Fix validation on ETP: "" is not valid
This was causing tests to pass which ought not be passing. This is not an API change because we default the value of it when needed. So we would never see this in the wild, but it makes the tests sloppy.
This commit is contained in:
@@ -4454,9 +4454,8 @@ func ValidateService(service *core.Service) field.ErrorList {
|
||||
// validate LoadBalancerClass field
|
||||
allErrs = append(allErrs, validateLoadBalancerClassField(nil, service)...)
|
||||
|
||||
// external traffic fields
|
||||
allErrs = append(allErrs, validateServiceExternalTrafficFieldsValue(service)...)
|
||||
allErrs = append(allErrs, validateServiceExternalTrafficFieldsCombination(service)...)
|
||||
// external traffic policy fields
|
||||
allErrs = append(allErrs, validateServiceExternalTrafficPolicy(service)...)
|
||||
|
||||
// internal traffic policy field
|
||||
allErrs = append(allErrs, validateServiceInternalTrafficFieldsValue(service)...)
|
||||
@@ -4508,22 +4507,46 @@ func validateServicePort(sp *core.ServicePort, requireName, isHeadlessService bo
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validateServiceExternalTrafficFieldsValue validates ExternalTraffic related annotations
|
||||
// have legal value.
|
||||
func validateServiceExternalTrafficFieldsValue(service *core.Service) field.ErrorList {
|
||||
func needsExternalTrafficPolicy(svc *api.Service) bool {
|
||||
return svc.Spec.Type == core.ServiceTypeLoadBalancer || svc.Spec.Type == core.ServiceTypeNodePort
|
||||
}
|
||||
|
||||
var validExternalTrafficPolicies = sets.NewString(
|
||||
string(core.ServiceExternalTrafficPolicyTypeCluster),
|
||||
string(core.ServiceExternalTrafficPolicyTypeLocal))
|
||||
|
||||
func validateServiceExternalTrafficPolicy(service *core.Service) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
// Check first class fields.
|
||||
if service.Spec.ExternalTrafficPolicy != "" &&
|
||||
service.Spec.ExternalTrafficPolicy != core.ServiceExternalTrafficPolicyTypeCluster &&
|
||||
service.Spec.ExternalTrafficPolicy != core.ServiceExternalTrafficPolicyTypeLocal {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("externalTrafficPolicy"), service.Spec.ExternalTrafficPolicy,
|
||||
fmt.Sprintf("ExternalTrafficPolicy must be empty, %v or %v", core.ServiceExternalTrafficPolicyTypeCluster, core.ServiceExternalTrafficPolicyTypeLocal)))
|
||||
fldPath := field.NewPath("spec")
|
||||
|
||||
if !needsExternalTrafficPolicy(service) {
|
||||
if service.Spec.ExternalTrafficPolicy != "" {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("externalTrafficPolicy"), service.Spec.ExternalTrafficPolicy,
|
||||
"may only be set when `type` is 'NodePort' or 'LoadBalancer'"))
|
||||
}
|
||||
} else {
|
||||
if service.Spec.ExternalTrafficPolicy == "" {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("externalTrafficPolicy"), ""))
|
||||
} else if !validExternalTrafficPolicies.Has(string(service.Spec.ExternalTrafficPolicy)) {
|
||||
allErrs = append(allErrs, field.NotSupported(fldPath.Child("externalTrafficPolicy"),
|
||||
service.Spec.ExternalTrafficPolicy, validExternalTrafficPolicies.List()))
|
||||
}
|
||||
}
|
||||
|
||||
if service.Spec.HealthCheckNodePort < 0 {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("spec").Child("healthCheckNodePort"), service.Spec.HealthCheckNodePort,
|
||||
"HealthCheckNodePort must be not less than 0"))
|
||||
if !apiservice.NeedsHealthCheck(service) {
|
||||
if service.Spec.HealthCheckNodePort != 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("healthCheckNodePort"), service.Spec.HealthCheckNodePort,
|
||||
"may only be set when `type` is 'LoadBalancer' and `externalTrafficPolicy` is 'Local'"))
|
||||
}
|
||||
} else {
|
||||
if service.Spec.HealthCheckNodePort == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("healthCheckNodePort"), ""))
|
||||
} else {
|
||||
for _, msg := range validation.IsValidPortNum(int(service.Spec.HealthCheckNodePort)) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("healthCheckNodePort"), service.Spec.HealthCheckNodePort, msg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
@@ -4559,29 +4582,6 @@ func validateServiceInternalTrafficFieldsValue(service *core.Service) field.Erro
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validateServiceExternalTrafficFieldsCombination validates if ExternalTrafficPolicy,
|
||||
// HealthCheckNodePort and Type combination are legal. For update, it should be called
|
||||
// after clearing externalTraffic related fields for the ease of transitioning between
|
||||
// different service types.
|
||||
func validateServiceExternalTrafficFieldsCombination(service *core.Service) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if service.Spec.Type != core.ServiceTypeLoadBalancer &&
|
||||
service.Spec.Type != core.ServiceTypeNodePort &&
|
||||
service.Spec.ExternalTrafficPolicy != "" {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "externalTrafficPolicy"), service.Spec.ExternalTrafficPolicy,
|
||||
"ExternalTrafficPolicy can only be set on NodePort and LoadBalancer service"))
|
||||
}
|
||||
|
||||
if !apiservice.NeedsHealthCheck(service) &&
|
||||
service.Spec.HealthCheckNodePort != 0 {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "healthCheckNodePort"), service.Spec.HealthCheckNodePort,
|
||||
"HealthCheckNodePort can only be set on LoadBalancer service with ExternalTrafficPolicy=Local"))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateServiceCreate validates Services as they are created.
|
||||
func ValidateServiceCreate(service *core.Service) field.ErrorList {
|
||||
return ValidateService(service)
|
||||
|
Reference in New Issue
Block a user