Update go dependencies
This commit is contained in:
parent
432f534383
commit
f4a4daed84
1299 changed files with 71186 additions and 91183 deletions
49
vendor/k8s.io/apimachinery/pkg/api/equality/semantic.go
generated
vendored
49
vendor/k8s.io/apimachinery/pkg/api/equality/semantic.go
generated
vendored
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package equality
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
)
|
||||
|
||||
// Semantic can do semantic deep equality checks for api objects.
|
||||
// Example: apiequality.Semantic.DeepEqual(aPod, aPodWithNonNilButEmptyMaps) == true
|
||||
var Semantic = conversion.EqualitiesOrDie(
|
||||
func(a, b resource.Quantity) bool {
|
||||
// Ignore formatting, only care that numeric value stayed the same.
|
||||
// TODO: if we decide it's important, it should be safe to start comparing the format.
|
||||
//
|
||||
// Uninitialized quantities are equivalent to 0 quantities.
|
||||
return a.Cmp(b) == 0
|
||||
},
|
||||
func(a, b metav1.MicroTime) bool {
|
||||
return a.UTC() == b.UTC()
|
||||
},
|
||||
func(a, b metav1.Time) bool {
|
||||
return a.UTC() == b.UTC()
|
||||
},
|
||||
func(a, b labels.Selector) bool {
|
||||
return a.String() == b.String()
|
||||
},
|
||||
func(a, b fields.Selector) bool {
|
||||
return a.String() == b.String()
|
||||
},
|
||||
)
|
||||
16
vendor/k8s.io/apimachinery/pkg/api/errors/errors.go
generated
vendored
16
vendor/k8s.io/apimachinery/pkg/api/errors/errors.go
generated
vendored
|
|
@ -20,6 +20,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -82,7 +83,20 @@ func (u *UnexpectedObjectError) Error() string {
|
|||
func FromObject(obj runtime.Object) error {
|
||||
switch t := obj.(type) {
|
||||
case *metav1.Status:
|
||||
return &StatusError{*t}
|
||||
return &StatusError{ErrStatus: *t}
|
||||
case runtime.Unstructured:
|
||||
var status metav1.Status
|
||||
obj := t.UnstructuredContent()
|
||||
if !reflect.DeepEqual(obj["kind"], "Status") {
|
||||
break
|
||||
}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(t.UnstructuredContent(), &status); err != nil {
|
||||
return err
|
||||
}
|
||||
if status.APIVersion != "v1" && status.APIVersion != "meta.k8s.io/v1" {
|
||||
break
|
||||
}
|
||||
return &StatusError{ErrStatus: status}
|
||||
}
|
||||
return &UnexpectedObjectError{obj}
|
||||
}
|
||||
|
|
|
|||
22
vendor/k8s.io/apimachinery/pkg/api/meta/meta.go
generated
vendored
22
vendor/k8s.io/apimachinery/pkg/api/meta/meta.go
generated
vendored
|
|
@ -20,7 +20,7 @@ import (
|
|||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/klog"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||
|
|
@ -132,12 +132,12 @@ func AsPartialObjectMetadata(m metav1.Object) *metav1beta1.PartialObjectMetadata
|
|||
CreationTimestamp: m.GetCreationTimestamp(),
|
||||
DeletionTimestamp: m.GetDeletionTimestamp(),
|
||||
DeletionGracePeriodSeconds: m.GetDeletionGracePeriodSeconds(),
|
||||
Labels: m.GetLabels(),
|
||||
Annotations: m.GetAnnotations(),
|
||||
OwnerReferences: m.GetOwnerReferences(),
|
||||
Finalizers: m.GetFinalizers(),
|
||||
ClusterName: m.GetClusterName(),
|
||||
Initializers: m.GetInitializers(),
|
||||
Labels: m.GetLabels(),
|
||||
Annotations: m.GetAnnotations(),
|
||||
OwnerReferences: m.GetOwnerReferences(),
|
||||
Finalizers: m.GetFinalizers(),
|
||||
ClusterName: m.GetClusterName(),
|
||||
Initializers: m.GetInitializers(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -607,7 +607,7 @@ func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference {
|
|||
var ret []metav1.OwnerReference
|
||||
s := a.ownerReferences
|
||||
if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice {
|
||||
glog.Errorf("expect %v to be a pointer to slice", s)
|
||||
klog.Errorf("expect %v to be a pointer to slice", s)
|
||||
return ret
|
||||
}
|
||||
s = s.Elem()
|
||||
|
|
@ -615,7 +615,7 @@ func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference {
|
|||
ret = make([]metav1.OwnerReference, s.Len(), s.Len()+1)
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
if err := extractFromOwnerReference(s.Index(i), &ret[i]); err != nil {
|
||||
glog.Errorf("extractFromOwnerReference failed: %v", err)
|
||||
klog.Errorf("extractFromOwnerReference failed: %v", err)
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
|
@ -625,13 +625,13 @@ func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference {
|
|||
func (a genericAccessor) SetOwnerReferences(references []metav1.OwnerReference) {
|
||||
s := a.ownerReferences
|
||||
if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice {
|
||||
glog.Errorf("expect %v to be a pointer to slice", s)
|
||||
klog.Errorf("expect %v to be a pointer to slice", s)
|
||||
}
|
||||
s = s.Elem()
|
||||
newReferences := reflect.MakeSlice(s.Type(), len(references), len(references))
|
||||
for i := 0; i < len(references); i++ {
|
||||
if err := setOwnerReference(newReferences.Index(i), &references[i]); err != nil {
|
||||
glog.Errorf("setOwnerReference failed: %v", err)
|
||||
klog.Errorf("setOwnerReference failed: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
vendor/k8s.io/apimachinery/pkg/api/resource/generated.pb.go
generated
vendored
3
vendor/k8s.io/apimachinery/pkg/api/resource/generated.pb.go
generated
vendored
|
|
@ -14,9 +14,8 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by protoc-gen-gogo.
|
||||
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||
// source: k8s.io/kubernetes/vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto
|
||||
// DO NOT EDIT!
|
||||
|
||||
/*
|
||||
Package resource is a generated protocol buffer package.
|
||||
|
|
|
|||
20
vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto
generated
vendored
20
vendor/k8s.io/apimachinery/pkg/api/resource/generated.proto
generated
vendored
|
|
@ -27,9 +27,9 @@ option go_package = "resource";
|
|||
// Quantity is a fixed-point representation of a number.
|
||||
// It provides convenient marshaling/unmarshaling in JSON and YAML,
|
||||
// in addition to String() and Int64() accessors.
|
||||
//
|
||||
//
|
||||
// The serialization format is:
|
||||
//
|
||||
//
|
||||
// <quantity> ::= <signedNumber><suffix>
|
||||
// (Note that <suffix> may be empty, from the "" case in <decimalSI>.)
|
||||
// <digit> ::= 0 | 1 | ... | 9
|
||||
|
|
@ -43,16 +43,16 @@ option go_package = "resource";
|
|||
// <decimalSI> ::= m | "" | k | M | G | T | P | E
|
||||
// (Note that 1024 = 1Ki but 1000 = 1k; I didn't choose the capitalization.)
|
||||
// <decimalExponent> ::= "e" <signedNumber> | "E" <signedNumber>
|
||||
//
|
||||
//
|
||||
// No matter which of the three exponent forms is used, no quantity may represent
|
||||
// a number greater than 2^63-1 in magnitude, nor may it have more than 3 decimal
|
||||
// places. Numbers larger or more precise will be capped or rounded up.
|
||||
// (E.g.: 0.1m will rounded up to 1m.)
|
||||
// This may be extended in the future if we require larger or smaller quantities.
|
||||
//
|
||||
//
|
||||
// When a Quantity is parsed from a string, it will remember the type of suffix
|
||||
// it had, and will use the same type again when it is serialized.
|
||||
//
|
||||
//
|
||||
// Before serializing, Quantity will be put in "canonical form".
|
||||
// This means that Exponent/suffix will be adjusted up or down (with a
|
||||
// corresponding increase or decrease in Mantissa) such that:
|
||||
|
|
@ -60,22 +60,22 @@ option go_package = "resource";
|
|||
// b. No fractional digits will be emitted
|
||||
// c. The exponent (or suffix) is as large as possible.
|
||||
// The sign will be omitted unless the number is negative.
|
||||
//
|
||||
//
|
||||
// Examples:
|
||||
// 1.5 will be serialized as "1500m"
|
||||
// 1.5Gi will be serialized as "1536Mi"
|
||||
//
|
||||
//
|
||||
// Note that the quantity will NEVER be internally represented by a
|
||||
// floating point number. That is the whole point of this exercise.
|
||||
//
|
||||
//
|
||||
// Non-canonical values will still parse as long as they are well formed,
|
||||
// but will be re-emitted in their canonical form. (So always use canonical
|
||||
// form, or don't diff.)
|
||||
//
|
||||
//
|
||||
// This format is intended to make it difficult to use these numbers without
|
||||
// writing some sort of special handling code in the hopes that that will
|
||||
// cause implementors to also use a fixed point implementation.
|
||||
//
|
||||
//
|
||||
// +protobuf=true
|
||||
// +protobuf.embed=string
|
||||
// +protobuf.options.marshal=false
|
||||
|
|
|
|||
18
vendor/k8s.io/apimachinery/pkg/api/validation/doc.go
generated
vendored
18
vendor/k8s.io/apimachinery/pkg/api/validation/doc.go
generated
vendored
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package validation contains generic api type validation functions.
|
||||
package validation // import "k8s.io/apimachinery/pkg/api/validation"
|
||||
85
vendor/k8s.io/apimachinery/pkg/api/validation/generic.go
generated
vendored
85
vendor/k8s.io/apimachinery/pkg/api/validation/generic.go
generated
vendored
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
const IsNegativeErrorMsg string = `must be greater than or equal to 0`
|
||||
|
||||
// ValidateNameFunc validates that the provided name is valid for a given resource type.
|
||||
// Not all resources have the same validation rules for names. Prefix is true
|
||||
// if the name will have a value appended to it. If the name is not valid,
|
||||
// this returns a list of descriptions of individual characteristics of the
|
||||
// value that were not valid. Otherwise this returns an empty list or nil.
|
||||
type ValidateNameFunc func(name string, prefix bool) []string
|
||||
|
||||
// NameIsDNSSubdomain is a ValidateNameFunc for names that must be a DNS subdomain.
|
||||
func NameIsDNSSubdomain(name string, prefix bool) []string {
|
||||
if prefix {
|
||||
name = maskTrailingDash(name)
|
||||
}
|
||||
return validation.IsDNS1123Subdomain(name)
|
||||
}
|
||||
|
||||
// NameIsDNSLabel is a ValidateNameFunc for names that must be a DNS 1123 label.
|
||||
func NameIsDNSLabel(name string, prefix bool) []string {
|
||||
if prefix {
|
||||
name = maskTrailingDash(name)
|
||||
}
|
||||
return validation.IsDNS1123Label(name)
|
||||
}
|
||||
|
||||
// NameIsDNS1035Label is a ValidateNameFunc for names that must be a DNS 952 label.
|
||||
func NameIsDNS1035Label(name string, prefix bool) []string {
|
||||
if prefix {
|
||||
name = maskTrailingDash(name)
|
||||
}
|
||||
return validation.IsDNS1035Label(name)
|
||||
}
|
||||
|
||||
// ValidateNamespaceName can be used to check whether the given namespace name is valid.
|
||||
// Prefix indicates this name will be used as part of generation, in which case
|
||||
// trailing dashes are allowed.
|
||||
var ValidateNamespaceName = NameIsDNSLabel
|
||||
|
||||
// ValidateServiceAccountName can be used to check whether the given service account name is valid.
|
||||
// Prefix indicates this name will be used as part of generation, in which case
|
||||
// trailing dashes are allowed.
|
||||
var ValidateServiceAccountName = NameIsDNSSubdomain
|
||||
|
||||
// maskTrailingDash replaces the final character of a string with a subdomain safe
|
||||
// value if is a dash.
|
||||
func maskTrailingDash(name string) string {
|
||||
if strings.HasSuffix(name, "-") {
|
||||
return name[:len(name)-2] + "a"
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
// Validates that given value is not negative.
|
||||
func ValidateNonnegativeField(value int64, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if value < 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, value, IsNegativeErrorMsg))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
308
vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go
generated
vendored
308
vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go
generated
vendored
|
|
@ -1,308 +0,0 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package validation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
v1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
const FieldImmutableErrorMsg string = `field is immutable`
|
||||
|
||||
const totalAnnotationSizeLimitB int = 256 * (1 << 10) // 256 kB
|
||||
|
||||
// BannedOwners is a black list of object that are not allowed to be owners.
|
||||
var BannedOwners = map[schema.GroupVersionKind]struct{}{
|
||||
{Group: "", Version: "v1", Kind: "Event"}: {},
|
||||
}
|
||||
|
||||
// ValidateClusterName can be used to check whether the given cluster name is valid.
|
||||
var ValidateClusterName = NameIsDNS1035Label
|
||||
|
||||
// ValidateAnnotations validates that a set of annotations are correctly defined.
|
||||
func ValidateAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
var totalSize int64
|
||||
for k, v := range annotations {
|
||||
for _, msg := range validation.IsQualifiedName(strings.ToLower(k)) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, k, msg))
|
||||
}
|
||||
totalSize += (int64)(len(k)) + (int64)(len(v))
|
||||
}
|
||||
if totalSize > (int64)(totalAnnotationSizeLimitB) {
|
||||
allErrs = append(allErrs, field.TooLong(fldPath, "", totalAnnotationSizeLimitB))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateOwnerReference(ownerReference metav1.OwnerReference, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
gvk := schema.FromAPIVersionAndKind(ownerReference.APIVersion, ownerReference.Kind)
|
||||
// gvk.Group is empty for the legacy group.
|
||||
if len(gvk.Version) == 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("apiVersion"), ownerReference.APIVersion, "version must not be empty"))
|
||||
}
|
||||
if len(gvk.Kind) == 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("kind"), ownerReference.Kind, "kind must not be empty"))
|
||||
}
|
||||
if len(ownerReference.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), ownerReference.Name, "name must not be empty"))
|
||||
}
|
||||
if len(ownerReference.UID) == 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("uid"), ownerReference.UID, "uid must not be empty"))
|
||||
}
|
||||
if _, ok := BannedOwners[gvk]; ok {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ownerReference, fmt.Sprintf("%s is disallowed from being an owner", gvk)))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateOwnerReferences(ownerReferences []metav1.OwnerReference, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
controllerName := ""
|
||||
for _, ref := range ownerReferences {
|
||||
allErrs = append(allErrs, validateOwnerReference(ref, fldPath)...)
|
||||
if ref.Controller != nil && *ref.Controller {
|
||||
if controllerName != "" {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ownerReferences,
|
||||
fmt.Sprintf("Only one reference can have Controller set to true. Found \"true\" in references for %v and %v", controllerName, ref.Name)))
|
||||
} else {
|
||||
controllerName = ref.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// Validate finalizer names
|
||||
func ValidateFinalizerName(stringValue string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
for _, msg := range validation.IsQualifiedName(stringValue) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, stringValue, msg))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateNoNewFinalizers(newFinalizers []string, oldFinalizers []string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
extra := sets.NewString(newFinalizers...).Difference(sets.NewString(oldFinalizers...))
|
||||
if len(extra) != 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath, fmt.Sprintf("no new finalizers can be added if the object is being deleted, found new finalizers %#v", extra.List())))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateImmutableField(newVal, oldVal interface{}, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
if !apiequality.Semantic.DeepEqual(oldVal, newVal) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, newVal, FieldImmutableErrorMsg))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateObjectMeta validates an object's metadata on creation. It expects that name generation has already
|
||||
// been performed.
|
||||
// It doesn't return an error for rootscoped resources with namespace, because namespace should already be cleared before.
|
||||
func ValidateObjectMeta(objMeta *metav1.ObjectMeta, requiresNamespace bool, nameFn ValidateNameFunc, fldPath *field.Path) field.ErrorList {
|
||||
metadata, err := meta.Accessor(objMeta)
|
||||
if err != nil {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, objMeta, err.Error()))
|
||||
return allErrs
|
||||
}
|
||||
return ValidateObjectMetaAccessor(metadata, requiresNamespace, nameFn, fldPath)
|
||||
}
|
||||
|
||||
// ValidateObjectMeta validates an object's metadata on creation. It expects that name generation has already
|
||||
// been performed.
|
||||
// It doesn't return an error for rootscoped resources with namespace, because namespace should already be cleared before.
|
||||
func ValidateObjectMetaAccessor(meta metav1.Object, requiresNamespace bool, nameFn ValidateNameFunc, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if len(meta.GetGenerateName()) != 0 {
|
||||
for _, msg := range nameFn(meta.GetGenerateName(), true) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("generateName"), meta.GetGenerateName(), msg))
|
||||
}
|
||||
}
|
||||
// If the generated name validates, but the calculated value does not, it's a problem with generation, and we
|
||||
// report it here. This may confuse users, but indicates a programming bug and still must be validated.
|
||||
// If there are multiple fields out of which one is required then add an or as a separator
|
||||
if len(meta.GetName()) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("name"), "name or generateName is required"))
|
||||
} else {
|
||||
for _, msg := range nameFn(meta.GetName(), false) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("name"), meta.GetName(), msg))
|
||||
}
|
||||
}
|
||||
if requiresNamespace {
|
||||
if len(meta.GetNamespace()) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("namespace"), ""))
|
||||
} else {
|
||||
for _, msg := range ValidateNamespaceName(meta.GetNamespace(), false) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("namespace"), meta.GetNamespace(), msg))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if len(meta.GetNamespace()) != 0 {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("namespace"), "not allowed on this type"))
|
||||
}
|
||||
}
|
||||
if len(meta.GetClusterName()) != 0 {
|
||||
for _, msg := range ValidateClusterName(meta.GetClusterName(), false) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("clusterName"), meta.GetClusterName(), msg))
|
||||
}
|
||||
}
|
||||
allErrs = append(allErrs, ValidateNonnegativeField(meta.GetGeneration(), fldPath.Child("generation"))...)
|
||||
allErrs = append(allErrs, v1validation.ValidateLabels(meta.GetLabels(), fldPath.Child("labels"))...)
|
||||
allErrs = append(allErrs, ValidateAnnotations(meta.GetAnnotations(), fldPath.Child("annotations"))...)
|
||||
allErrs = append(allErrs, ValidateOwnerReferences(meta.GetOwnerReferences(), fldPath.Child("ownerReferences"))...)
|
||||
allErrs = append(allErrs, ValidateInitializers(meta.GetInitializers(), fldPath.Child("initializers"))...)
|
||||
allErrs = append(allErrs, ValidateFinalizers(meta.GetFinalizers(), fldPath.Child("finalizers"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateInitializers(initializers *metav1.Initializers, fldPath *field.Path) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
if initializers == nil {
|
||||
return allErrs
|
||||
}
|
||||
for i, initializer := range initializers.Pending {
|
||||
allErrs = append(allErrs, validation.IsFullyQualifiedName(fldPath.Child("pending").Index(i).Child("name"), initializer.Name)...)
|
||||
}
|
||||
allErrs = append(allErrs, validateInitializersResult(initializers.Result, fldPath.Child("result"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
func validateInitializersResult(result *metav1.Status, fldPath *field.Path) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
if result == nil {
|
||||
return allErrs
|
||||
}
|
||||
switch result.Status {
|
||||
case metav1.StatusFailure:
|
||||
default:
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("status"), result.Status, "must be 'Failure'"))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateFinalizers tests if the finalizers name are valid, and if there are conflicting finalizers.
|
||||
func ValidateFinalizers(finalizers []string, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
hasFinalizerOrphanDependents := false
|
||||
hasFinalizerDeleteDependents := false
|
||||
for _, finalizer := range finalizers {
|
||||
allErrs = append(allErrs, ValidateFinalizerName(finalizer, fldPath)...)
|
||||
if finalizer == metav1.FinalizerOrphanDependents {
|
||||
hasFinalizerOrphanDependents = true
|
||||
}
|
||||
if finalizer == metav1.FinalizerDeleteDependents {
|
||||
hasFinalizerDeleteDependents = true
|
||||
}
|
||||
}
|
||||
if hasFinalizerDeleteDependents && hasFinalizerOrphanDependents {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, finalizers, fmt.Sprintf("finalizer %s and %s cannot be both set", metav1.FinalizerOrphanDependents, metav1.FinalizerDeleteDependents)))
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateObjectMetaUpdate validates an object's metadata when updated
|
||||
func ValidateObjectMetaUpdate(newMeta, oldMeta *metav1.ObjectMeta, fldPath *field.Path) field.ErrorList {
|
||||
newMetadata, err := meta.Accessor(newMeta)
|
||||
if err != nil {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, newMeta, err.Error()))
|
||||
return allErrs
|
||||
}
|
||||
oldMetadata, err := meta.Accessor(oldMeta)
|
||||
if err != nil {
|
||||
allErrs := field.ErrorList{}
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, oldMeta, err.Error()))
|
||||
return allErrs
|
||||
}
|
||||
return ValidateObjectMetaAccessorUpdate(newMetadata, oldMetadata, fldPath)
|
||||
}
|
||||
|
||||
func ValidateObjectMetaAccessorUpdate(newMeta, oldMeta metav1.Object, fldPath *field.Path) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
|
||||
// Finalizers cannot be added if the object is already being deleted.
|
||||
if oldMeta.GetDeletionTimestamp() != nil {
|
||||
allErrs = append(allErrs, ValidateNoNewFinalizers(newMeta.GetFinalizers(), oldMeta.GetFinalizers(), fldPath.Child("finalizers"))...)
|
||||
}
|
||||
|
||||
// Reject updates that don't specify a resource version
|
||||
if len(newMeta.GetResourceVersion()) == 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("resourceVersion"), newMeta.GetResourceVersion(), "must be specified for an update"))
|
||||
}
|
||||
|
||||
// Generation shouldn't be decremented
|
||||
if newMeta.GetGeneration() < oldMeta.GetGeneration() {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("generation"), newMeta.GetGeneration(), "must not be decremented"))
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, ValidateInitializersUpdate(newMeta.GetInitializers(), oldMeta.GetInitializers(), fldPath.Child("initializers"))...)
|
||||
|
||||
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetName(), oldMeta.GetName(), fldPath.Child("name"))...)
|
||||
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetNamespace(), oldMeta.GetNamespace(), fldPath.Child("namespace"))...)
|
||||
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetUID(), oldMeta.GetUID(), fldPath.Child("uid"))...)
|
||||
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetCreationTimestamp(), oldMeta.GetCreationTimestamp(), fldPath.Child("creationTimestamp"))...)
|
||||
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetDeletionTimestamp(), oldMeta.GetDeletionTimestamp(), fldPath.Child("deletionTimestamp"))...)
|
||||
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetDeletionGracePeriodSeconds(), oldMeta.GetDeletionGracePeriodSeconds(), fldPath.Child("deletionGracePeriodSeconds"))...)
|
||||
allErrs = append(allErrs, ValidateImmutableField(newMeta.GetClusterName(), oldMeta.GetClusterName(), fldPath.Child("clusterName"))...)
|
||||
|
||||
allErrs = append(allErrs, v1validation.ValidateLabels(newMeta.GetLabels(), fldPath.Child("labels"))...)
|
||||
allErrs = append(allErrs, ValidateAnnotations(newMeta.GetAnnotations(), fldPath.Child("annotations"))...)
|
||||
allErrs = append(allErrs, ValidateOwnerReferences(newMeta.GetOwnerReferences(), fldPath.Child("ownerReferences"))...)
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateInitializersUpdate checks the update of the metadata initializers field
|
||||
func ValidateInitializersUpdate(newInit, oldInit *metav1.Initializers, fldPath *field.Path) field.ErrorList {
|
||||
var allErrs field.ErrorList
|
||||
switch {
|
||||
case oldInit == nil && newInit != nil:
|
||||
// Initializers may not be set on new objects
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, nil, "field is immutable once initialization has completed"))
|
||||
case oldInit != nil && newInit == nil:
|
||||
// this is a valid transition and means initialization was successful
|
||||
case oldInit != nil && newInit != nil:
|
||||
// validate changes to initializers
|
||||
switch {
|
||||
case oldInit.Result == nil && newInit.Result != nil:
|
||||
// setting a result is allowed
|
||||
allErrs = append(allErrs, validateInitializersResult(newInit.Result, fldPath.Child("result"))...)
|
||||
case oldInit.Result != nil:
|
||||
// setting Result implies permanent failure, and all future updates will be prevented
|
||||
allErrs = append(allErrs, ValidateImmutableField(newInit.Result, oldInit.Result, fldPath.Child("result"))...)
|
||||
default:
|
||||
// leaving the result nil is allowed
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue