...

Source file src/k8s.io/kube-aggregator/pkg/apis/apiregistration/validation/validation.go

Documentation: k8s.io/kube-aggregator/pkg/apis/apiregistration/validation

     1  /*
     2  Copyright 2016 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package validation
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  
    23  	"k8s.io/apimachinery/pkg/api/validation"
    24  	"k8s.io/apimachinery/pkg/api/validation/path"
    25  	utilvalidation "k8s.io/apimachinery/pkg/util/validation"
    26  	"k8s.io/apimachinery/pkg/util/validation/field"
    27  
    28  	"k8s.io/kube-aggregator/pkg/apis/apiregistration"
    29  )
    30  
    31  // ValidateAPIService validates that the APIService is correctly defined.
    32  func ValidateAPIService(apiService *apiregistration.APIService) field.ErrorList {
    33  	requiredName := apiService.Spec.Version + "." + apiService.Spec.Group
    34  
    35  	allErrs := validation.ValidateObjectMeta(&apiService.ObjectMeta, false,
    36  		func(name string, prefix bool) []string {
    37  			if minimalFailures := path.IsValidPathSegmentName(name); len(minimalFailures) > 0 {
    38  				return minimalFailures
    39  			}
    40  			// the name *must* be version.group
    41  			if name != requiredName {
    42  				return []string{fmt.Sprintf("must be `spec.version+\".\"+spec.group`: %q", requiredName)}
    43  			}
    44  
    45  			return []string{}
    46  		},
    47  		field.NewPath("metadata"))
    48  
    49  	// in this case we allow empty group
    50  	if len(apiService.Spec.Group) == 0 && apiService.Spec.Version != "v1" {
    51  		allErrs = append(allErrs, field.Required(field.NewPath("spec", "group"), "only v1 may have an empty group and it better be legacy kube"))
    52  	}
    53  	if len(apiService.Spec.Group) > 0 {
    54  		for _, errString := range utilvalidation.IsDNS1123Subdomain(apiService.Spec.Group) {
    55  			allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "group"), apiService.Spec.Group, errString))
    56  		}
    57  	}
    58  
    59  	for _, errString := range utilvalidation.IsDNS1035Label(apiService.Spec.Version) {
    60  		allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "version"), apiService.Spec.Version, errString))
    61  	}
    62  
    63  	if apiService.Spec.GroupPriorityMinimum <= 0 || apiService.Spec.GroupPriorityMinimum > 20000 {
    64  		allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "groupPriorityMinimum"), apiService.Spec.GroupPriorityMinimum, "must be positive and less than 20000"))
    65  	}
    66  	if apiService.Spec.VersionPriority <= 0 || apiService.Spec.VersionPriority > 1000 {
    67  		allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "versionPriority"), apiService.Spec.VersionPriority, "must be positive and less than 1000"))
    68  	}
    69  
    70  	if apiService.Spec.Service == nil {
    71  		if len(apiService.Spec.CABundle) != 0 {
    72  			allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "caBundle"), fmt.Sprintf("%d bytes", len(apiService.Spec.CABundle)), "local APIServices may not have a caBundle"))
    73  		}
    74  		if apiService.Spec.InsecureSkipTLSVerify {
    75  			allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "insecureSkipTLSVerify"), apiService.Spec.InsecureSkipTLSVerify, "local APIServices may not have insecureSkipTLSVerify"))
    76  		}
    77  		return allErrs
    78  	}
    79  
    80  	if len(apiService.Spec.Service.Namespace) == 0 {
    81  		allErrs = append(allErrs, field.Required(field.NewPath("spec", "service", "namespace"), ""))
    82  	}
    83  	if len(apiService.Spec.Service.Name) == 0 {
    84  		allErrs = append(allErrs, field.Required(field.NewPath("spec", "service", "name"), ""))
    85  	}
    86  	if errs := utilvalidation.IsValidPortNum(int(apiService.Spec.Service.Port)); errs != nil {
    87  		allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "service", "port"), apiService.Spec.Service.Port, "port is not valid: "+strings.Join(errs, ", ")))
    88  	}
    89  	if apiService.Spec.InsecureSkipTLSVerify && len(apiService.Spec.CABundle) > 0 {
    90  		allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "insecureSkipTLSVerify"), apiService.Spec.InsecureSkipTLSVerify, "may not be true if caBundle is present"))
    91  	}
    92  
    93  	return allErrs
    94  }
    95  
    96  // ValidateAPIServiceUpdate validates an update of APIService.
    97  func ValidateAPIServiceUpdate(newAPIService *apiregistration.APIService, oldAPIService *apiregistration.APIService) field.ErrorList {
    98  	allErrs := validation.ValidateObjectMetaUpdate(&newAPIService.ObjectMeta, &oldAPIService.ObjectMeta, field.NewPath("metadata"))
    99  	allErrs = append(allErrs, ValidateAPIService(newAPIService)...)
   100  
   101  	return allErrs
   102  }
   103  
   104  // ValidateAPIServiceStatus validates that the APIService status is one of 'True', 'False' or 'Unknown'.
   105  func ValidateAPIServiceStatus(status *apiregistration.APIServiceStatus, fldPath *field.Path) field.ErrorList {
   106  	allErrs := field.ErrorList{}
   107  
   108  	for i, condition := range status.Conditions {
   109  		if condition.Status != apiregistration.ConditionTrue &&
   110  			condition.Status != apiregistration.ConditionFalse &&
   111  			condition.Status != apiregistration.ConditionUnknown {
   112  			allErrs = append(allErrs, field.NotSupported(fldPath.Child("conditions").Index(i).Child("status"), condition.Status, []string{
   113  				string(apiregistration.ConditionTrue), string(apiregistration.ConditionFalse), string(apiregistration.ConditionUnknown)}))
   114  		}
   115  	}
   116  
   117  	return allErrs
   118  }
   119  
   120  // ValidateAPIServiceStatusUpdate validates an update of the status field of APIService.
   121  func ValidateAPIServiceStatusUpdate(newAPIService *apiregistration.APIService, oldAPIService *apiregistration.APIService) field.ErrorList {
   122  	allErrs := validation.ValidateObjectMetaUpdate(&newAPIService.ObjectMeta, &oldAPIService.ObjectMeta, field.NewPath("metadata"))
   123  	allErrs = append(allErrs, ValidateAPIServiceStatus(&newAPIService.Status, field.NewPath("status"))...)
   124  	return allErrs
   125  }
   126  

View as plain text