diff --git a/pkg/apis/resource/validation/validation.go b/pkg/apis/resource/validation/validation.go index 2f58721ddc1..24fe8cfbdcb 100644 --- a/pkg/apis/resource/validation/validation.go +++ b/pkg/apis/resource/validation/validation.go @@ -802,17 +802,24 @@ func validateNetworkDeviceData(networkDeviceData *resource.NetworkDeviceData, fl allErrs = append(allErrs, validateSet(networkDeviceData.IPs, maxIPs, func(address string, fldPath *field.Path) field.ErrorList { - return validation.IsValidCIDR(fldPath, address) - }, - func(address string) (string, string) { // reformat CIDR to handle different ways IPs can be written // (e.g. 2001:db8::1/64 == 2001:0db8::1/64) ip, ipNet, err := netutils.ParseCIDRSloppy(address) if err != nil { - return "", "" // will fail at IsValidCIDR + // must fail + return validation.IsValidCIDR(fldPath, address) } maskSize, _ := ipNet.Mask.Size() - return fmt.Sprintf("%s/%d", ip.String(), maskSize), "" + canonical := fmt.Sprintf("%s/%d", ip.String(), maskSize) + if address != canonical { + return field.ErrorList{ + field.Invalid(fldPath, address, fmt.Sprintf("must be in canonical form (%s)", canonical)), + } + } + return nil + }, + func(address string) (string, string) { + return address, "" }, fldPath.Child("ips"))...) return allErrs diff --git a/pkg/apis/resource/validation/validation_resourceclaim_test.go b/pkg/apis/resource/validation/validation_resourceclaim_test.go index 7c8763f5faf..6458c5dbc2b 100644 --- a/pkg/apis/resource/validation/validation_resourceclaim_test.go +++ b/pkg/apis/resource/validation/validation_resourceclaim_test.go @@ -1040,7 +1040,7 @@ func TestValidateClaimStatusUpdate(t *testing.T) { NetworkData: &resource.NetworkDeviceData{ IPs: []string{ "2001:db8::1/64", - "2001:0db8::1/64", + "2001:db8::1/64", }, }, }, @@ -1059,6 +1059,8 @@ func TestValidateClaimStatusUpdate(t *testing.T) { field.TooLong(field.NewPath("status", "devices").Index(0).Child("networkData", "interfaceName"), "", interfaceNameMaxLength), field.TooLong(field.NewPath("status", "devices").Index(0).Child("networkData", "hardwareAddress"), "", hardwareAddressMaxLength), field.Invalid(field.NewPath("status", "devices").Index(0).Child("networkData", "ips").Index(0), "300.9.8.0/24", "must be a valid CIDR value, (e.g. 10.9.8.0/24 or 2001:db8::/64)"), + field.Invalid(field.NewPath("status", "devices").Index(0).Child("networkData", "ips").Index(1), "010.009.008.000/24", "must be in canonical form (10.9.8.0/24)"), + field.Invalid(field.NewPath("status", "devices").Index(0).Child("networkData", "ips").Index(2), "2001:0db8::1/64", "must be in canonical form (2001:db8::1/64)"), }, oldClaim: func() *resource.ResourceClaim { return validAllocatedClaim }(), update: func(claim *resource.ResourceClaim) *resource.ResourceClaim { @@ -1072,6 +1074,8 @@ func TestValidateClaimStatusUpdate(t *testing.T) { HardwareAddress: strings.Repeat("x", hardwareAddressMaxLength+1), IPs: []string{ "300.9.8.0/24", + "010.009.008.000/24", + "2001:0db8::1/64", }, }, }, @@ -1169,7 +1173,7 @@ func TestValidateClaimStatusUpdate(t *testing.T) { NetworkData: &resource.NetworkDeviceData{ IPs: []string{ "2001:db8::1/64", - "2001:0db8::1/64", + "2001:db8::1/64", }, }, },