diff --git a/pkg/api/validation/validation.go b/pkg/api/validation/validation.go index 10065db79d8..c112b927a3d 100644 --- a/pkg/api/validation/validation.go +++ b/pkg/api/validation/validation.go @@ -1592,11 +1592,24 @@ func validateEndpointSubsets(subsets []api.EndpointSubset) errs.ValidationErrorL return allErrs } +var linkLocalNet *net.IPNet + func validateEndpointAddress(address *api.EndpointAddress) errs.ValidationErrorList { + if linkLocalNet == nil { + var err error + _, linkLocalNet, err = net.ParseCIDR("169.254.0.0/16") + if err != nil { + glog.Errorf("Failed to parse link-local CIDR: %v", err) + } + } + allErrs := errs.ValidationErrorList{} if !util.IsValidIPv4(address.IP) { allErrs = append(allErrs, errs.NewFieldInvalid("ip", address.IP, "invalid IPv4 address")) } + if linkLocalNet.Contains(net.ParseIP(address.IP)) { + allErrs = append(allErrs, errs.NewFieldInvalid("ip", address.IP, "may not be in the link-local range (169.254.0.0/16)")) + } return allErrs } diff --git a/pkg/api/validation/validation_test.go b/pkg/api/validation/validation_test.go index 0367f7f3797..4af153cce0d 100644 --- a/pkg/api/validation/validation_test.go +++ b/pkg/api/validation/validation_test.go @@ -3350,10 +3350,23 @@ func TestValidateEndpoints(t *testing.T) { }, errorType: "FieldValueRequired", }, + "Address is link-local": { + endpoints: api.Endpoints{ + ObjectMeta: api.ObjectMeta{Name: "mysvc", Namespace: "namespace"}, + Subsets: []api.EndpointSubset{ + { + Addresses: []api.EndpointAddress{{IP: "169.254.169.254"}}, + Ports: []api.EndpointPort{{Name: "p", Port: 93, Protocol: "TCP"}}, + }, + }, + }, + errorType: "FieldValueInvalid", + errorDetail: "link-local", + }, } for k, v := range errorCases { - if errs := ValidateEndpoints(&v.endpoints); len(errs) == 0 || errs[0].(*errors.ValidationError).Type != v.errorType || errs[0].(*errors.ValidationError).Detail != v.errorDetail { + if errs := ValidateEndpoints(&v.endpoints); len(errs) == 0 || errs[0].(*errors.ValidationError).Type != v.errorType || !strings.Contains(errs[0].(*errors.ValidationError).Detail, v.errorDetail) { t.Errorf("Expected error type %s with detail %s for %s, got %v", v.errorType, v.errorDetail, k, errs) } }