git subrepo clone (merge) https://github.com/kubernetes-incubator/metrics-server.git metrics-server
subrepo:
subdir: "metrics-server"
merged: "92d8412"
upstream:
origin: "https://github.com/kubernetes-incubator/metrics-server.git"
branch: "master"
commit: "92d8412"
git-subrepo:
version: "0.4.0"
origin: "???"
commit: "???"
diff --git a/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/doc.go b/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/doc.go
new file mode 100644
index 0000000..9f20152
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/doc.go
@@ -0,0 +1,18 @@
+/*
+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"
diff --git a/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/generic.go b/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/generic.go
new file mode 100644
index 0000000..348cdc0
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/generic.go
@@ -0,0 +1,85 @@
+/*
+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
+}
diff --git a/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go b/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go
new file mode 100644
index 0000000..44b9b16
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/objectmeta.go
@@ -0,0 +1,308 @@
+/*
+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
+}
diff --git a/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/path/name.go b/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/path/name.go
new file mode 100644
index 0000000..a50cd08
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/apimachinery/pkg/api/validation/path/name.go
@@ -0,0 +1,68 @@
+/*
+Copyright 2015 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 path
+
+import (
+ "fmt"
+ "strings"
+)
+
+// NameMayNotBe specifies strings that cannot be used as names specified as path segments (like the REST API or etcd store)
+var NameMayNotBe = []string{".", ".."}
+
+// NameMayNotContain specifies substrings that cannot be used in names specified as path segments (like the REST API or etcd store)
+var NameMayNotContain = []string{"/", "%"}
+
+// IsValidPathSegmentName validates the name can be safely encoded as a path segment
+func IsValidPathSegmentName(name string) []string {
+ for _, illegalName := range NameMayNotBe {
+ if name == illegalName {
+ return []string{fmt.Sprintf(`may not be '%s'`, illegalName)}
+ }
+ }
+
+ var errors []string
+ for _, illegalContent := range NameMayNotContain {
+ if strings.Contains(name, illegalContent) {
+ errors = append(errors, fmt.Sprintf(`may not contain '%s'`, illegalContent))
+ }
+ }
+
+ return errors
+}
+
+// IsValidPathSegmentPrefix validates the name can be used as a prefix for a name which will be encoded as a path segment
+// It does not check for exact matches with disallowed names, since an arbitrary suffix might make the name valid
+func IsValidPathSegmentPrefix(name string) []string {
+ var errors []string
+ for _, illegalContent := range NameMayNotContain {
+ if strings.Contains(name, illegalContent) {
+ errors = append(errors, fmt.Sprintf(`may not contain '%s'`, illegalContent))
+ }
+ }
+
+ return errors
+}
+
+// ValidatePathSegmentName validates the name can be safely encoded as a path segment
+func ValidatePathSegmentName(name string, prefix bool) []string {
+ if prefix {
+ return IsValidPathSegmentPrefix(name)
+ } else {
+ return IsValidPathSegmentName(name)
+ }
+}