From 593b1c6c63ed3a3edd0a17922d84c0211f3f1f6e Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Wed, 10 Jan 2024 12:30:55 -0500 Subject: [PATCH] Do service.spec.LoadBalancerSourceRanges validation inline Inline the LoadBalancerSourceRanges parsing to make it more obvious what it's requiring (and more importantly, *not* requiring), and change it to use IsValidCIDR as well. --- pkg/apis/core/validation/validation.go | 38 ++++++++++++++++---------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go index 686d184781f..61b543cc587 100644 --- a/pkg/apis/core/validation/validation.go +++ b/pkg/apis/core/validation/validation.go @@ -5450,24 +5450,32 @@ func ValidateService(service *core.Service) field.ErrorList { ports[key] = true } - // Validate SourceRange field and annotation - _, ok := service.Annotations[core.AnnotationLoadBalancerSourceRangesKey] - if len(service.Spec.LoadBalancerSourceRanges) > 0 || ok { - var fieldPath *field.Path - var val string - if len(service.Spec.LoadBalancerSourceRanges) > 0 { - fieldPath = specPath.Child("LoadBalancerSourceRanges") - val = fmt.Sprintf("%v", service.Spec.LoadBalancerSourceRanges) - } else { - fieldPath = field.NewPath("metadata", "annotations").Key(core.AnnotationLoadBalancerSourceRangesKey) - val = service.Annotations[core.AnnotationLoadBalancerSourceRangesKey] - } + // Validate SourceRanges field or annotation. + if len(service.Spec.LoadBalancerSourceRanges) > 0 { + fieldPath := specPath.Child("LoadBalancerSourceRanges") + if service.Spec.Type != core.ServiceTypeLoadBalancer { allErrs = append(allErrs, field.Forbidden(fieldPath, "may only be used when `type` is 'LoadBalancer'")) } - _, err := apiservice.GetLoadBalancerSourceRanges(service) - if err != nil { - allErrs = append(allErrs, field.Invalid(fieldPath, val, "must be a list of IP ranges. For example, 10.240.0.0/24,10.250.0.0/24 ")) + for idx, value := range service.Spec.LoadBalancerSourceRanges { + // Note: due to a historical accident around transition from the + // annotation value, these values are allowed to be space-padded. + value = strings.TrimSpace(value) + allErrs = append(allErrs, validation.IsValidCIDR(fieldPath.Index(idx), value)...) + } + } else if val, annotationSet := service.Annotations[core.AnnotationLoadBalancerSourceRangesKey]; annotationSet { + fieldPath := field.NewPath("metadata", "annotations").Key(core.AnnotationLoadBalancerSourceRangesKey) + if service.Spec.Type != core.ServiceTypeLoadBalancer { + allErrs = append(allErrs, field.Forbidden(fieldPath, "may only be used when `type` is 'LoadBalancer'")) + } + + val = strings.TrimSpace(val) + if val != "" { + cidrs := strings.Split(val, ",") + for _, value := range cidrs { + value = strings.TrimSpace(value) + allErrs = append(allErrs, validation.IsValidCIDR(fieldPath, value)...) + } } }