Skip to content

Commit 76f1684

Browse files
committed
Rename ValidateNonSpecialIP to ValidateEndpointIP
There is not a single definition of "non-special IP" that makes sense in all contexts. Rename ValidateNonSpecialIP to ValidateEndpointIP and clarify that it shouldn't be used for other validations. Also add a few more unit tests.
1 parent e0ab1a1 commit 76f1684

File tree

3 files changed

+31
-21
lines changed

3 files changed

+31
-21
lines changed

pkg/apis/core/validation/validation.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5943,7 +5943,9 @@ func ValidateService(service *core.Service) field.ErrorList {
59435943
if errs := validation.IsValidIP(idxPath, ip); len(errs) != 0 {
59445944
allErrs = append(allErrs, errs...)
59455945
} else {
5946-
allErrs = append(allErrs, ValidateNonSpecialIP(ip, idxPath)...)
5946+
// For historical reasons, this uses ValidateEndpointIP even
5947+
// though that is not exactly the appropriate set of checks.
5948+
allErrs = append(allErrs, ValidateEndpointIP(ip, idxPath)...)
59475949
}
59485950
}
59495951

@@ -7489,19 +7491,21 @@ func validateEndpointAddress(address *core.EndpointAddress, fldPath *field.Path)
74897491
allErrs = append(allErrs, field.Invalid(fldPath.Child("nodeName"), *address.NodeName, msg).WithOrigin("format=dns-label"))
74907492
}
74917493
}
7492-
allErrs = append(allErrs, ValidateNonSpecialIP(address.IP, fldPath.Child("ip"))...)
7494+
allErrs = append(allErrs, ValidateEndpointIP(address.IP, fldPath.Child("ip"))...)
74937495
return allErrs
74947496
}
74957497

7496-
// ValidateNonSpecialIP is used to validate Endpoints, EndpointSlices, and
7497-
// external IPs. Specifically, this disallows unspecified and loopback addresses
7498-
// are nonsensical and link-local addresses tend to be used for node-centric
7499-
// purposes (e.g. metadata service).
7498+
// ValidateEndpointIP is used to validate Endpoints and EndpointSlice addresses, and also
7499+
// (for historical reasons) external IPs. It disallows certain address types that don't
7500+
// make sense in those contexts. Note that this function is _almost_, but not exactly,
7501+
// equivalent to net.IP.IsGlobalUnicast(). (Unlike IsGlobalUnicast, it allows global
7502+
// multicast IPs, which is probably a bug.)
75007503
//
7501-
// IPv6 references
7502-
// - https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml
7503-
// - https://www.iana.org/assignments/ipv6-multicast-addresses/ipv6-multicast-addresses.xhtml
7504-
func ValidateNonSpecialIP(ipAddress string, fldPath *field.Path) field.ErrorList {
7504+
// This function should not be used for new validations; the exact set of IPs that do and
7505+
// don't make sense in a particular field is context-dependent (e.g., localhost makes
7506+
// sense in some places; unspecified IPs make sense in fields that are used as bind
7507+
// addresses rather than destination addresses).
7508+
func ValidateEndpointIP(ipAddress string, fldPath *field.Path) field.ErrorList {
75057509
allErrs := field.ErrorList{}
75067510
ip := netutils.ParseIPSloppy(ipAddress)
75077511
if ip == nil {
@@ -7520,7 +7524,7 @@ func ValidateNonSpecialIP(ipAddress string, fldPath *field.Path) field.ErrorList
75207524
if ip.IsLinkLocalMulticast() {
75217525
allErrs = append(allErrs, field.Invalid(fldPath, ipAddress, "may not be in the link-local multicast range (224.0.0.0/24, ff02::/10)"))
75227526
}
7523-
return allErrs.WithOrigin("format=non-special-ip")
7527+
return allErrs.WithOrigin("format=endpoint-ip")
75247528
}
75257529

75267530
func validateEndpointPort(port *core.EndpointPort, requireName bool, fldPath *field.Path) field.ErrorList {

pkg/apis/core/validation/validation_test.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20725,7 +20725,7 @@ func TestValidateEndpointsCreate(t *testing.T) {
2072520725
}},
2072620726
},
2072720727
expectedErrs: field.ErrorList{
20728-
field.Invalid(field.NewPath("subsets[0].addresses[0].ip"), nil, "").WithOrigin("format=non-special-ip"),
20728+
field.Invalid(field.NewPath("subsets[0].addresses[0].ip"), nil, "").WithOrigin("format=endpoint-ip"),
2072920729
},
2073020730
},
2073120731
"Address is link-local": {
@@ -20737,7 +20737,7 @@ func TestValidateEndpointsCreate(t *testing.T) {
2073720737
}},
2073820738
},
2073920739
expectedErrs: field.ErrorList{
20740-
field.Invalid(field.NewPath("subsets[0].addresses[0].ip"), nil, "").WithOrigin("format=non-special-ip"),
20740+
field.Invalid(field.NewPath("subsets[0].addresses[0].ip"), nil, "").WithOrigin("format=endpoint-ip"),
2074120741
},
2074220742
},
2074320743
"Address is link-local multicast": {
@@ -20749,7 +20749,7 @@ func TestValidateEndpointsCreate(t *testing.T) {
2074920749
}},
2075020750
},
2075120751
expectedErrs: field.ErrorList{
20752-
field.Invalid(field.NewPath("subsets[0].addresses[0].ip"), nil, "").WithOrigin("format=non-special-ip"),
20752+
field.Invalid(field.NewPath("subsets[0].addresses[0].ip"), nil, "").WithOrigin("format=endpoint-ip"),
2075320753
},
2075420754
},
2075520755
"Invalid AppProtocol": {
@@ -23641,7 +23641,7 @@ func TestValidateResourceRequirements(t *testing.T) {
2364123641
}
2364223642
}
2364323643

