diff --git a/artifacts/k8s.cni.cncf.io_ipamclaims.yaml b/artifacts/k8s.cni.cncf.io_ipamclaims.yaml index 95b20ce..1e912b9 100644 --- a/artifacts/k8s.cni.cncf.io_ipamclaims.yaml +++ b/artifacts/k8s.cni.cncf.io_ipamclaims.yaml @@ -42,15 +42,33 @@ spec: description: The pod interface name for which this allocation was created type: string + x-kubernetes-validations: + - message: Interface is immutable + rule: self == oldSelf ipRequests: - description: The IPs requested by the user + description: The IPs (v4, v6) requested by the user for this particular + network attachment items: + description: CIDR represents type: string + x-kubernetes-validations: + - message: CIDR is invalid + rule: isCIDR(self) + maxItems: 2 type: array + x-kubernetes-validations: + - message: IPRequests are immutable + rule: self == oldSelf + - message: When 2 CIDRs are set, they must be from different IP families + rule: size(self) != 2 || isCIDR(self[0]) && isCIDR(self[1]) && cidr(self[0]).ip().family() + != cidr(self[1]).ip().family() network: description: The network name for which this persistent allocation was created type: string + x-kubernetes-validations: + - message: Network is immutable + rule: self == oldSelf required: - interface - network @@ -120,7 +138,12 @@ spec: description: The list of IP addresses (v4, v6) that were allocated for the pod interface items: + description: CIDR represents type: string + x-kubernetes-validations: + - message: CIDR is invalid + rule: isCIDR(self) + maxItems: 2 type: array ownerPod: description: The name of the pod holding the IPAMClaim diff --git a/cmd/example/main.go b/cmd/example/main.go index 774b567..e81b8fa 100644 --- a/cmd/example/main.go +++ b/cmd/example/main.go @@ -38,8 +38,9 @@ func main() { Name: "example", }, Spec: v1alpha1.IPAMClaimSpec{ - Network: "tenantblue", - Interface: "iface321", + Network: "tenantblue", + Interface: "iface321", + IPRequests: []v1alpha1.CIDR{"10.10.10.0/24", "fd10::0/64"}, }, } @@ -61,7 +62,7 @@ func main() { ) }() - ipamClaim.Status.IPs = []v1alpha1.CIDR{"winner", "winner", "chicken", "dinner"} + ipamClaim.Status.IPs = []v1alpha1.CIDR{"192.168.0.0/16", "fd00:abcd::0/64"} _, err = exampleClient.K8sV1alpha1().IPAMClaims("default").UpdateStatus( context.Background(), ipamClaim, diff --git a/pkg/crd/ipamclaims/v1alpha1/types.go b/pkg/crd/ipamclaims/v1alpha1/types.go index d7f23d4..41bdf60 100644 --- a/pkg/crd/ipamclaims/v1alpha1/types.go +++ b/pkg/crd/ipamclaims/v1alpha1/types.go @@ -30,17 +30,24 @@ type IPAMClaim struct { type IPAMClaimSpec struct { // The network name for which this persistent allocation was created + // +kubebuilder:validation:Required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Network is immutable" Network string `json:"network"` // The pod interface name for which this allocation was created + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Interface is immutable" Interface string `json:"interface"` - // The IPs requested by the user + // The IPs (v4, v6) requested by the user for this particular network attachment // +optional + // +kubebuilder:validation:MaxItems=2 + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="IPRequests are immutable" + // +kubebuilder:validation:XValidation:rule="size(self) != 2 || isCIDR(self[0]) && isCIDR(self[1]) && cidr(self[0]).ip().family() != cidr(self[1]).ip().family()", message="When 2 CIDRs are set, they must be from different IP families" IPRequests []CIDR `json:"ipRequests,omitempty"` } // IPAMClaimStatus contains the observed status of the IPAMClaim. type IPAMClaimStatus struct { // The list of IP addresses (v4, v6) that were allocated for the pod interface + // +kubebuilder:validation:MaxItems=2 IPs []CIDR `json:"ips"` // The name of the pod holding the IPAMClaim OwnerPod string `json:"ownerPod"` @@ -56,4 +63,6 @@ type IPAMClaimList struct { Items []IPAMClaim `json:"items"` } +// CIDR represents +// +kubebuilder:validation:XValidation:rule="isCIDR(self)", message="CIDR is invalid" type CIDR string