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/apiserver/pkg/admission/attributes.go b/metrics-server/vendor/k8s.io/apiserver/pkg/admission/attributes.go
new file mode 100644
index 0000000..7272e88
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/apiserver/pkg/admission/attributes.go
@@ -0,0 +1,140 @@
+/*
+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 admission
+
+import (
+ "fmt"
+ "strings"
+ "sync"
+
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/util/validation"
+ "k8s.io/apiserver/pkg/authentication/user"
+)
+
+type attributesRecord struct {
+ kind schema.GroupVersionKind
+ namespace string
+ name string
+ resource schema.GroupVersionResource
+ subresource string
+ operation Operation
+ object runtime.Object
+ oldObject runtime.Object
+ userInfo user.Info
+
+ // other elements are always accessed in single goroutine.
+ // But ValidatingAdmissionWebhook add annotations concurrently.
+ annotations map[string]string
+ annotationsLock sync.RWMutex
+}
+
+func NewAttributesRecord(object runtime.Object, oldObject runtime.Object, kind schema.GroupVersionKind, namespace, name string, resource schema.GroupVersionResource, subresource string, operation Operation, userInfo user.Info) Attributes {
+ return &attributesRecord{
+ kind: kind,
+ namespace: namespace,
+ name: name,
+ resource: resource,
+ subresource: subresource,
+ operation: operation,
+ object: object,
+ oldObject: oldObject,
+ userInfo: userInfo,
+ }
+}
+
+func (record *attributesRecord) GetKind() schema.GroupVersionKind {
+ return record.kind
+}
+
+func (record *attributesRecord) GetNamespace() string {
+ return record.namespace
+}
+
+func (record *attributesRecord) GetName() string {
+ return record.name
+}
+
+func (record *attributesRecord) GetResource() schema.GroupVersionResource {
+ return record.resource
+}
+
+func (record *attributesRecord) GetSubresource() string {
+ return record.subresource
+}
+
+func (record *attributesRecord) GetOperation() Operation {
+ return record.operation
+}
+
+func (record *attributesRecord) GetObject() runtime.Object {
+ return record.object
+}
+
+func (record *attributesRecord) GetOldObject() runtime.Object {
+ return record.oldObject
+}
+
+func (record *attributesRecord) GetUserInfo() user.Info {
+ return record.userInfo
+}
+
+// getAnnotations implements privateAnnotationsGetter.It's a private method used
+// by WithAudit decorator.
+func (record *attributesRecord) getAnnotations() map[string]string {
+ record.annotationsLock.RLock()
+ defer record.annotationsLock.RUnlock()
+
+ if record.annotations == nil {
+ return nil
+ }
+ cp := make(map[string]string, len(record.annotations))
+ for key, value := range record.annotations {
+ cp[key] = value
+ }
+ return cp
+}
+
+func (record *attributesRecord) AddAnnotation(key, value string) error {
+ if err := checkKeyFormat(key); err != nil {
+ return err
+ }
+
+ record.annotationsLock.Lock()
+ defer record.annotationsLock.Unlock()
+
+ if record.annotations == nil {
+ record.annotations = make(map[string]string)
+ }
+ if v, ok := record.annotations[key]; ok && v != value {
+ return fmt.Errorf("admission annotations are not allowd to be overwritten, key:%q, old value: %q, new value:%q", key, record.annotations[key], value)
+ }
+ record.annotations[key] = value
+ return nil
+}
+
+func checkKeyFormat(key string) error {
+ parts := strings.Split(key, "/")
+ if len(parts) != 2 {
+ return fmt.Errorf("annotation key has invalid format, the right format is a DNS subdomain prefix and '/' and key name. (e.g. 'podsecuritypolicy.admission.k8s.io/admit-policy')")
+ }
+ if msgs := validation.IsQualifiedName(key); len(msgs) != 0 {
+ return fmt.Errorf("annotation key has invalid format %s. A qualified name like 'podsecuritypolicy.admission.k8s.io/admit-policy' is required.", strings.Join(msgs, ","))
+ }
+ return nil
+}