23644-
func TestValidateNonSpecialIP(t *testing.T) {
23644+
func TestValidateEndpointIP(t *testing.T) {
2364523645
fp := field.NewPath("ip")
2364623646

2364723647
// Valid values.
@@ -23652,11 +23652,15 @@ func TestValidateNonSpecialIP(t *testing.T) {
2365223652
{"ipv4", "10.1.2.3"},
2365323653
{"ipv4 class E", "244.1.2.3"},
2365423654
{"ipv6", "2000::1"},
23655+
23656+
// These probably should not have been allowed, but they are
23657+
{"ipv4 multicast", "239.255.255.253"},
23658+
{"ipv6 multicast", "ff05::1:3"},
2365523659
} {
2365623660
t.Run(tc.desc, func(t *testing.T) {
23657-
errs := ValidateNonSpecialIP(tc.ip, fp)
23661+
errs := ValidateEndpointIP(tc.ip, fp)
2365823662
if len(errs) != 0 {
23659-
t.Errorf("ValidateNonSpecialIP(%q, ...) = %v; want nil", tc.ip, errs)
23663+
t.Errorf("ValidateEndpointIP(%q, ...) = %v; want nil", tc.ip, errs)
2366023664
}
2366123665
})
2366223666
}
@@ -23670,13 +23674,15 @@ func TestValidateNonSpecialIP(t *testing.T) {
2367023674
{"ipv4 localhost", "127.0.0.0"},
2367123675
{"ipv4 localhost", "127.255.255.255"},
2367223676
{"ipv6 localhost", "::1"},
23677+
{"ipv4 link local", "169.254.169.254"},
2367323678
{"ipv6 link local", "fe80::"},
23679+
{"ipv4 local multicast", "224.0.0.251"},
2367423680
{"ipv6 local multicast", "ff02::"},
2367523681
} {
2367623682
t.Run(tc.desc, func(t *testing.T) {
23677-
errs := ValidateNonSpecialIP(tc.ip, fp)
23683+
errs := ValidateEndpointIP(tc.ip, fp)
2367823684
if len(errs) == 0 {
23679-
t.Errorf("ValidateNonSpecialIP(%q, ...) = nil; want non-nil (errors)", tc.ip)
23685+
t.Errorf("ValidateEndpointIP(%q, ...) = nil; want non-nil (errors)", tc.ip)
2368023686
}
2368123687
})
2368223688
}

pkg/apis/discovery/validation/validation.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ func validateEndpoints(endpoints []discovery.Endpoint, addrType discovery.Addres
100100
switch addrType {
101101
case discovery.AddressTypeIPv4:
102102
allErrs = append(allErrs, validation.IsValidIPv4Address(addressPath.Index(i), address)...)
103-
allErrs = append(allErrs, apivalidation.ValidateNonSpecialIP(address, addressPath.Index(i))...)
103+
allErrs = append(allErrs, apivalidation.ValidateEndpointIP(address, addressPath.Index(i))...)
104104
case discovery.AddressTypeIPv6:
105105
allErrs = append(allErrs, validation.IsValidIPv6Address(addressPath.Index(i), address)...)
106-
allErrs = append(allErrs, apivalidation.ValidateNonSpecialIP(address, addressPath.Index(i))...)
106+
allErrs = append(allErrs, apivalidation.ValidateEndpointIP(address, addressPath.Index(i))...)
107107
case discovery.AddressTypeFQDN:
108108
allErrs = append(allErrs, validation.IsFullyQualifiedDomainName(addressPath.Index(i), address)...)
109109
}

0 commit comments

Comments
 (0)