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/plugins.go b/metrics-server/vendor/k8s.io/apiserver/pkg/admission/plugins.go
new file mode 100644
index 0000000..c17d62c
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/apiserver/pkg/admission/plugins.go
@@ -0,0 +1,208 @@
+/*
+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 (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"reflect"
+	"sort"
+	"strings"
+	"sync"
+
+	"github.com/golang/glog"
+)
+
+// Factory is a function that returns an Interface for admission decisions.
+// The config parameter provides an io.Reader handler to the factory in
+// order to load specific configurations. If no configuration is provided
+// the parameter is nil.
+type Factory func(config io.Reader) (Interface, error)
+
+type Plugins struct {
+	lock     sync.Mutex
+	registry map[string]Factory
+}
+
+func NewPlugins() *Plugins {
+	return &Plugins{}
+}
+
+// All registered admission options.
+var (
+	// PluginEnabledFn checks whether a plugin is enabled.  By default, if you ask about it, it's enabled.
+	PluginEnabledFn = func(name string, config io.Reader) bool {
+		return true
+	}
+)
+
+// PluginEnabledFunc is a function type that can provide an external check on whether an admission plugin may be enabled
+type PluginEnabledFunc func(name string, config io.Reader) bool
+
+// Registered enumerates the names of all registered plugins.
+func (ps *Plugins) Registered() []string {
+	ps.lock.Lock()
+	defer ps.lock.Unlock()
+	keys := []string{}
+	for k := range ps.registry {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	return keys
+}
+
+// Register registers a plugin Factory by name. This
+// is expected to happen during app startup.
+func (ps *Plugins) Register(name string, plugin Factory) {
+	ps.lock.Lock()
+	defer ps.lock.Unlock()
+	if ps.registry != nil {
+		_, found := ps.registry[name]
+		if found {
+			glog.Fatalf("Admission plugin %q was registered twice", name)
+		}
+	} else {
+		ps.registry = map[string]Factory{}
+	}
+
+	glog.V(1).Infof("Registered admission plugin %q", name)
+	ps.registry[name] = plugin
+}
+
+// getPlugin creates an instance of the named plugin.  It returns `false` if the
+// the name is not known. The error is returned only when the named provider was
+// known but failed to initialize.  The config parameter specifies the io.Reader
+// handler of the configuration file for the cloud provider, or nil for no configuration.
+func (ps *Plugins) getPlugin(name string, config io.Reader) (Interface, bool, error) {
+	ps.lock.Lock()
+	defer ps.lock.Unlock()
+	f, found := ps.registry[name]
+	if !found {
+		return nil, false, nil
+	}
+
+	config1, config2, err := splitStream(config)
+	if err != nil {
+		return nil, true, err
+	}
+	if !PluginEnabledFn(name, config1) {
+		return nil, true, nil
+	}
+
+	ret, err := f(config2)
+	return ret, true, err
+}
+
+// splitStream reads the stream bytes and constructs two copies of it.
+func splitStream(config io.Reader) (io.Reader, io.Reader, error) {
+	if config == nil || reflect.ValueOf(config).IsNil() {
+		return nil, nil, nil
+	}
+
+	configBytes, err := ioutil.ReadAll(config)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return bytes.NewBuffer(configBytes), bytes.NewBuffer(configBytes), nil
+}
+
+// NewFromPlugins returns an admission.Interface that will enforce admission control decisions of all
+// the given plugins.
+func (ps *Plugins) NewFromPlugins(pluginNames []string, configProvider ConfigProvider, pluginInitializer PluginInitializer, decorator Decorator) (Interface, error) {
+	handlers := []Interface{}
+	mutationPlugins := []string{}
+	validationPlugins := []string{}
+	for _, pluginName := range pluginNames {
+		pluginConfig, err := configProvider.ConfigFor(pluginName)
+		if err != nil {
+			return nil, err
+		}
+
+		plugin, err := ps.InitPlugin(pluginName, pluginConfig, pluginInitializer)
+		if err != nil {
+			return nil, err
+		}
+		if plugin != nil {
+			if decorator != nil {
+				handlers = append(handlers, decorator.Decorate(plugin, pluginName))
+			} else {
+				handlers = append(handlers, plugin)
+			}
+
+			if _, ok := plugin.(MutationInterface); ok {
+				mutationPlugins = append(mutationPlugins, pluginName)
+			}
+			if _, ok := plugin.(ValidationInterface); ok {
+				validationPlugins = append(validationPlugins, pluginName)
+			}
+		}
+	}
+	if len(mutationPlugins) != 0 {
+		glog.Infof("Loaded %d mutating admission controller(s) successfully in the following order: %s.", len(mutationPlugins), strings.Join(mutationPlugins, ","))
+	}
+	if len(validationPlugins) != 0 {
+		glog.Infof("Loaded %d validating admission controller(s) successfully in the following order: %s.", len(validationPlugins), strings.Join(validationPlugins, ","))
+	}
+	return chainAdmissionHandler(handlers), nil
+}
+
+// InitPlugin creates an instance of the named interface.
+func (ps *Plugins) InitPlugin(name string, config io.Reader, pluginInitializer PluginInitializer) (Interface, error) {
+	if name == "" {
+		glog.Info("No admission plugin specified.")
+		return nil, nil
+	}
+
+	plugin, found, err := ps.getPlugin(name, config)
+	if err != nil {
+		return nil, fmt.Errorf("couldn't init admission plugin %q: %v", name, err)
+	}
+	if !found {
+		return nil, fmt.Errorf("unknown admission plugin: %s", name)
+	}
+
+	pluginInitializer.Initialize(plugin)
+	// ensure that plugins have been properly initialized
+	if err := ValidateInitialization(plugin); err != nil {
+		return nil, fmt.Errorf("failed to initialize admission plugin %q: %v", name, err)
+	}
+
+	return plugin, nil
+}
+
+// ValidateInitialization will call the InitializationValidate function in each plugin if they implement
+// the InitializationValidator interface.
+func ValidateInitialization(plugin Interface) error {
+	if validater, ok := plugin.(InitializationValidator); ok {
+		err := validater.ValidateInitialization()
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+type PluginInitializers []PluginInitializer
+
+func (pp PluginInitializers) Initialize(plugin Interface) {
+	for _, p := range pp {
+		p.Initialize(plugin)
+	}
+}