From f31d865d925c51ccb8e512626d68f0184ab85fc8 Mon Sep 17 00:00:00 2001 From: Axel Christ Date: Thu, 21 Sep 2023 16:43:26 +0200 Subject: [PATCH] Implement validation for core types --- .../networkinterface_controller_test.go | 1 + .../v1alpha1.core.apinet.api.onmetal.de.yaml | 4 +- internal/apis/core/validation/common.go | 59 +++++++++++++++++++ internal/apis/core/validation/instance.go | 39 ++++++++++++ internal/apis/core/validation/ip.go | 33 +++++++++++ internal/apis/core/validation/ipaddress.go | 9 +++ internal/apis/core/validation/loadbalancer.go | 41 +++++++++++++ internal/apis/core/validation/natgateway.go | 26 ++++++++ .../core/validation/natgatewayautoscaler.go | 27 +++++++++ internal/apis/core/validation/network.go | 19 ++++++ internal/apis/core/validation/networkid.go | 9 +++ .../apis/core/validation/networkinterface.go | 21 +++++++ internal/app/core_test.go | 2 + 13 files changed, 288 insertions(+), 2 deletions(-) create mode 100644 internal/apis/core/validation/common.go diff --git a/apinetlet/controllers/networkinterface_controller_test.go b/apinetlet/controllers/networkinterface_controller_test.go index c6876bad..311f5512 100644 --- a/apinetlet/controllers/networkinterface_controller_test.go +++ b/apinetlet/controllers/networkinterface_controller_test.go @@ -62,6 +62,7 @@ var _ = Describe("NetworkInterfaceController", func() { Spec: apinetv1alpha1.NetworkInterfaceSpec{ NetworkRef: corev1.LocalObjectReference{Name: apiNetNetwork.Name}, IPs: []net.IP{net.MustParseIP("192.168.178.1")}, + NodeRef: corev1.LocalObjectReference{Name: "my-node"}, }, } Expect(k8sClient.Create(ctx, apiNetNic)).To(Succeed()) diff --git a/config/apiserver/apiservice/bases/v1alpha1.core.apinet.api.onmetal.de.yaml b/config/apiserver/apiservice/bases/v1alpha1.core.apinet.api.onmetal.de.yaml index 3a219fb1..4128864f 100644 --- a/config/apiserver/apiservice/bases/v1alpha1.core.apinet.api.onmetal.de.yaml +++ b/config/apiserver/apiservice/bases/v1alpha1.core.apinet.api.onmetal.de.yaml @@ -8,5 +8,5 @@ spec: service: namespace: system name: apiserver-service - groupPriorityMinimum: 2000 - versionPriority: 100 + groupPriorityMinimum: 1900 + versionPriority: 90 diff --git a/internal/apis/core/validation/common.go b/internal/apis/core/validation/common.go new file mode 100644 index 00000000..fe7856ba --- /dev/null +++ b/internal/apis/core/validation/common.go @@ -0,0 +1,59 @@ +// Copyright 2023 OnMetal authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package validation + +import ( + "fmt" + "sort" + + "github.com/onmetal/onmetal-api-net/apimachinery/api/net" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/sets" + "k8s.io/apimachinery/pkg/util/validation/field" +) + +func ValidateEnum[E comparable](allowed sets.Set[E], value E, fldPath *field.Path, requiredDetail string) field.ErrorList { + var allErrs field.ErrorList + var zero E + if value == zero && !allowed.Has(zero) { + allErrs = append(allErrs, field.Required(fldPath, requiredDetail)) + } else if !allowed.Has(value) { + validValues := make([]string, 0, allowed.Len()) + for item := range allowed { + validValues = append(validValues, fmt.Sprint(item)) + } + sort.Strings(validValues) + + allErrs = append(allErrs, field.NotSupported(fldPath, value, validValues)) + } + return allErrs +} + +var IPFamilies = sets.New( + corev1.IPv4Protocol, + corev1.IPv6Protocol, +) + +func ValidateIPFamily(ipFamily corev1.IPFamily, fldPath *field.Path) field.ErrorList { + return ValidateEnum(IPFamilies, ipFamily, fldPath, "must specify IP family") +} + +func ValidateIPMatchesFamily(ip net.IP, ipFamily corev1.IPFamily, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if ip.Family() != ipFamily { + allErrs = append(allErrs, field.Invalid(fldPath, ip, fmt.Sprintf("IP should have family %s", ipFamily))) + } + return allErrs +} diff --git a/internal/apis/core/validation/instance.go b/internal/apis/core/validation/instance.go index 17c16b30..db7926b1 100644 --- a/internal/apis/core/validation/instance.go +++ b/internal/apis/core/validation/instance.go @@ -17,13 +17,36 @@ package validation import ( "github.com/onmetal/onmetal-api-net/internal/apis/core" "k8s.io/apimachinery/pkg/api/validation" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" ) +var InstanceTypes = sets.New( + core.InstanceTypeLoadBalancer, +) + +func ValidateInstanceType(typ core.InstanceType, fldPath *field.Path) field.ErrorList { + return ValidateEnum(InstanceTypes, typ, fldPath, "must specify instance type") +} + func ValidateInstance(instance *core.Instance) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, validation.ValidateObjectMetaAccessor(instance, true, validation.NameIsDNSLabel, field.NewPath("metadata"))...) + allErrs = append(allErrs, ValidateInstanceSpec(&instance.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateInstanceSpec(spec *core.InstanceSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, ValidateInstanceType(spec.Type, fldPath.Child("type"))...) + + switch spec.Type { + case core.InstanceTypeLoadBalancer: + allErrs = append(allErrs, ValidateLoadBalancerType(spec.LoadBalancerType, fldPath.Child("loadBalancerType"))...) + } return allErrs } @@ -33,6 +56,22 @@ func ValidateInstanceUpdate(newInstance, oldInstance *core.Instance) field.Error allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(newInstance, oldInstance, field.NewPath("metadata"))...) allErrs = append(allErrs, ValidateInstance(newInstance)...) + allErrs = append(allErrs, ValidateInstanceSpecUpdate(&newInstance.Spec, &oldInstance.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateInstanceSpecUpdate(newSpec, oldSpec *core.InstanceSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + if oldSpec.NodeRef == nil { + oldSpec.NodeRef = newSpec.NodeRef + } + + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.Type, oldSpec.Type, fldPath.Child("type"))...) + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.LoadBalancerType, oldSpec.LoadBalancerType, fldPath.Child("loadBalancerType"))...) + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.NetworkRef, oldSpec.NetworkRef, fldPath.Child("networkRef"))...) + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.NodeRef, oldSpec.NodeRef, fldPath.Child("nodeRef"))...) return allErrs } diff --git a/internal/apis/core/validation/ip.go b/internal/apis/core/validation/ip.go index 1f848afe..ba4299ca 100644 --- a/internal/apis/core/validation/ip.go +++ b/internal/apis/core/validation/ip.go @@ -17,13 +17,35 @@ package validation import ( "github.com/onmetal/onmetal-api-net/internal/apis/core" "k8s.io/apimachinery/pkg/api/validation" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" ) +var IPTypes = sets.New( + core.IPTypePublic, +) + +func ValidateIPType(ipType core.IPType, fldPath *field.Path) field.ErrorList { + return ValidateEnum(IPTypes, ipType, fldPath, "must specify IP type") +} + func ValidateIP(ip *core.IP) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, validation.ValidateObjectMetaAccessor(ip, true, validation.NameIsDNSLabel, field.NewPath("metadata"))...) + allErrs = append(allErrs, ValidateIPSpec(&ip.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateIPSpec(spec *core.IPSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, ValidateIPType(spec.Type, fldPath.Child("type"))...) + allErrs = append(allErrs, ValidateIPFamily(spec.IPFamily, fldPath.Child("ipFamily"))...) + if spec.IP.IsValid() { + allErrs = append(allErrs, ValidateIPMatchesFamily(spec.IP, spec.IPFamily, fldPath.Child("ip"))...) + } return allErrs } @@ -33,6 +55,17 @@ func ValidateIPUpdate(newIP, oldIP *core.IP) field.ErrorList { allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(newIP, oldIP, field.NewPath("metadata"))...) allErrs = append(allErrs, ValidateIP(newIP)...) + allErrs = append(allErrs, ValidateIPSpecUpdate(&newIP.Spec, &oldIP.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateIPSpecUpdate(newSpec, oldSpec *core.IPSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.Type, oldSpec.Type, fldPath.Child("type"))...) + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.IPFamily, oldSpec.IPFamily, fldPath.Child("ipFamily"))...) + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.IP, oldSpec.IP, fldPath.Child("ip"))...) return allErrs } diff --git a/internal/apis/core/validation/ipaddress.go b/internal/apis/core/validation/ipaddress.go index 4698de0e..c3e0832e 100644 --- a/internal/apis/core/validation/ipaddress.go +++ b/internal/apis/core/validation/ipaddress.go @@ -46,6 +46,15 @@ func ValidateIPAddressUpdate(newIPAddress, oldIPAddress *core.IPAddress) field.E allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(newIPAddress, oldIPAddress, field.NewPath("metadata"))...) allErrs = append(allErrs, ValidateIPAddress(newIPAddress)...) + allErrs = append(allErrs, ValidateIPAddressSpecUpdate(&newIPAddress.Spec, &oldIPAddress.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateIPAddressSpecUpdate(newSpec, oldSpec *core.IPAddressSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.ClaimRef, oldSpec.ClaimRef, fldPath.Child("clamRef"))...) return allErrs } diff --git a/internal/apis/core/validation/loadbalancer.go b/internal/apis/core/validation/loadbalancer.go index 68e41740..0e697234 100644 --- a/internal/apis/core/validation/loadbalancer.go +++ b/internal/apis/core/validation/loadbalancer.go @@ -17,13 +17,43 @@ package validation import ( "github.com/onmetal/onmetal-api-net/internal/apis/core" "k8s.io/apimachinery/pkg/api/validation" + metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" ) +var LoadBalancerTypes = sets.New( + core.LoadBalancerTypePublic, + core.LoadBalancerTypeInternal, +) + +func ValidateLoadBalancerType(typ core.LoadBalancerType, fldPath *field.Path) field.ErrorList { + return ValidateEnum(LoadBalancerTypes, typ, fldPath, "must specify type") +} + func ValidateLoadBalancer(loadBalancer *core.LoadBalancer) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, validation.ValidateObjectMetaAccessor(loadBalancer, true, validation.NameIsDNSLabel, field.NewPath("metadata"))...) + allErrs = append(allErrs, ValidateLoadBalancerSpec(&loadBalancer.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateLoadBalancerSpec(spec *core.LoadBalancerSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, ValidateLoadBalancerType(spec.Type, fldPath.Child("type"))...) + + for i, ip := range spec.IPs { + fldPath := fldPath.Child("ips").Index(i) + allErrs = append(allErrs, ValidateIPFamily(ip.IPFamily, fldPath)...) + if ip.IP.IsValid() { + allErrs = append(allErrs, ValidateIPMatchesFamily(ip.IP, ip.IPFamily, fldPath.Child("ip"))...) + } + } + + allErrs = append(allErrs, metav1validation.ValidateLabelSelector(spec.Selector, metav1validation.LabelSelectorValidationOptions{}, fldPath.Child("selector"))...) return allErrs } @@ -33,6 +63,17 @@ func ValidateLoadBalancerUpdate(newLoadBalancer, oldLoadBalancer *core.LoadBalan allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(newLoadBalancer, oldLoadBalancer, field.NewPath("metadata"))...) allErrs = append(allErrs, ValidateLoadBalancer(newLoadBalancer)...) + allErrs = append(allErrs, ValidateLoadBalancerSpecUpdate(&newLoadBalancer.Spec, &oldLoadBalancer.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateLoadBalancerSpecUpdate(newSpec, oldSpec *core.LoadBalancerSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.Type, oldSpec.Type, fldPath.Child("type"))...) + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.NetworkRef, oldSpec.NetworkRef, fldPath.Child("networkRef"))...) + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.Selector, oldSpec.Selector, fldPath.Child("selector"))...) return allErrs } diff --git a/internal/apis/core/validation/natgateway.go b/internal/apis/core/validation/natgateway.go index a6579e58..1193aeb5 100644 --- a/internal/apis/core/validation/natgateway.go +++ b/internal/apis/core/validation/natgateway.go @@ -24,6 +24,22 @@ func ValidateNATGateway(natGateway *core.NATGateway) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, validation.ValidateObjectMetaAccessor(natGateway, true, validation.NameIsDNSLabel, field.NewPath("metadata"))...) + allErrs = append(allErrs, ValidateNATGatewaySpec(&natGateway.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateNATGatewaySpec(spec *core.NATGatewaySpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, ValidateIPFamily(spec.IPFamily, fldPath.Child("ipFamily"))...) + + for i, ip := range spec.IPs { + fldPath := fldPath.Child("ips").Index(i) + if ip.IP.IsValid() { + allErrs = append(allErrs, ValidateIPMatchesFamily(ip.IP, spec.IPFamily, fldPath.Child("ip"))...) + } + } return allErrs } @@ -33,6 +49,16 @@ func ValidateNATGatewayUpdate(newNATGateway, oldNATGateway *core.NATGateway) fie allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(newNATGateway, oldNATGateway, field.NewPath("metadata"))...) allErrs = append(allErrs, ValidateNATGateway(newNATGateway)...) + allErrs = append(allErrs, ValidateNATGatewaySpecUpdate(&newNATGateway.Spec, &oldNATGateway.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateNATGatewaySpecUpdate(newSpec, oldSpec *core.NATGatewaySpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.IPFamily, oldSpec.IPFamily, fldPath.Child("ipFamily"))...) + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.NetworkRef, oldSpec.NetworkRef, fldPath.Child("networkRef"))...) return allErrs } diff --git a/internal/apis/core/validation/natgatewayautoscaler.go b/internal/apis/core/validation/natgatewayautoscaler.go index 3295dcab..f9dc81ee 100644 --- a/internal/apis/core/validation/natgatewayautoscaler.go +++ b/internal/apis/core/validation/natgatewayautoscaler.go @@ -16,6 +16,7 @@ package validation import ( "github.com/onmetal/onmetal-api-net/internal/apis/core" + "github.com/onmetal/onmetal-api/utils/generic" "k8s.io/apimachinery/pkg/api/validation" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -24,6 +25,23 @@ func ValidateNATGatewayAutoscaler(natGatewayAutoscaler *core.NATGatewayAutoscale var allErrs field.ErrorList allErrs = append(allErrs, validation.ValidateObjectMetaAccessor(natGatewayAutoscaler, true, validation.NameIsDNSLabel, field.NewPath("metadata"))...) + allErrs = append(allErrs, ValidateNATGatewayAutoscalerSpec(&natGatewayAutoscaler.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateNATGatewayAutoscalerSpec(spec *core.NATGatewayAutoscalerSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + minPublicIPs := generic.DerefZero(spec.MinPublicIPs) + allErrs = append(allErrs, validation.ValidateNonnegativeField(int64(minPublicIPs), fldPath.Child("minPublicIPs"))...) + + maxPublicIPs := generic.DerefZero(spec.MaxPublicIPs) + allErrs = append(allErrs, validation.ValidateNonnegativeField(int64(maxPublicIPs), fldPath.Child("maxPublicIPs"))...) + + if minPublicIPs > maxPublicIPs { + allErrs = append(allErrs, field.Invalid(fldPath.Child("maxPublicIPs"), maxPublicIPs, "must >= minPublicIPs")) + } return allErrs } @@ -37,10 +55,19 @@ func ValidateNATGatewayAutoscalerUpdate(newNATGatewayAutoscaler, oldNATGatewayAu return allErrs } +func ValidateNATGatewayAutoscalerSpecUpdate(newSpec, oldSpec *core.NATGatewayAutoscalerSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.NATGatewayRef, oldSpec.NATGatewayRef, fldPath.Child("natGatewayRef"))...) + + return allErrs +} + func ValidateNATGatewayAutoscalerStatusUpdate(newNATGatewayAutoscaler, oldNATGatewayAutoscaler *core.NATGatewayAutoscaler) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(newNATGatewayAutoscaler, oldNATGatewayAutoscaler, field.NewPath("metadata"))...) + allErrs = append(allErrs, ValidateNATGatewayAutoscalerSpecUpdate(&newNATGatewayAutoscaler.Spec, &oldNATGatewayAutoscaler.Spec, field.NewPath("spec"))...) return allErrs } diff --git a/internal/apis/core/validation/network.go b/internal/apis/core/validation/network.go index 65dab185..d1012706 100644 --- a/internal/apis/core/validation/network.go +++ b/internal/apis/core/validation/network.go @@ -24,6 +24,16 @@ func ValidateNetwork(network *core.Network) field.ErrorList { var allErrs field.ErrorList allErrs = append(allErrs, validation.ValidateObjectMetaAccessor(network, true, validation.NameIsDNSLabel, field.NewPath("metadata"))...) + allErrs = append(allErrs, ValidateNetworkSpec(&network.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateNetworkSpec(spec *core.NetworkSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + _ = spec + _ = fldPath return allErrs } @@ -33,6 +43,15 @@ func ValidateNetworkUpdate(newNetwork, oldNetwork *core.Network) field.ErrorList allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(newNetwork, oldNetwork, field.NewPath("metadata"))...) allErrs = append(allErrs, ValidateNetwork(newNetwork)...) + allErrs = append(allErrs, ValidateNetworkSpecUpdate(&newNetwork.Spec, &oldNetwork.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateNetworkSpecUpdate(newSpec, oldSpec *core.NetworkSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.ID, oldSpec.ID, fldPath.Child("id"))...) return allErrs } diff --git a/internal/apis/core/validation/networkid.go b/internal/apis/core/validation/networkid.go index ba499699..07b9f9fb 100644 --- a/internal/apis/core/validation/networkid.go +++ b/internal/apis/core/validation/networkid.go @@ -45,6 +45,15 @@ func ValidateNetworkIDUpdate(newNetworkID, oldNetworkID *core.NetworkID) field.E allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(newNetworkID, oldNetworkID, field.NewPath("metadata"))...) allErrs = append(allErrs, ValidateNetworkID(newNetworkID)...) + allErrs = append(allErrs, ValidateNetworkIDSpecUpdate(&newNetworkID.Spec, &oldNetworkID.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateNetworkIDSpecUpdate(newSpec, oldSpec *core.NetworkIDSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.ClaimRef, oldSpec.ClaimRef, fldPath.Child("claimRef"))...) return allErrs } diff --git a/internal/apis/core/validation/networkinterface.go b/internal/apis/core/validation/networkinterface.go index 29bfe30c..86465a57 100644 --- a/internal/apis/core/validation/networkinterface.go +++ b/internal/apis/core/validation/networkinterface.go @@ -24,6 +24,17 @@ func ValidateNetworkInterface(networkInterface *core.NetworkInterface) field.Err var allErrs field.ErrorList allErrs = append(allErrs, validation.ValidateObjectMetaAccessor(networkInterface, true, validation.NameIsDNSLabel, field.NewPath("metadata"))...) + allErrs = append(allErrs, ValidateNetworkInterfaceSpec(&networkInterface.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateNetworkInterfaceSpec(spec *core.NetworkInterfaceSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + if spec.NodeRef.Name == "" { + allErrs = append(allErrs, field.Required(fldPath.Child("nodeRef", "name"), "must specify target node")) + } return allErrs } @@ -33,6 +44,16 @@ func ValidateNetworkInterfaceUpdate(newNetworkInterface, oldNetworkInterface *co allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(newNetworkInterface, oldNetworkInterface, field.NewPath("metadata"))...) allErrs = append(allErrs, ValidateNetworkInterface(newNetworkInterface)...) + allErrs = append(allErrs, ValidateNetworkInterfaceSpecUpdate(&newNetworkInterface.Spec, &oldNetworkInterface.Spec, field.NewPath("spec"))...) + + return allErrs +} + +func ValidateNetworkInterfaceSpecUpdate(newSpec, oldSpec *core.NetworkInterfaceSpec, fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.NetworkRef, oldSpec.NetworkRef, fldPath.Child("networkRef"))...) + allErrs = append(allErrs, validation.ValidateImmutableField(newSpec.NodeRef, oldSpec.NodeRef, fldPath.Child("nodeRef"))...) return allErrs } diff --git a/internal/app/core_test.go b/internal/app/core_test.go index 3f6f7123..c91a4b4c 100644 --- a/internal/app/core_test.go +++ b/internal/app/core_test.go @@ -76,6 +76,7 @@ var _ = Describe("Core", func() { GenerateName: "ip-", }, Spec: v1alpha1.IPSpec{ + Type: v1alpha1.IPTypePublic, IPFamily: corev1.IPv4Protocol, }, } @@ -259,6 +260,7 @@ var _ = Describe("Core", func() { IPFamily: corev1.IPv4Protocol, }, }, + NodeRef: corev1.LocalObjectReference{Name: "my-node"}, }, } Expect(k8sClient.Create(ctx, networkInterface)).To(Succeed())