diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/builder/doc.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/builder/doc.go
new file mode 100644
index 0000000..c310906
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/builder/doc.go
@@ -0,0 +1,20 @@
+/*
+Copyright 2016 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 builder contains code to generate OpenAPI discovery spec (which
+// initial version of it also known as Swagger 2.0).
+// For more details: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md
+package builder
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/builder/openapi.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/builder/openapi.go
new file mode 100644
index 0000000..f48700d
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/builder/openapi.go
@@ -0,0 +1,457 @@
+/*
+Copyright 2016 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 builder
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"reflect"
+	"strings"
+
+	restful "github.com/emicklei/go-restful"
+	"github.com/go-openapi/spec"
+
+	"k8s.io/kube-openapi/pkg/common"
+	"k8s.io/kube-openapi/pkg/util"
+)
+
+const (
+	OpenAPIVersion = "2.0"
+	// TODO: Make this configurable.
+	extensionPrefix = "x-kubernetes-"
+)
+
+type openAPI struct {
+	config       *common.Config
+	swagger      *spec.Swagger
+	protocolList []string
+	definitions  map[string]common.OpenAPIDefinition
+}
+
+// BuildOpenAPISpec builds OpenAPI spec given a list of webservices (containing routes) and common.Config to customize it.
+func BuildOpenAPISpec(webServices []*restful.WebService, config *common.Config) (*spec.Swagger, error) {
+	o := newOpenAPI(config)
+	err := o.buildPaths(webServices)
+	if err != nil {
+		return nil, err
+	}
+	return o.finalizeSwagger()
+}
+
+// BuildOpenAPIDefinitionsForResource builds a partial OpenAPI spec given a sample object and common.Config to customize it.
+func BuildOpenAPIDefinitionsForResource(model interface{}, config *common.Config) (*spec.Definitions, error) {
+	o := newOpenAPI(config)
+	// We can discard the return value of toSchema because all we care about is the side effect of calling it.
+	// All the models created for this resource get added to o.swagger.Definitions
+	_, err := o.toSchema(getCanonicalTypeName(model))
+	if err != nil {
+		return nil, err
+	}
+	swagger, err := o.finalizeSwagger()
+	if err != nil {
+		return nil, err
+	}
+	return &swagger.Definitions, nil
+}
+
+// BuildOpenAPIDefinitionsForResources returns the OpenAPI spec which includes the definitions for the
+// passed type names.
+func BuildOpenAPIDefinitionsForResources(config *common.Config, names ...string) (*spec.Swagger, error) {
+	o := newOpenAPI(config)
+	// We can discard the return value of toSchema because all we care about is the side effect of calling it.
+	// All the models created for this resource get added to o.swagger.Definitions
+	for _, name := range names {
+		_, err := o.toSchema(name)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return o.finalizeSwagger()
+}
+
+// newOpenAPI sets up the openAPI object so we can build the spec.
+func newOpenAPI(config *common.Config) openAPI {
+	o := openAPI{
+		config: config,
+		swagger: &spec.Swagger{
+			SwaggerProps: spec.SwaggerProps{
+				Swagger:     OpenAPIVersion,
+				Definitions: spec.Definitions{},
+				Paths:       &spec.Paths{Paths: map[string]spec.PathItem{}},
+				Info:        config.Info,
+			},
+		},
+	}
+	if o.config.GetOperationIDAndTags == nil {
+		o.config.GetOperationIDAndTags = func(r *restful.Route) (string, []string, error) {
+			return r.Operation, nil, nil
+		}
+	}
+	if o.config.GetDefinitionName == nil {
+		o.config.GetDefinitionName = func(name string) (string, spec.Extensions) {
+			return name[strings.LastIndex(name, "/")+1:], nil
+		}
+	}
+	o.definitions = o.config.GetDefinitions(func(name string) spec.Ref {
+		defName, _ := o.config.GetDefinitionName(name)
+		return spec.MustCreateRef("#/definitions/" + common.EscapeJsonPointer(defName))
+	})
+	if o.config.CommonResponses == nil {
+		o.config.CommonResponses = map[int]spec.Response{}
+	}
+	return o
+}
+
+// finalizeSwagger is called after the spec is built and returns the final spec.
+// NOTE: finalizeSwagger also make changes to the final spec, as specified in the config.
+func (o *openAPI) finalizeSwagger() (*spec.Swagger, error) {
+	if o.config.SecurityDefinitions != nil {
+		o.swagger.SecurityDefinitions = *o.config.SecurityDefinitions
+		o.swagger.Security = o.config.DefaultSecurity
+	}
+	if o.config.PostProcessSpec != nil {
+		var err error
+		o.swagger, err = o.config.PostProcessSpec(o.swagger)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	return o.swagger, nil
+}
+
+func getCanonicalTypeName(model interface{}) string {
+	t := reflect.TypeOf(model)
+	if t.Kind() == reflect.Ptr {
+		t = t.Elem()
+	}
+	if t.PkgPath() == "" {
+		return t.Name()
+	}
+	path := t.PkgPath()
+	if strings.Contains(path, "/vendor/") {
+		path = path[strings.Index(path, "/vendor/")+len("/vendor/"):]
+	}
+	return path + "." + t.Name()
+}
+
+func (o *openAPI) buildDefinitionRecursively(name string) error {
+	uniqueName, extensions := o.config.GetDefinitionName(name)
+	if _, ok := o.swagger.Definitions[uniqueName]; ok {
+		return nil
+	}
+	if item, ok := o.definitions[name]; ok {
+		schema := spec.Schema{
+			VendorExtensible:   item.Schema.VendorExtensible,
+			SchemaProps:        item.Schema.SchemaProps,
+			SwaggerSchemaProps: item.Schema.SwaggerSchemaProps,
+		}
+		if extensions != nil {
+			if schema.Extensions == nil {
+				schema.Extensions = spec.Extensions{}
+			}
+			for k, v := range extensions {
+				schema.Extensions[k] = v
+			}
+		}
+		o.swagger.Definitions[uniqueName] = schema
+		for _, v := range item.Dependencies {
+			if err := o.buildDefinitionRecursively(v); err != nil {
+				return err
+			}
+		}
+	} else {
+		return fmt.Errorf("cannot find model definition for %v. If you added a new type, you may need to add +k8s:openapi-gen=true to the package or type and run code-gen again", name)
+	}
+	return nil
+}
+
+// buildDefinitionForType build a definition for a given type and return a referable name to its definition.
+// This is the main function that keep track of definitions used in this spec and is depend on code generated
+// by k8s.io/kubernetes/cmd/libs/go2idl/openapi-gen.
+func (o *openAPI) buildDefinitionForType(name string) (string, error) {
+	if err := o.buildDefinitionRecursively(name); err != nil {
+		return "", err
+	}
+	defName, _ := o.config.GetDefinitionName(name)
+	return "#/definitions/" + common.EscapeJsonPointer(defName), nil
+}
+
+// buildPaths builds OpenAPI paths using go-restful's web services.
+func (o *openAPI) buildPaths(webServices []*restful.WebService) error {
+	pathsToIgnore := util.NewTrie(o.config.IgnorePrefixes)
+	duplicateOpId := make(map[string]string)
+	for _, w := range webServices {
+		rootPath := w.RootPath()
+		if pathsToIgnore.HasPrefix(rootPath) {
+			continue
+		}
+		commonParams, err := o.buildParameters(w.PathParameters())
+		if err != nil {
+			return err
+		}
+		for path, routes := range groupRoutesByPath(w.Routes()) {
+			// go-swagger has special variable definition {$NAME:*} that can only be
+			// used at the end of the path and it is not recognized by OpenAPI.
+			if strings.HasSuffix(path, ":*}") {
+				path = path[:len(path)-3] + "}"
+			}
+			if pathsToIgnore.HasPrefix(path) {
+				continue
+			}
+			// Aggregating common parameters make API spec (and generated clients) simpler
+			inPathCommonParamsMap, err := o.findCommonParameters(routes)
+			if err != nil {
+				return err
+			}
+			pathItem, exists := o.swagger.Paths.Paths[path]
+			if exists {
+				return fmt.Errorf("duplicate webservice route has been found for path: %v", path)
+			}
+			pathItem = spec.PathItem{
+				PathItemProps: spec.PathItemProps{
+					Parameters: make([]spec.Parameter, 0),
+				},
+			}
+			// add web services's parameters as well as any parameters appears in all ops, as common parameters
+			pathItem.Parameters = append(pathItem.Parameters, commonParams...)
+			for _, p := range inPathCommonParamsMap {
+				pathItem.Parameters = append(pathItem.Parameters, p)
+			}
+			sortParameters(pathItem.Parameters)
+			for _, route := range routes {
+				op, err := o.buildOperations(route, inPathCommonParamsMap)
+				sortParameters(op.Parameters)
+				if err != nil {
+					return err
+				}
+				dpath, exists := duplicateOpId[op.ID]
+				if exists {
+					return fmt.Errorf("duplicate Operation ID %v for path %v and %v", op.ID, dpath, path)
+				} else {
+					duplicateOpId[op.ID] = path
+				}
+				switch strings.ToUpper(route.Method) {
+				case "GET":
+					pathItem.Get = op
+				case "POST":
+					pathItem.Post = op
+				case "HEAD":
+					pathItem.Head = op
+				case "PUT":
+					pathItem.Put = op
+				case "DELETE":
+					pathItem.Delete = op
+				case "OPTIONS":
+					pathItem.Options = op
+				case "PATCH":
+					pathItem.Patch = op
+				}
+			}
+			o.swagger.Paths.Paths[path] = pathItem
+		}
+	}
+	return nil
+}
+
+// buildOperations builds operations for each webservice path
+func (o *openAPI) buildOperations(route restful.Route, inPathCommonParamsMap map[interface{}]spec.Parameter) (ret *spec.Operation, err error) {
+	ret = &spec.Operation{
+		OperationProps: spec.OperationProps{
+			Description: route.Doc,
+			Consumes:    route.Consumes,
+			Produces:    route.Produces,
+			Schemes:     o.config.ProtocolList,
+			Responses: &spec.Responses{
+				ResponsesProps: spec.ResponsesProps{
+					StatusCodeResponses: make(map[int]spec.Response),
+				},
+			},
+		},
+	}
+	for k, v := range route.Metadata {
+		if strings.HasPrefix(k, extensionPrefix) {
+			if ret.Extensions == nil {
+				ret.Extensions = spec.Extensions{}
+			}
+			ret.Extensions.Add(k, v)
+		}
+	}
+	if ret.ID, ret.Tags, err = o.config.GetOperationIDAndTags(&route); err != nil {
+		return ret, err
+	}
+
+	// Build responses
+	for _, resp := range route.ResponseErrors {
+		ret.Responses.StatusCodeResponses[resp.Code], err = o.buildResponse(resp.Model, resp.Message)
+		if err != nil {
+			return ret, err
+		}
+	}
+	// If there is no response but a write sample, assume that write sample is an http.StatusOK response.
+	if len(ret.Responses.StatusCodeResponses) == 0 && route.WriteSample != nil {
+		ret.Responses.StatusCodeResponses[http.StatusOK], err = o.buildResponse(route.WriteSample, "OK")
+		if err != nil {
+			return ret, err
+		}
+	}
+	for code, resp := range o.config.CommonResponses {
+		if _, exists := ret.Responses.StatusCodeResponses[code]; !exists {
+			ret.Responses.StatusCodeResponses[code] = resp
+		}
+	}
+	// If there is still no response, use default response provided.
+	if len(ret.Responses.StatusCodeResponses) == 0 {
+		ret.Responses.Default = o.config.DefaultResponse
+	}
+
+	// Build non-common Parameters
+	ret.Parameters = make([]spec.Parameter, 0)
+	for _, param := range route.ParameterDocs {
+		if _, isCommon := inPathCommonParamsMap[mapKeyFromParam(param)]; !isCommon {
+			openAPIParam, err := o.buildParameter(param.Data(), route.ReadSample)
+			if err != nil {
+				return ret, err
+			}
+			ret.Parameters = append(ret.Parameters, openAPIParam)
+		}
+	}
+	return ret, nil
+}
+
+func (o *openAPI) buildResponse(model interface{}, description string) (spec.Response, error) {
+	schema, err := o.toSchema(getCanonicalTypeName(model))
+	if err != nil {
+		return spec.Response{}, err
+	}
+	return spec.Response{
+		ResponseProps: spec.ResponseProps{
+			Description: description,
+			Schema:      schema,
+		},
+	}, nil
+}
+
+func (o *openAPI) findCommonParameters(routes []restful.Route) (map[interface{}]spec.Parameter, error) {
+	commonParamsMap := make(map[interface{}]spec.Parameter, 0)
+	paramOpsCountByName := make(map[interface{}]int, 0)
+	paramNameKindToDataMap := make(map[interface{}]restful.ParameterData, 0)
+	for _, route := range routes {
+		routeParamDuplicateMap := make(map[interface{}]bool)
+		s := ""
+		for _, param := range route.ParameterDocs {
+			m, _ := json.Marshal(param.Data())
+			s += string(m) + "\n"
+			key := mapKeyFromParam(param)
+			if routeParamDuplicateMap[key] {
+				msg, _ := json.Marshal(route.ParameterDocs)
+				return commonParamsMap, fmt.Errorf("duplicate parameter %v for route %v, %v", param.Data().Name, string(msg), s)
+			}
+			routeParamDuplicateMap[key] = true
+			paramOpsCountByName[key]++
+			paramNameKindToDataMap[key] = param.Data()
+		}
+	}
+	for key, count := range paramOpsCountByName {
+		paramData := paramNameKindToDataMap[key]
+		if count == len(routes) && paramData.Kind != restful.BodyParameterKind {
+			openAPIParam, err := o.buildParameter(paramData, nil)
+			if err != nil {
+				return commonParamsMap, err
+			}
+			commonParamsMap[key] = openAPIParam
+		}
+	}
+	return commonParamsMap, nil
+}
+
+func (o *openAPI) toSchema(name string) (_ *spec.Schema, err error) {
+	if openAPIType, openAPIFormat := common.GetOpenAPITypeFormat(name); openAPIType != "" {
+		return &spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Type:   []string{openAPIType},
+				Format: openAPIFormat,
+			},
+		}, nil
+	} else {
+		ref, err := o.buildDefinitionForType(name)
+		if err != nil {
+			return nil, err
+		}
+		return &spec.Schema{
+			SchemaProps: spec.SchemaProps{
+				Ref: spec.MustCreateRef(ref),
+			},
+		}, nil
+	}
+}
+
+func (o *openAPI) buildParameter(restParam restful.ParameterData, bodySample interface{}) (ret spec.Parameter, err error) {
+	ret = spec.Parameter{
+		ParamProps: spec.ParamProps{
+			Name:        restParam.Name,
+			Description: restParam.Description,
+			Required:    restParam.Required,
+		},
+	}
+	switch restParam.Kind {
+	case restful.BodyParameterKind:
+		if bodySample != nil {
+			ret.In = "body"
+			ret.Schema, err = o.toSchema(getCanonicalTypeName(bodySample))
+			return ret, err
+		} else {
+			// There is not enough information in the body parameter to build the definition.
+			// Body parameter has a data type that is a short name but we need full package name
+			// of the type to create a definition.
+			return ret, fmt.Errorf("restful body parameters are not supported: %v", restParam.DataType)
+		}
+	case restful.PathParameterKind:
+		ret.In = "path"
+		if !restParam.Required {
+			return ret, fmt.Errorf("path parameters should be marked at required for parameter %v", restParam)
+		}
+	case restful.QueryParameterKind:
+		ret.In = "query"
+	case restful.HeaderParameterKind:
+		ret.In = "header"
+	case restful.FormParameterKind:
+		ret.In = "formData"
+	default:
+		return ret, fmt.Errorf("unknown restful operation kind : %v", restParam.Kind)
+	}
+	openAPIType, openAPIFormat := common.GetOpenAPITypeFormat(restParam.DataType)
+	if openAPIType == "" {
+		return ret, fmt.Errorf("non-body Restful parameter type should be a simple type, but got : %v", restParam.DataType)
+	}
+	ret.Type = openAPIType
+	ret.Format = openAPIFormat
+	ret.UniqueItems = !restParam.AllowMultiple
+	return ret, nil
+}
+
+func (o *openAPI) buildParameters(restParam []*restful.Parameter) (ret []spec.Parameter, err error) {
+	ret = make([]spec.Parameter, len(restParam))
+	for i, v := range restParam {
+		ret[i], err = o.buildParameter(v.Data(), nil)
+		if err != nil {
+			return ret, err
+		}
+	}
+	return ret, nil
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/builder/util.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/builder/util.go
new file mode 100644
index 0000000..5e9a56a
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/builder/util.go
@@ -0,0 +1,61 @@
+/*
+Copyright 2016 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 builder
+
+import (
+	"sort"
+
+	"github.com/emicklei/go-restful"
+	"github.com/go-openapi/spec"
+)
+
+type parameters []spec.Parameter
+
+func (s parameters) Len() int      { return len(s) }
+func (s parameters) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// byNameIn used in sorting parameters by Name and In fields.
+type byNameIn struct {
+	parameters
+}
+
+func (s byNameIn) Less(i, j int) bool {
+	return s.parameters[i].Name < s.parameters[j].Name || (s.parameters[i].Name == s.parameters[j].Name && s.parameters[i].In < s.parameters[j].In)
+}
+
+// SortParameters sorts parameters by Name and In fields.
+func sortParameters(p []spec.Parameter) {
+	sort.Sort(byNameIn{p})
+}
+
+func groupRoutesByPath(routes []restful.Route) map[string][]restful.Route {
+	pathToRoutes := make(map[string][]restful.Route)
+	for _, r := range routes {
+		pathToRoutes[r.Path] = append(pathToRoutes[r.Path], r)
+	}
+	return pathToRoutes
+}
+
+func mapKeyFromParam(param *restful.Parameter) interface{} {
+	return struct {
+		Name string
+		Kind int
+	}{
+		Name: param.Data().Name,
+		Kind: param.Data().Kind,
+	}
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/common/common.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/common/common.go
new file mode 100644
index 0000000..0d23587
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/common/common.go
@@ -0,0 +1,168 @@
+/*
+Copyright 2016 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 common
+
+import (
+	"net/http"
+	"strings"
+
+	"github.com/emicklei/go-restful"
+	"github.com/go-openapi/spec"
+)
+
+// OpenAPIDefinition describes single type. Normally these definitions are auto-generated using gen-openapi.
+type OpenAPIDefinition struct {
+	Schema       spec.Schema
+	Dependencies []string
+}
+
+type ReferenceCallback func(path string) spec.Ref
+
+// GetOpenAPIDefinitions is collection of all definitions.
+type GetOpenAPIDefinitions func(ReferenceCallback) map[string]OpenAPIDefinition
+
+// OpenAPIDefinitionGetter gets openAPI definitions for a given type. If a type implements this interface,
+// the definition returned by it will be used, otherwise the auto-generated definitions will be used. See
+// GetOpenAPITypeFormat for more information about trade-offs of using this interface or GetOpenAPITypeFormat method when
+// possible.
+type OpenAPIDefinitionGetter interface {
+	OpenAPIDefinition() *OpenAPIDefinition
+}
+
+type PathHandler interface {
+	Handle(path string, handler http.Handler)
+}
+
+// Config is set of configuration for openAPI spec generation.
+type Config struct {
+	// List of supported protocols such as https, http, etc.
+	ProtocolList []string
+
+	// Info is general information about the API.
+	Info *spec.Info
+
+	// DefaultResponse will be used if an operation does not have any responses listed. It
+	// will show up as ... "responses" : {"default" : $DefaultResponse} in the spec.
+	DefaultResponse *spec.Response
+
+	// CommonResponses will be added as a response to all operation specs. This is a good place to add common
+	// responses such as authorization failed.
+	CommonResponses map[int]spec.Response
+
+	// List of webservice's path prefixes to ignore
+	IgnorePrefixes []string
+
+	// OpenAPIDefinitions should provide definition for all models used by routes. Failure to provide this map
+	// or any of the models will result in spec generation failure.
+	GetDefinitions GetOpenAPIDefinitions
+
+	// GetOperationIDAndTags returns operation id and tags for a restful route. It is an optional function to customize operation IDs.
+	GetOperationIDAndTags func(r *restful.Route) (string, []string, error)
+
+	// GetDefinitionName returns a friendly name for a definition base on the serving path. parameter `name` is the full name of the definition.
+	// It is an optional function to customize model names.
+	GetDefinitionName func(name string) (string, spec.Extensions)
+
+	// PostProcessSpec runs after the spec is ready to serve. It allows a final modification to the spec before serving.
+	PostProcessSpec func(*spec.Swagger) (*spec.Swagger, error)
+
+	// SecurityDefinitions is list of all security definitions for OpenAPI service. If this is not nil, the user of config
+	// is responsible to provide DefaultSecurity and (maybe) add unauthorized response to CommonResponses.
+	SecurityDefinitions *spec.SecurityDefinitions
+
+	// DefaultSecurity for all operations. This will pass as spec.SwaggerProps.Security to OpenAPI.
+	// For most cases, this will be list of acceptable definitions in SecurityDefinitions.
+	DefaultSecurity []map[string][]string
+}
+
+var schemaTypeFormatMap = map[string][]string{
+	"uint":        {"integer", "int32"},
+	"uint8":       {"integer", "byte"},
+	"uint16":      {"integer", "int32"},
+	"uint32":      {"integer", "int64"},
+	"uint64":      {"integer", "int64"},
+	"int":         {"integer", "int32"},
+	"int8":        {"integer", "byte"},
+	"int16":       {"integer", "int32"},
+	"int32":       {"integer", "int32"},
+	"int64":       {"integer", "int64"},
+	"byte":        {"integer", "byte"},
+	"float64":     {"number", "double"},
+	"float32":     {"number", "float"},
+	"bool":        {"boolean", ""},
+	"time.Time":   {"string", "date-time"},
+	"string":      {"string", ""},
+	"integer":     {"integer", ""},
+	"number":      {"number", ""},
+	"boolean":     {"boolean", ""},
+	"[]byte":      {"string", "byte"}, // base64 encoded characters
+	"interface{}": {"object", ""},
+}
+
+// This function is a reference for converting go (or any custom type) to a simple open API type,format pair. There are
+// two ways to customize spec for a type. If you add it here, a type will be converted to a simple type and the type
+// comment (the comment that is added before type definition) will be lost. The spec will still have the property
+// comment. The second way is to implement OpenAPIDefinitionGetter interface. That function can customize the spec (so
+// the spec does not need to be simple type,format) or can even return a simple type,format (e.g. IntOrString). For simple
+// type formats, the benefit of adding OpenAPIDefinitionGetter interface is to keep both type and property documentation.
+// Example:
+// type Sample struct {
+//      ...
+//      // port of the server
+//      port IntOrString
+//      ...
+// }
+// // IntOrString documentation...
+// type IntOrString { ... }
+//
+// Adding IntOrString to this function:
+// "port" : {
+//           format:      "string",
+//           type:        "int-or-string",
+//           Description: "port of the server"
+// }
+//
+// Implement OpenAPIDefinitionGetter for IntOrString:
+//
+// "port" : {
+//           $Ref:    "#/definitions/IntOrString"
+//           Description: "port of the server"
+// }
+// ...
+// definitions:
+// {
+//           "IntOrString": {
+//                     format:      "string",
+//                     type:        "int-or-string",
+//                     Description: "IntOrString documentation..."    // new
+//           }
+// }
+//
+func GetOpenAPITypeFormat(typeName string) (string, string) {
+	mapped, ok := schemaTypeFormatMap[typeName]
+	if !ok {
+		return "", ""
+	}
+	return mapped[0], mapped[1]
+}
+
+func EscapeJsonPointer(p string) string {
+	// Escaping reference name using rfc6901
+	p = strings.Replace(p, "~", "~0", -1)
+	p = strings.Replace(p, "/", "~1", -1)
+	return p
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/common/doc.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/common/doc.go
new file mode 100644
index 0000000..2ba6d24
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/common/doc.go
@@ -0,0 +1,19 @@
+/*
+Copyright 2016 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 common holds shared code and types between open API code
+// generator and spec generator.
+package common
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/README b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/README
new file mode 100644
index 0000000..feb19b4
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/README
@@ -0,0 +1,46 @@
+# Generate OpenAPI definitions
+
+- To generate definition for a specific type or package add "+k8s:openapi-gen=true" tag to the type/package comment lines.
+- To exclude a type or a member from a tagged package/type, add "+k8s:openapi-gen=false" tag to the comment lines.
+
+# OpenAPI Extensions
+OpenAPI spec can have extensions on types. To define one or more extensions on a type or its member
+add `+k8s:openapi-gen=x-kubernetes-$NAME:`$VALUE`` to the comment lines before type/member. A type/member can
+have multiple extensions. The rest of the line in the comment will be used as $VALUE so there is no need to
+escape or quote the value string. Extensions can be used to pass more information to client generators or
+documentation generators. For example a type might have a friendly name to be displayed in documentation or
+being used in a client's fluent interface.
+
+# Custom OpenAPI type definitions
+
+Custom types which otherwise don't map directly to OpenAPI can override their
+OpenAPI definition by implementing a function named "OpenAPIDefinition" with
+the following signature:
+
+	import openapi "k8s.io/kube-openapi/pkg/common"
+
+	// ...
+
+	type Time struct {
+		time.Time
+	}
+
+	func (_ Time) OpenAPIDefinition() openapi.OpenAPIDefinition {
+		return openapi.OpenAPIDefinition{
+			Schema: spec.Schema{
+				SchemaProps: spec.SchemaProps{
+					Type:   []string{"string"},
+					Format: "date-time",
+				},
+			},
+		}
+	}
+
+Alternatively, the type can avoid the "openapi" import by defining the following
+methods. The following example produces the same OpenAPI definition as the
+example above:
+
+    func (_ Time) OpenAPISchemaType() []string { return []string{"string"} }
+    func (_ Time) OpenAPISchemaFormat() string { return "date-time" }
+
+TODO(mehdy): Make k8s:openapi-gen a parameter to the generator now that OpenAPI has its own repo.
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/api_linter.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/api_linter.go
new file mode 100644
index 0000000..9270d26
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/api_linter.go
@@ -0,0 +1,100 @@
+/*
+Copyright 2018 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 generators
+
+import (
+	"fmt"
+	"io"
+
+	"k8s.io/kube-openapi/pkg/generators/rules"
+
+	"github.com/golang/glog"
+	"k8s.io/gengo/types"
+)
+
+// apiLinter is the framework hosting mutliple API rules and recording API rule
+// violations
+type apiLinter struct {
+	// API rules that implement APIRule interface and output API rule violations
+	rules      []APIRule
+	violations []apiViolation
+}
+
+// newAPILinter creates an apiLinter object with API rules in package rules. Please
+// add APIRule here when new API rule is implemented.
+func newAPILinter() *apiLinter {
+	return &apiLinter{
+		rules: []APIRule{
+			&rules.NamesMatch{},
+		},
+	}
+}
+
+// apiViolation uniquely identifies single API rule violation
+type apiViolation struct {
+	// Name of rule from APIRule.Name()
+	rule string
+
+	packageName string
+	typeName    string
+
+	// Optional: name of field that violates API rule. Empty fieldName implies that
+	// the entire type violates the rule.
+	field string
+}
+
+// APIRule is the interface for validating API rule on Go types
+type APIRule interface {
+	// Validate evaluates API rule on type t and returns a list of field names in
+	// the type that violate the rule. Empty field name [""] implies the entire
+	// type violates the rule.
+	Validate(t *types.Type) ([]string, error)
+
+	// Name returns the name of APIRule
+	Name() string
+}
+
+// validate runs all API rules on type t and records any API rule violation
+func (l *apiLinter) validate(t *types.Type) error {
+	for _, r := range l.rules {
+		glog.V(5).Infof("validating API rule %v for type %v", r.Name(), t)
+		fields, err := r.Validate(t)
+		if err != nil {
+			return err
+		}
+		for _, field := range fields {
+			l.violations = append(l.violations, apiViolation{
+				rule:        r.Name(),
+				packageName: t.Name.Package,
+				typeName:    t.Name.Name,
+				field:       field,
+			})
+		}
+	}
+	return nil
+}
+
+// report prints any API rule violation to writer w and returns error if violation exists
+func (l *apiLinter) report(w io.Writer) error {
+	for _, v := range l.violations {
+		fmt.Fprintf(w, "API rule violation: %s,%s,%s,%s\n", v.rule, v.packageName, v.typeName, v.field)
+	}
+	if len(l.violations) > 0 {
+		return fmt.Errorf("API rule violations exist")
+	}
+	return nil
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/extension.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/extension.go
new file mode 100644
index 0000000..befe38d
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/extension.go
@@ -0,0 +1,182 @@
+/*
+Copyright 2018 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 generators
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+
+	"k8s.io/gengo/examples/set-gen/sets"
+	"k8s.io/gengo/types"
+)
+
+const extensionPrefix = "x-kubernetes-"
+
+// extensionAttributes encapsulates common traits for particular extensions.
+type extensionAttributes struct {
+	xName         string
+	kind          types.Kind
+	allowedValues sets.String
+}
+
+// Extension tag to openapi extension attributes
+var tagToExtension = map[string]extensionAttributes{
+	"patchMergeKey": extensionAttributes{
+		xName: "x-kubernetes-patch-merge-key",
+		kind:  types.Slice,
+	},
+	"patchStrategy": extensionAttributes{
+		xName:         "x-kubernetes-patch-strategy",
+		kind:          types.Slice,
+		allowedValues: sets.NewString("merge", "retainKeys"),
+	},
+	"listMapKey": extensionAttributes{
+		xName: "x-kubernetes-list-map-keys",
+		kind:  types.Slice,
+	},
+	"listType": extensionAttributes{
+		xName:         "x-kubernetes-list-type",
+		kind:          types.Slice,
+		allowedValues: sets.NewString("atomic", "set", "map"),
+	},
+}
+
+// Extension encapsulates information necessary to generate an OpenAPI extension.
+type extension struct {
+	idlTag string   // Example: listType
+	xName  string   // Example: x-kubernetes-list-type
+	values []string // Example: [atomic]
+}
+
+func (e extension) hasAllowedValues() bool {
+	return tagToExtension[e.idlTag].allowedValues.Len() > 0
+}
+
+func (e extension) allowedValues() sets.String {
+	return tagToExtension[e.idlTag].allowedValues
+}
+
+func (e extension) hasKind() bool {
+	return len(tagToExtension[e.idlTag].kind) > 0
+}
+
+func (e extension) kind() types.Kind {
+	return tagToExtension[e.idlTag].kind
+}
+
+func (e extension) validateAllowedValues() error {
+	// allowedValues not set means no restrictions on values.
+	if !e.hasAllowedValues() {
+		return nil
+	}
+	// Check for missing value.
+	if len(e.values) == 0 {
+		return fmt.Errorf("%s needs a value, none given.", e.idlTag)
+	}
+	// For each extension value, validate that it is allowed.
+	allowedValues := e.allowedValues()
+	if !allowedValues.HasAll(e.values...) {
+		return fmt.Errorf("%v not allowed for %s. Allowed values: %v",
+			e.values, e.idlTag, allowedValues.List())
+	}
+	return nil
+}
+
+func (e extension) validateType(kind types.Kind) error {
+	// If this extension class has no kind, then don't validate the type.
+	if !e.hasKind() {
+		return nil
+	}
+	if kind != e.kind() {
+		return fmt.Errorf("tag %s on type %v; only allowed on type %v",
+			e.idlTag, kind, e.kind())
+	}
+	return nil
+}
+
+func (e extension) hasMultipleValues() bool {
+	return len(e.values) > 1
+}
+
+// Returns sorted list of map keys. Needed for deterministic testing.
+func sortedMapKeys(m map[string][]string) []string {
+	keys := make([]string, len(m))
+	i := 0
+	for k := range m {
+		keys[i] = k
+		i++
+	}
+	sort.Strings(keys)
+	return keys
+}
+
+// Parses comments to return openapi extensions. Returns a list of
+// extensions which parsed correctly, as well as a list of the
+// parse errors. Validating extensions is performed separately.
+// NOTE: Non-empty errors does not mean extensions is empty.
+func parseExtensions(comments []string) ([]extension, []error) {
+	extensions := []extension{}
+	errors := []error{}
+	// First, generate extensions from "+k8s:openapi-gen=x-kubernetes-*" annotations.
+	values := getOpenAPITagValue(comments)
+	for _, val := range values {
+		// Example: x-kubernetes-member-tag:member_test
+		if strings.HasPrefix(val, extensionPrefix) {
+			parts := strings.SplitN(val, ":", 2)
+			if len(parts) != 2 {
+				errors = append(errors, fmt.Errorf("invalid extension value: %v", val))
+				continue
+			}
+			e := extension{
+				idlTag: tagName,            // Example: k8s:openapi-gen
+				xName:  parts[0],           // Example: x-kubernetes-member-tag
+				values: []string{parts[1]}, // Example: member_test
+			}
+			extensions = append(extensions, e)
+		}
+	}
+	// Next, generate extensions from "idlTags" (e.g. +listType)
+	tagValues := types.ExtractCommentTags("+", comments)
+	for _, idlTag := range sortedMapKeys(tagValues) {
+		xAttrs, exists := tagToExtension[idlTag]
+		if !exists {
+			continue
+		}
+		values := tagValues[idlTag]
+		e := extension{
+			idlTag: idlTag,       // listType
+			xName:  xAttrs.xName, // x-kubernetes-list-type
+			values: values,       // [atomic]
+		}
+		extensions = append(extensions, e)
+	}
+	return extensions, errors
+}
+
+func validateMemberExtensions(extensions []extension, m *types.Member) []error {
+	errors := []error{}
+	for _, e := range extensions {
+		if err := e.validateAllowedValues(); err != nil {
+			errors = append(errors, err)
+		}
+		if err := e.validateType(m.Type.Kind); err != nil {
+			errors = append(errors, err)
+		}
+	}
+	return errors
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go
new file mode 100644
index 0000000..d6c6275
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/openapi.go
@@ -0,0 +1,704 @@
+/*
+Copyright 2016 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 generators
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+	"path/filepath"
+	"reflect"
+	"sort"
+	"strings"
+
+	"k8s.io/gengo/args"
+	"k8s.io/gengo/generator"
+	"k8s.io/gengo/namer"
+	"k8s.io/gengo/types"
+	generatorargs "k8s.io/kube-openapi/cmd/openapi-gen/args"
+	openapi "k8s.io/kube-openapi/pkg/common"
+
+	"github.com/golang/glog"
+)
+
+// This is the comment tag that carries parameters for open API generation.
+const tagName = "k8s:openapi-gen"
+const tagOptional = "optional"
+
+// Known values for the tag.
+const (
+	tagValueTrue  = "true"
+	tagValueFalse = "false"
+)
+
+// Used for temporary validation of patch struct tags.
+// TODO: Remove patch struct tag validation because they we are now consuming OpenAPI on server.
+var tempPatchTags = [...]string{
+	"patchMergeKey",
+	"patchStrategy",
+}
+
+func getOpenAPITagValue(comments []string) []string {
+	return types.ExtractCommentTags("+", comments)[tagName]
+}
+
+func getSingleTagsValue(comments []string, tag string) (string, error) {
+	tags, ok := types.ExtractCommentTags("+", comments)[tag]
+	if !ok || len(tags) == 0 {
+		return "", nil
+	}
+	if len(tags) > 1 {
+		return "", fmt.Errorf("multiple values are not allowed for tag %s", tag)
+	}
+	return tags[0], nil
+}
+
+func hasOpenAPITagValue(comments []string, value string) bool {
+	tagValues := getOpenAPITagValue(comments)
+	for _, val := range tagValues {
+		if val == value {
+			return true
+		}
+	}
+	return false
+}
+
+// hasOptionalTag returns true if the member has +optional in its comments or
+// omitempty in its json tags.
+func hasOptionalTag(m *types.Member) bool {
+	hasOptionalCommentTag := types.ExtractCommentTags(
+		"+", m.CommentLines)[tagOptional] != nil
+	hasOptionalJsonTag := strings.Contains(
+		reflect.StructTag(m.Tags).Get("json"), "omitempty")
+	return hasOptionalCommentTag || hasOptionalJsonTag
+}
+
+type identityNamer struct{}
+
+func (_ identityNamer) Name(t *types.Type) string {
+	return t.Name.String()
+}
+
+var _ namer.Namer = identityNamer{}
+
+// NameSystems returns the name system used by the generators in this package.
+func NameSystems() namer.NameSystems {
+	return namer.NameSystems{
+		"raw":           namer.NewRawNamer("", nil),
+		"sorting_namer": identityNamer{},
+	}
+}
+
+// DefaultNameSystem returns the default name system for ordering the types to be
+// processed by the generators in this package.
+func DefaultNameSystem() string {
+	return "sorting_namer"
+}
+
+func Packages(context *generator.Context, arguments *args.GeneratorArgs) generator.Packages {
+	boilerplate, err := arguments.LoadGoBoilerplate()
+	if err != nil {
+		glog.Fatalf("Failed loading boilerplate: %v", err)
+	}
+	header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...)
+	header = append(header, []byte(
+		`
+// This file was autogenerated by openapi-gen. Do not edit it manually!
+
+`)...)
+
+	reportFilename := "-"
+	if customArgs, ok := arguments.CustomArgs.(*generatorargs.CustomArgs); ok {
+		reportFilename = customArgs.ReportFilename
+	}
+
+	return generator.Packages{
+		&generator.DefaultPackage{
+			PackageName: filepath.Base(arguments.OutputPackagePath),
+			PackagePath: arguments.OutputPackagePath,
+			HeaderText:  header,
+			GeneratorFunc: func(c *generator.Context) (generators []generator.Generator) {
+				return []generator.Generator{NewOpenAPIGen(arguments.OutputFileBaseName, arguments.OutputPackagePath, context, newAPILinter(), reportFilename)}
+			},
+			FilterFunc: func(c *generator.Context, t *types.Type) bool {
+				// There is a conflict between this codegen and codecgen, we should avoid types generated for codecgen
+				if strings.HasPrefix(t.Name.Name, "codecSelfer") {
+					return false
+				}
+				pkg := context.Universe.Package(t.Name.Package)
+				if hasOpenAPITagValue(pkg.Comments, tagValueTrue) {
+					return !hasOpenAPITagValue(t.CommentLines, tagValueFalse)
+				}
+				if hasOpenAPITagValue(t.CommentLines, tagValueTrue) {
+					return true
+				}
+				return false
+			},
+		},
+	}
+}
+
+const (
+	specPackagePath          = "github.com/go-openapi/spec"
+	openAPICommonPackagePath = "k8s.io/kube-openapi/pkg/common"
+)
+
+// openApiGen produces a file with auto-generated OpenAPI functions.
+type openAPIGen struct {
+	generator.DefaultGen
+	// TargetPackage is the package that will get GetOpenAPIDefinitions function returns all open API definitions.
+	targetPackage  string
+	imports        namer.ImportTracker
+	types          []*types.Type
+	context        *generator.Context
+	linter         *apiLinter
+	reportFilename string
+}
+
+func NewOpenAPIGen(sanitizedName string, targetPackage string, context *generator.Context, linter *apiLinter, reportFilename string) generator.Generator {
+	return &openAPIGen{
+		DefaultGen: generator.DefaultGen{
+			OptionalName: sanitizedName,
+		},
+		imports:        generator.NewImportTracker(),
+		targetPackage:  targetPackage,
+		context:        context,
+		linter:         linter,
+		reportFilename: reportFilename,
+	}
+}
+
+const nameTmpl = "schema_$.type|private$"
+
+func (g *openAPIGen) Namers(c *generator.Context) namer.NameSystems {
+	// Have the raw namer for this file track what it imports.
+	return namer.NameSystems{
+		"raw": namer.NewRawNamer(g.targetPackage, g.imports),
+		"private": &namer.NameStrategy{
+			Join: func(pre string, in []string, post string) string {
+				return strings.Join(in, "_")
+			},
+			PrependPackageNames: 4, // enough to fully qualify from k8s.io/api/...
+		},
+	}
+}
+
+func (g *openAPIGen) Filter(c *generator.Context, t *types.Type) bool {
+	// There is a conflict between this codegen and codecgen, we should avoid types generated for codecgen
+	if strings.HasPrefix(t.Name.Name, "codecSelfer") {
+		return false
+	}
+	g.types = append(g.types, t)
+	return true
+}
+
+func (g *openAPIGen) isOtherPackage(pkg string) bool {
+	if pkg == g.targetPackage {
+		return false
+	}
+	if strings.HasSuffix(pkg, "\""+g.targetPackage+"\"") {
+		return false
+	}
+	return true
+}
+
+func (g *openAPIGen) Imports(c *generator.Context) []string {
+	importLines := []string{}
+	for _, singleImport := range g.imports.ImportLines() {
+		importLines = append(importLines, singleImport)
+	}
+	return importLines
+}
+
+func argsFromType(t *types.Type) generator.Args {
+	return generator.Args{
+		"type":              t,
+		"ReferenceCallback": types.Ref(openAPICommonPackagePath, "ReferenceCallback"),
+		"OpenAPIDefinition": types.Ref(openAPICommonPackagePath, "OpenAPIDefinition"),
+		"SpecSchemaType":    types.Ref(specPackagePath, "Schema"),
+	}
+}
+
+func (g *openAPIGen) Init(c *generator.Context, w io.Writer) error {
+	sw := generator.NewSnippetWriter(w, c, "$", "$")
+	sw.Do("func GetOpenAPIDefinitions(ref $.ReferenceCallback|raw$) map[string]$.OpenAPIDefinition|raw$ {\n", argsFromType(nil))
+	sw.Do("return map[string]$.OpenAPIDefinition|raw${\n", argsFromType(nil))
+
+	for _, t := range g.types {
+		err := newOpenAPITypeWriter(sw).generateCall(t)
+		if err != nil {
+			return err
+		}
+	}
+
+	sw.Do("}\n", nil)
+	sw.Do("}\n\n", nil)
+
+	return sw.Error()
+}
+
+func (g *openAPIGen) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
+	glog.V(5).Infof("validating API rules for type %v", t)
+	if err := g.linter.validate(t); err != nil {
+		return err
+	}
+	glog.V(5).Infof("generating for type %v", t)
+	sw := generator.NewSnippetWriter(w, c, "$", "$")
+	err := newOpenAPITypeWriter(sw).generate(t)
+	if err != nil {
+		return err
+	}
+	return sw.Error()
+}
+
+func getJsonTags(m *types.Member) []string {
+	jsonTag := reflect.StructTag(m.Tags).Get("json")
+	if jsonTag == "" {
+		return []string{}
+	}
+	return strings.Split(jsonTag, ",")
+}
+
+func getReferableName(m *types.Member) string {
+	jsonTags := getJsonTags(m)
+	if len(jsonTags) > 0 {
+		if jsonTags[0] == "-" {
+			return ""
+		} else {
+			return jsonTags[0]
+		}
+	} else {
+		return m.Name
+	}
+}
+
+func shouldInlineMembers(m *types.Member) bool {
+	jsonTags := getJsonTags(m)
+	return len(jsonTags) > 1 && jsonTags[1] == "inline"
+}
+
+type openAPITypeWriter struct {
+	*generator.SnippetWriter
+	refTypes               map[string]*types.Type
+	GetDefinitionInterface *types.Type
+}
+
+func newOpenAPITypeWriter(sw *generator.SnippetWriter) openAPITypeWriter {
+	return openAPITypeWriter{
+		SnippetWriter: sw,
+		refTypes:      map[string]*types.Type{},
+	}
+}
+
+func methodReturnsValue(mt *types.Type, pkg, name string) bool {
+	if len(mt.Signature.Parameters) != 0 || len(mt.Signature.Results) != 1 {
+		return false
+	}
+	r := mt.Signature.Results[0]
+	return r.Name.Name == name && r.Name.Package == pkg
+}
+
+func hasOpenAPIDefinitionMethod(t *types.Type) bool {
+	for mn, mt := range t.Methods {
+		if mn != "OpenAPIDefinition" {
+			continue
+		}
+		return methodReturnsValue(mt, openAPICommonPackagePath, "OpenAPIDefinition")
+	}
+	return false
+}
+
+func hasOpenAPIDefinitionMethods(t *types.Type) bool {
+	var hasSchemaTypeMethod, hasOpenAPISchemaFormat bool
+	for mn, mt := range t.Methods {
+		switch mn {
+		case "OpenAPISchemaType":
+			hasSchemaTypeMethod = methodReturnsValue(mt, "", "[]string")
+		case "OpenAPISchemaFormat":
+			hasOpenAPISchemaFormat = methodReturnsValue(mt, "", "string")
+		}
+	}
+	return hasSchemaTypeMethod && hasOpenAPISchemaFormat
+}
+
+// typeShortName returns short package name (e.g. the name x appears in package x definition) dot type name.
+func typeShortName(t *types.Type) string {
+	return filepath.Base(t.Name.Package) + "." + t.Name.Name
+}
+
+func (g openAPITypeWriter) generateMembers(t *types.Type, required []string) ([]string, error) {
+	var err error
+	for _, m := range t.Members {
+		if hasOpenAPITagValue(m.CommentLines, tagValueFalse) {
+			continue
+		}
+		if shouldInlineMembers(&m) {
+			required, err = g.generateMembers(m.Type, required)
+			if err != nil {
+				return required, err
+			}
+			continue
+		}
+		name := getReferableName(&m)
+		if name == "" {
+			continue
+		}
+		if !hasOptionalTag(&m) {
+			required = append(required, name)
+		}
+		if err = g.generateProperty(&m, t); err != nil {
+			glog.Errorf("Error when generating: %v, %v\n", name, m)
+			return required, err
+		}
+	}
+	return required, nil
+}
+
+func (g openAPITypeWriter) generateCall(t *types.Type) error {
+	// Only generate for struct type and ignore the rest
+	switch t.Kind {
+	case types.Struct:
+		args := argsFromType(t)
+		g.Do("\"$.$\": ", t.Name)
+		if hasOpenAPIDefinitionMethod(t) {
+			g.Do("$.type|raw${}.OpenAPIDefinition(),\n", args)
+		} else {
+			g.Do(nameTmpl+"(ref),\n", args)
+		}
+	}
+	return g.Error()
+}
+
+func (g openAPITypeWriter) generate(t *types.Type) error {
+	// Only generate for struct type and ignore the rest
+	switch t.Kind {
+	case types.Struct:
+		if hasOpenAPIDefinitionMethod(t) {
+			// already invoked directly
+			return nil
+		}
+
+		args := argsFromType(t)
+		g.Do("func "+nameTmpl+"(ref $.ReferenceCallback|raw$) $.OpenAPIDefinition|raw$ {\n", args)
+		if hasOpenAPIDefinitionMethods(t) {
+			g.Do("return $.OpenAPIDefinition|raw${\n"+
+				"Schema: spec.Schema{\n"+
+				"SchemaProps: spec.SchemaProps{\n", args)
+			g.generateDescription(t.CommentLines)
+			g.Do("Type:$.type|raw${}.OpenAPISchemaType(),\n"+
+				"Format:$.type|raw${}.OpenAPISchemaFormat(),\n"+
+				"},\n"+
+				"},\n"+
+				"}\n}\n\n", args)
+			return nil
+		}
+		g.Do("return $.OpenAPIDefinition|raw${\nSchema: spec.Schema{\nSchemaProps: spec.SchemaProps{\n", args)
+		g.generateDescription(t.CommentLines)
+		g.Do("Properties: map[string]$.SpecSchemaType|raw${\n", args)
+		required, err := g.generateMembers(t, []string{})
+		if err != nil {
+			return err
+		}
+		g.Do("},\n", nil)
+		if len(required) > 0 {
+			g.Do("Required: []string{\"$.$\"},\n", strings.Join(required, "\",\""))
+		}
+		g.Do("},\n", nil)
+		if err := g.generateStructExtensions(t); err != nil {
+			return err
+		}
+		g.Do("},\n", nil)
+		g.Do("Dependencies: []string{\n", args)
+		// Map order is undefined, sort them or we may get a different file generated each time.
+		keys := []string{}
+		for k := range g.refTypes {
+			keys = append(keys, k)
+		}
+		sort.Strings(keys)
+		for _, k := range keys {
+			v := g.refTypes[k]
+			if t, _ := openapi.GetOpenAPITypeFormat(v.String()); t != "" {
+				// This is a known type, we do not need a reference to it
+				// Will eliminate special case of time.Time
+				continue
+			}
+			g.Do("\"$.$\",", k)
+		}
+		g.Do("},\n}\n}\n\n", nil)
+	}
+	return nil
+}
+
+func (g openAPITypeWriter) generateStructExtensions(t *types.Type) error {
+	extensions, errors := parseExtensions(t.CommentLines)
+	// Initially, we will only log struct extension errors.
+	if len(errors) > 0 {
+		for _, e := range errors {
+			glog.V(2).Infof("[%s]: %s\n", t.String(), e)
+		}
+	}
+	// TODO(seans3): Validate struct extensions here.
+	g.emitExtensions(extensions)
+	return nil
+}
+
+func (g openAPITypeWriter) generateMemberExtensions(m *types.Member, parent *types.Type) error {
+	extensions, parseErrors := parseExtensions(m.CommentLines)
+	validationErrors := validateMemberExtensions(extensions, m)
+	errors := append(parseErrors, validationErrors...)
+	// Initially, we will only log member extension errors.
+	if len(errors) > 0 {
+		errorPrefix := fmt.Sprintf("[%s] %s:", parent.String(), m.String())
+		for _, e := range errors {
+			glog.V(2).Infof("%s %s\n", errorPrefix, e)
+		}
+	}
+	g.emitExtensions(extensions)
+	return nil
+}
+
+func (g openAPITypeWriter) emitExtensions(extensions []extension) {
+	// If any extensions exist, then emit code to create them.
+	if len(extensions) == 0 {
+		return
+	}
+	g.Do("VendorExtensible: spec.VendorExtensible{\nExtensions: spec.Extensions{\n", nil)
+	for _, extension := range extensions {
+		g.Do("\"$.$\": ", extension.xName)
+		if extension.hasMultipleValues() {
+			g.Do("[]string{\n", nil)
+		}
+		for _, value := range extension.values {
+			g.Do("\"$.$\",\n", value)
+		}
+		if extension.hasMultipleValues() {
+			g.Do("},\n", nil)
+		}
+	}
+	g.Do("},\n},\n", nil)
+}
+
+// TODO(#44005): Move this validation outside of this generator (probably to policy verifier)
+func (g openAPITypeWriter) validatePatchTags(m *types.Member, parent *types.Type) error {
+	// TODO: Remove patch struct tag validation because they we are now consuming OpenAPI on server.
+	for _, tagKey := range tempPatchTags {
+		structTagValue := reflect.StructTag(m.Tags).Get(tagKey)
+		commentTagValue, err := getSingleTagsValue(m.CommentLines, tagKey)
+		if err != nil {
+			return err
+		}
+		if structTagValue != commentTagValue {
+			return fmt.Errorf("Tags in comment and struct should match for member (%s) of (%s)",
+				m.Name, parent.Name.String())
+		}
+	}
+	return nil
+}
+
+func (g openAPITypeWriter) generateDescription(CommentLines []string) {
+	var buffer bytes.Buffer
+	delPrevChar := func() {
+		if buffer.Len() > 0 {
+			buffer.Truncate(buffer.Len() - 1) // Delete the last " " or "\n"
+		}
+	}
+
+	for _, line := range CommentLines {
+		// Ignore all lines after ---
+		if line == "---" {
+			break
+		}
+		line = strings.TrimRight(line, " ")
+		leading := strings.TrimLeft(line, " ")
+		switch {
+		case len(line) == 0: // Keep paragraphs
+			delPrevChar()
+			buffer.WriteString("\n\n")
+		case strings.HasPrefix(leading, "TODO"): // Ignore one line TODOs
+		case strings.HasPrefix(leading, "+"): // Ignore instructions to go2idl
+		default:
+			if strings.HasPrefix(line, " ") || strings.HasPrefix(line, "\t") {
+				delPrevChar()
+				line = "\n" + line + "\n" // Replace it with newline. This is useful when we have a line with: "Example:\n\tJSON-someting..."
+			} else {
+				line += " "
+			}
+			buffer.WriteString(line)
+		}
+	}
+
+	postDoc := strings.TrimRight(buffer.String(), "\n")
+	postDoc = strings.Replace(postDoc, "\\\"", "\"", -1) // replace user's \" to "
+	postDoc = strings.Replace(postDoc, "\"", "\\\"", -1) // Escape "
+	postDoc = strings.Replace(postDoc, "\n", "\\n", -1)
+	postDoc = strings.Replace(postDoc, "\t", "\\t", -1)
+	postDoc = strings.Trim(postDoc, " ")
+	if postDoc != "" {
+		g.Do("Description: \"$.$\",\n", postDoc)
+	}
+}
+
+func (g openAPITypeWriter) generateProperty(m *types.Member, parent *types.Type) error {
+	name := getReferableName(m)
+	if name == "" {
+		return nil
+	}
+	if err := g.validatePatchTags(m, parent); err != nil {
+		return err
+	}
+	g.Do("\"$.$\": {\n", name)
+	if err := g.generateMemberExtensions(m, parent); err != nil {
+		return err
+	}
+	g.Do("SchemaProps: spec.SchemaProps{\n", nil)
+	g.generateDescription(m.CommentLines)
+	jsonTags := getJsonTags(m)
+	if len(jsonTags) > 1 && jsonTags[1] == "string" {
+		g.generateSimpleProperty("string", "")
+		g.Do("},\n},\n", nil)
+		return nil
+	}
+	t := resolveAliasAndPtrType(m.Type)
+	// If we can get a openAPI type and format for this type, we consider it to be simple property
+	typeString, format := openapi.GetOpenAPITypeFormat(t.String())
+	if typeString != "" {
+		g.generateSimpleProperty(typeString, format)
+		g.Do("},\n},\n", nil)
+		return nil
+	}
+	switch t.Kind {
+	case types.Builtin:
+		return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", t)
+	case types.Map:
+		if err := g.generateMapProperty(t); err != nil {
+			return err
+		}
+	case types.Slice, types.Array:
+		if err := g.generateSliceProperty(t); err != nil {
+			return err
+		}
+	case types.Struct, types.Interface:
+		g.generateReferenceProperty(t)
+	default:
+		return fmt.Errorf("cannot generate spec for type %v", t)
+	}
+	g.Do("},\n},\n", nil)
+	return g.Error()
+}
+
+func (g openAPITypeWriter) generateSimpleProperty(typeString, format string) {
+	g.Do("Type: []string{\"$.$\"},\n", typeString)
+	g.Do("Format: \"$.$\",\n", format)
+}
+
+func (g openAPITypeWriter) generateReferenceProperty(t *types.Type) {
+	g.refTypes[t.Name.String()] = t
+	g.Do("Ref: ref(\"$.$\"),\n", t.Name.String())
+}
+
+func resolveAliasAndPtrType(t *types.Type) *types.Type {
+	var prev *types.Type
+	for prev != t {
+		prev = t
+		if t.Kind == types.Alias {
+			t = t.Underlying
+		}
+		if t.Kind == types.Pointer {
+			t = t.Elem
+		}
+	}
+	return t
+}
+
+func (g openAPITypeWriter) generateMapProperty(t *types.Type) error {
+	keyType := resolveAliasAndPtrType(t.Key)
+	elemType := resolveAliasAndPtrType(t.Elem)
+
+	// According to OpenAPI examples, only map from string is supported
+	if keyType.Name.Name != "string" {
+		return fmt.Errorf("map with non-string keys are not supported by OpenAPI in %v", t)
+	}
+	g.Do("Type: []string{\"object\"},\n", nil)
+	g.Do("AdditionalProperties: &spec.SchemaOrBool{\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil)
+	typeString, format := openapi.GetOpenAPITypeFormat(elemType.String())
+	if typeString != "" {
+		g.generateSimpleProperty(typeString, format)
+		g.Do("},\n},\n},\n", nil)
+		return nil
+	}
+	switch elemType.Kind {
+	case types.Builtin:
+		return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", elemType)
+	case types.Struct:
+		g.generateReferenceProperty(elemType)
+	case types.Slice, types.Array:
+		g.generateSliceProperty(elemType)
+	default:
+		return fmt.Errorf("map Element kind %v is not supported in %v", elemType.Kind, t.Name)
+	}
+	g.Do("},\n},\n},\n", nil)
+	return nil
+}
+
+func (g openAPITypeWriter) generateSliceProperty(t *types.Type) error {
+	elemType := resolveAliasAndPtrType(t.Elem)
+	g.Do("Type: []string{\"array\"},\n", nil)
+	g.Do("Items: &spec.SchemaOrArray{\nSchema: &spec.Schema{\nSchemaProps: spec.SchemaProps{\n", nil)
+	typeString, format := openapi.GetOpenAPITypeFormat(elemType.String())
+	if typeString != "" {
+		g.generateSimpleProperty(typeString, format)
+		g.Do("},\n},\n},\n", nil)
+		return nil
+	}
+	switch elemType.Kind {
+	case types.Builtin:
+		return fmt.Errorf("please add type %v to getOpenAPITypeFormat function", elemType)
+	case types.Struct:
+		g.generateReferenceProperty(elemType)
+	case types.Slice, types.Array:
+		g.generateSliceProperty(elemType)
+	default:
+		return fmt.Errorf("slice Element kind %v is not supported in %v", elemType.Kind, t)
+	}
+	g.Do("},\n},\n},\n", nil)
+	return nil
+}
+
+// Finalize prints the API rule violations to report file (if specified from arguments) or stdout (default)
+func (g *openAPIGen) Finalize(c *generator.Context, w io.Writer) error {
+	// If report file isn't specified, return error to force user to choose either stdout ("-") or a file name
+	if len(g.reportFilename) == 0 {
+		return fmt.Errorf("empty report file name: please provide a valid file name or use the default \"-\" (stdout)")
+	}
+	// If stdout is specified, print violations and return error
+	if g.reportFilename == "-" {
+		return g.linter.report(os.Stdout)
+	}
+	// Otherwise, print violations to report file and return nil
+	f, err := os.Create(g.reportFilename)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	g.linter.report(f)
+	// NOTE: we don't return error here because we assume that the report file will
+	// get evaluated afterwards to determine if error should be raised. For example,
+	// you can have make rules that compare the report file with existing known
+	// violations (whitelist) and determine no error if no change is detected.
+	return nil
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/rules/doc.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/rules/doc.go
new file mode 100644
index 0000000..384a44d
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/rules/doc.go
@@ -0,0 +1,23 @@
+/*
+Copyright 2018 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 rules contains API rules that are enforced in OpenAPI spec generation
+// as part of the machinery. Files under this package implement APIRule interface
+// which evaluates Go type and produces list of API rule violations.
+//
+// Implementations of APIRule should be added to API linter under openAPIGen code-
+// generator to get integrated in the generation process.
+package rules
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/rules/names_match.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/rules/names_match.go
new file mode 100644
index 0000000..edd3b5e
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/generators/rules/names_match.go
@@ -0,0 +1,171 @@
+/*
+Copyright 2018 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 rules
+
+import (
+	"reflect"
+	"strings"
+
+	"k8s.io/apimachinery/pkg/util/sets"
+	"k8s.io/gengo/types"
+)
+
+var (
+	// Blacklist of JSON tags that should skip match evaluation
+	jsonTagBlacklist = sets.NewString(
+		// Omitted field is ignored by the package
+		"-",
+	)
+
+	// Blacklist of JSON names that should skip match evaluation
+	jsonNameBlacklist = sets.NewString(
+		// Empty name is used for inline struct field (e.g. metav1.TypeMeta)
+		"",
+		// Special case for object and list meta
+		"metadata",
+	)
+
+	// List of substrings that aren't allowed in Go name and JSON name
+	disallowedNameSubstrings = sets.NewString(
+		// Underscore is not allowed in either name
+		"_",
+		// Dash is not allowed in either name. Note that since dash is a valid JSON tag, this should be checked
+		// after JSON tag blacklist check.
+		"-",
+	)
+)
+
+/*
+NamesMatch implements APIRule interface.
+Go field names must be CamelCase. JSON field names must be camelCase. Other than capitalization of the
+initial letter, the two should almost always match. No underscores nor dashes in either.
+This rule verifies the convention "Other than capitalization of the initial letter, the two should almost always match."
+Examples (also in unit test):
+    Go name      | JSON name    | match
+                   podSpec        false
+    PodSpec        podSpec        true
+    PodSpec        PodSpec        false
+    podSpec        podSpec        false
+    PodSpec        spec           false
+    Spec           podSpec        false
+    JSONSpec       jsonSpec       true
+    JSONSpec       jsonspec       false
+    HTTPJSONSpec   httpJSONSpec   true
+NOTE: this validator cannot tell two sequential all-capital words from one word, therefore the case below
+is also considered matched.
+    HTTPJSONSpec   httpjsonSpec   true
+NOTE: JSON names in jsonNameBlacklist should skip evaluation
+                                  true
+    podSpec                       true
+    podSpec        -              true
+    podSpec        metadata       true
+*/
+type NamesMatch struct{}
+
+// Name returns the name of APIRule
+func (n *NamesMatch) Name() string {
+	return "names_match"
+}
+
+// Validate evaluates API rule on type t and returns a list of field names in
+// the type that violate the rule. Empty field name [""] implies the entire
+// type violates the rule.
+func (n *NamesMatch) Validate(t *types.Type) ([]string, error) {
+	fields := make([]string, 0)
+
+	// Only validate struct type and ignore the rest
+	switch t.Kind {
+	case types.Struct:
+		for _, m := range t.Members {
+			goName := m.Name
+			jsonTag, ok := reflect.StructTag(m.Tags).Lookup("json")
+			// Distinguish empty JSON tag and missing JSON tag. Empty JSON tag / name is
+			// allowed (in JSON name blacklist) but missing JSON tag is invalid.
+			if !ok {
+				fields = append(fields, goName)
+				continue
+			}
+			if jsonTagBlacklist.Has(jsonTag) {
+				continue
+			}
+			jsonName := strings.Split(jsonTag, ",")[0]
+			if !namesMatch(goName, jsonName) {
+				fields = append(fields, goName)
+			}
+		}
+	}
+	return fields, nil
+}
+
+// namesMatch evaluates if goName and jsonName match the API rule
+// TODO: Use an off-the-shelf CamelCase solution instead of implementing this logic. The following existing
+//       packages have been tried out:
+//		github.com/markbates/inflect
+//		github.com/segmentio/go-camelcase
+//		github.com/iancoleman/strcase
+//		github.com/fatih/camelcase
+//	 Please see https://github.com/kubernetes/kube-openapi/pull/83#issuecomment-400842314 for more details
+//	 about why they don't satisfy our need. What we need can be a function that detects an acronym at the
+//	 beginning of a string.
+func namesMatch(goName, jsonName string) bool {
+	if jsonNameBlacklist.Has(jsonName) {
+		return true
+	}
+	if !isAllowedName(goName) || !isAllowedName(jsonName) {
+		return false
+	}
+	if strings.ToLower(goName) != strings.ToLower(jsonName) {
+		return false
+	}
+	// Go field names must be CamelCase. JSON field names must be camelCase.
+	if !isCapital(goName[0]) || isCapital(jsonName[0]) {
+		return false
+	}
+	for i := 0; i < len(goName); i++ {
+		if goName[i] == jsonName[i] {
+			// goName[0:i-1] is uppercase and jsonName[0:i-1] is lowercase, goName[i:]
+			// and jsonName[i:] should match;
+			// goName[i] should be lowercase if i is equal to 1, e.g.:
+			//	goName   | jsonName
+			//	PodSpec     podSpec
+			// or uppercase if i is greater than 1, e.g.:
+			//      goname   | jsonName
+			//      JSONSpec   jsonSpec
+			// This is to rule out cases like:
+			//      goname   | jsonName
+			//      JSONSpec   jsonspec
+			return goName[i:] == jsonName[i:] && (i == 1 || isCapital(goName[i]))
+		}
+	}
+	return true
+}
+
+// isCaptical returns true if one character is capital
+func isCapital(b byte) bool {
+	return b >= 'A' && b <= 'Z'
+}
+
+// isAllowedName checks the list of disallowedNameSubstrings and returns true if name doesn't contain
+// any disallowed substring.
+func isAllowedName(name string) bool {
+	for _, substr := range disallowedNameSubstrings.UnsortedList() {
+		if strings.Contains(name, substr) {
+			return false
+		}
+	}
+	return true
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/handler/handler.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/handler/handler.go
new file mode 100644
index 0000000..c4bbc0b
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/handler/handler.go
@@ -0,0 +1,272 @@
+/*
+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 handler
+
+import (
+	"bytes"
+	"compress/gzip"
+	"crypto/sha512"
+	"encoding/json"
+	"fmt"
+	"mime"
+	"net/http"
+	"strings"
+	"sync"
+	"time"
+
+	"bitbucket.org/ww/goautoneg"
+
+	yaml "gopkg.in/yaml.v2"
+
+	"github.com/NYTimes/gziphandler"
+	restful "github.com/emicklei/go-restful"
+	"github.com/go-openapi/spec"
+	"github.com/golang/protobuf/proto"
+	openapi_v2 "github.com/googleapis/gnostic/OpenAPIv2"
+	"github.com/googleapis/gnostic/compiler"
+
+	"k8s.io/kube-openapi/pkg/builder"
+	"k8s.io/kube-openapi/pkg/common"
+)
+
+const (
+	jsonExt = ".json"
+
+	mimeJson = "application/json"
+	// TODO(mehdy): change @68f4ded to a version tag when gnostic add version tags.
+	mimePb   = "application/com.github.googleapis.gnostic.OpenAPIv2@68f4ded+protobuf"
+	mimePbGz = "application/x-gzip"
+)
+
+// OpenAPIService is the service responsible for serving OpenAPI spec. It has
+// the ability to safely change the spec while serving it.
+type OpenAPIService struct {
+	// rwMutex protects All members of this service.
+	rwMutex sync.RWMutex
+
+	lastModified time.Time
+
+	specBytes []byte
+	specPb    []byte
+	specPbGz  []byte
+
+	specBytesETag string
+	specPbETag    string
+	specPbGzETag  string
+}
+
+func init() {
+	mime.AddExtensionType(".json", mimeJson)
+	mime.AddExtensionType(".pb-v1", mimePb)
+	mime.AddExtensionType(".gz", mimePbGz)
+}
+
+func computeETag(data []byte) string {
+	return fmt.Sprintf("\"%X\"", sha512.Sum512(data))
+}
+
+// NOTE: [DEPRECATION] We will announce deprecation for format-separated endpoints for OpenAPI spec,
+// and switch to a single /openapi/v2 endpoint in Kubernetes 1.10. The design doc and deprecation process
+// are tracked at: https://docs.google.com/document/d/19lEqE9lc4yHJ3WJAJxS_G7TcORIJXGHyq3wpwcH28nU.
+//
+// BuildAndRegisterOpenAPIService builds the spec and registers a handler to provide access to it.
+// Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then RegisterOpenAPIService.
+func BuildAndRegisterOpenAPIService(servePath string, webServices []*restful.WebService, config *common.Config, handler common.PathHandler) (*OpenAPIService, error) {
+	spec, err := builder.BuildOpenAPISpec(webServices, config)
+	if err != nil {
+		return nil, err
+	}
+	return RegisterOpenAPIService(spec, servePath, handler)
+}
+
+// NOTE: [DEPRECATION] We will announce deprecation for format-separated endpoints for OpenAPI spec,
+// and switch to a single /openapi/v2 endpoint in Kubernetes 1.10. The design doc and deprecation process
+// are tracked at: https://docs.google.com/document/d/19lEqE9lc4yHJ3WJAJxS_G7TcORIJXGHyq3wpwcH28nU.
+//
+// RegisterOpenAPIService registers a handler to provide access to provided swagger spec.
+// Note: servePath should end with ".json" as the RegisterOpenAPIService assume it is serving a
+// json file and will also serve .pb and .gz files.
+func RegisterOpenAPIService(openapiSpec *spec.Swagger, servePath string, handler common.PathHandler) (*OpenAPIService, error) {
+	if !strings.HasSuffix(servePath, jsonExt) {
+		return nil, fmt.Errorf("serving path must end with \"%s\"", jsonExt)
+	}
+
+	servePathBase := strings.TrimSuffix(servePath, jsonExt)
+
+	o := OpenAPIService{}
+	if err := o.UpdateSpec(openapiSpec); err != nil {
+		return nil, err
+	}
+
+	type fileInfo struct {
+		ext            string
+		getDataAndETag func() ([]byte, string, time.Time)
+	}
+
+	files := []fileInfo{
+		{".json", o.getSwaggerBytes},
+		{"-2.0.0.json", o.getSwaggerBytes},
+		{"-2.0.0.pb-v1", o.getSwaggerPbBytes},
+		{"-2.0.0.pb-v1.gz", o.getSwaggerPbGzBytes},
+	}
+
+	for _, file := range files {
+		path := servePathBase + file.ext
+		getDataAndETag := file.getDataAndETag
+		handler.Handle(path, gziphandler.GzipHandler(http.HandlerFunc(
+			func(w http.ResponseWriter, r *http.Request) {
+				data, etag, lastModified := getDataAndETag()
+				w.Header().Set("Etag", etag)
+
+				// ServeContent will take care of caching using eTag.
+				http.ServeContent(w, r, path, lastModified, bytes.NewReader(data))
+			}),
+		))
+	}
+
+	return &o, nil
+}
+
+func (o *OpenAPIService) getSwaggerBytes() ([]byte, string, time.Time) {
+	o.rwMutex.RLock()
+	defer o.rwMutex.RUnlock()
+	return o.specBytes, o.specBytesETag, o.lastModified
+}
+
+func (o *OpenAPIService) getSwaggerPbBytes() ([]byte, string, time.Time) {
+	o.rwMutex.RLock()
+	defer o.rwMutex.RUnlock()
+	return o.specPb, o.specPbETag, o.lastModified
+}
+
+func (o *OpenAPIService) getSwaggerPbGzBytes() ([]byte, string, time.Time) {
+	o.rwMutex.RLock()
+	defer o.rwMutex.RUnlock()
+	return o.specPbGz, o.specPbGzETag, o.lastModified
+}
+
+func (o *OpenAPIService) UpdateSpec(openapiSpec *spec.Swagger) (err error) {
+	specBytes, err := json.MarshalIndent(openapiSpec, " ", " ")
+	if err != nil {
+		return err
+	}
+	specPb, err := toProtoBinary(specBytes)
+	if err != nil {
+		return err
+	}
+	specPbGz := toGzip(specPb)
+
+	specBytesETag := computeETag(specBytes)
+	specPbETag := computeETag(specPb)
+	specPbGzETag := computeETag(specPbGz)
+
+	lastModified := time.Now()
+
+	o.rwMutex.Lock()
+	defer o.rwMutex.Unlock()
+
+	o.specBytes = specBytes
+	o.specPb = specPb
+	o.specPbGz = specPbGz
+	o.specBytesETag = specBytesETag
+	o.specPbETag = specPbETag
+	o.specPbGzETag = specPbGzETag
+	o.lastModified = lastModified
+
+	return nil
+}
+
+func toProtoBinary(spec []byte) ([]byte, error) {
+	var info yaml.MapSlice
+	err := yaml.Unmarshal(spec, &info)
+	if err != nil {
+		return nil, err
+	}
+	document, err := openapi_v2.NewDocument(info, compiler.NewContext("$root", nil))
+	if err != nil {
+		return nil, err
+	}
+	return proto.Marshal(document)
+}
+
+func toGzip(data []byte) []byte {
+	var buf bytes.Buffer
+	zw := gzip.NewWriter(&buf)
+	zw.Write(data)
+	zw.Close()
+	return buf.Bytes()
+}
+
+// RegisterOpenAPIVersionedService registers a handler to provide access to provided swagger spec.
+func RegisterOpenAPIVersionedService(openapiSpec *spec.Swagger, servePath string, handler common.PathHandler) (*OpenAPIService, error) {
+	o := OpenAPIService{}
+	if err := o.UpdateSpec(openapiSpec); err != nil {
+		return nil, err
+	}
+
+	accepted := []struct {
+		Type           string
+		SubType        string
+		GetDataAndETag func() ([]byte, string, time.Time)
+	}{
+		{"application", "json", o.getSwaggerBytes},
+		{"application", "com.github.proto-openapi.spec.v2@v1.0+protobuf", o.getSwaggerPbBytes},
+	}
+
+	handler.Handle(servePath, gziphandler.GzipHandler(http.HandlerFunc(
+		func(w http.ResponseWriter, r *http.Request) {
+			decipherableFormats := r.Header.Get("Accept")
+			if decipherableFormats == "" {
+				decipherableFormats = "*/*"
+			}
+			clauses := goautoneg.ParseAccept(decipherableFormats)
+			w.Header().Add("Vary", "Accept")
+			for _, clause := range clauses {
+				for _, accepts := range accepted {
+					if clause.Type != accepts.Type && clause.Type != "*" {
+						continue
+					}
+					if clause.SubType != accepts.SubType && clause.SubType != "*" {
+						continue
+					}
+
+					// serve the first matching media type in the sorted clause list
+					data, etag, lastModified := accepts.GetDataAndETag()
+					w.Header().Set("Etag", etag)
+					// ServeContent will take care of caching using eTag.
+					http.ServeContent(w, r, servePath, lastModified, bytes.NewReader(data))
+					return
+				}
+			}
+			// Return 406 for not acceptable format
+			w.WriteHeader(406)
+			return
+		}),
+	))
+
+	return &o, nil
+}
+
+// BuildAndRegisterOpenAPIVersionedService builds the spec and registers a handler to provide access to it.
+// Use this method if your OpenAPI spec is static. If you want to update the spec, use BuildOpenAPISpec then RegisterOpenAPIVersionedService.
+func BuildAndRegisterOpenAPIVersionedService(servePath string, webServices []*restful.WebService, config *common.Config, handler common.PathHandler) (*OpenAPIService, error) {
+	spec, err := builder.BuildOpenAPISpec(webServices, config)
+	if err != nil {
+		return nil, err
+	}
+	return RegisterOpenAPIVersionedService(spec, servePath, handler)
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/proto/doc.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/proto/doc.go
new file mode 100644
index 0000000..11ed8a6
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/proto/doc.go
@@ -0,0 +1,19 @@
+/*
+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 proto is a collection of libraries for parsing and indexing the type definitions.
+// The openapi spec contains the object model definitions and extensions metadata.
+package proto
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/proto/document.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/proto/document.go
new file mode 100644
index 0000000..a57dcd3
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/proto/document.go
@@ -0,0 +1,299 @@
+/*
+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 proto
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+
+	"github.com/googleapis/gnostic/OpenAPIv2"
+	"gopkg.in/yaml.v2"
+)
+
+func newSchemaError(path *Path, format string, a ...interface{}) error {
+	err := fmt.Sprintf(format, a...)
+	if path.Len() == 0 {
+		return fmt.Errorf("SchemaError: %v", err)
+	}
+	return fmt.Errorf("SchemaError(%v): %v", path, err)
+}
+
+// VendorExtensionToMap converts openapi VendorExtension to a map.
+func VendorExtensionToMap(e []*openapi_v2.NamedAny) map[string]interface{} {
+	values := map[string]interface{}{}
+
+	for _, na := range e {
+		if na.GetName() == "" || na.GetValue() == nil {
+			continue
+		}
+		if na.GetValue().GetYaml() == "" {
+			continue
+		}
+		var value interface{}
+		err := yaml.Unmarshal([]byte(na.GetValue().GetYaml()), &value)
+		if err != nil {
+			continue
+		}
+
+		values[na.GetName()] = value
+	}
+
+	return values
+}
+
+// Definitions is an implementation of `Models`. It looks for
+// models in an openapi Schema.
+type Definitions struct {
+	models map[string]Schema
+}
+
+var _ Models = &Definitions{}
+
+// NewOpenAPIData creates a new `Models` out of the openapi document.
+func NewOpenAPIData(doc *openapi_v2.Document) (Models, error) {
+	definitions := Definitions{
+		models: map[string]Schema{},
+	}
+
+	// Save the list of all models first. This will allow us to
+	// validate that we don't have any dangling reference.
+	for _, namedSchema := range doc.GetDefinitions().GetAdditionalProperties() {
+		definitions.models[namedSchema.GetName()] = nil
+	}
+
+	// Now, parse each model. We can validate that references exists.
+	for _, namedSchema := range doc.GetDefinitions().GetAdditionalProperties() {
+		path := NewPath(namedSchema.GetName())
+		schema, err := definitions.ParseSchema(namedSchema.GetValue(), &path)
+		if err != nil {
+			return nil, err
+		}
+		definitions.models[namedSchema.GetName()] = schema
+	}
+
+	return &definitions, nil
+}
+
+// We believe the schema is a reference, verify that and returns a new
+// Schema
+func (d *Definitions) parseReference(s *openapi_v2.Schema, path *Path) (Schema, error) {
+	if len(s.GetProperties().GetAdditionalProperties()) > 0 {
+		return nil, newSchemaError(path, "unallowed embedded type definition")
+	}
+	if len(s.GetType().GetValue()) > 0 {
+		return nil, newSchemaError(path, "definition reference can't have a type")
+	}
+
+	if !strings.HasPrefix(s.GetXRef(), "#/definitions/") {
+		return nil, newSchemaError(path, "unallowed reference to non-definition %q", s.GetXRef())
+	}
+	reference := strings.TrimPrefix(s.GetXRef(), "#/definitions/")
+	if _, ok := d.models[reference]; !ok {
+		return nil, newSchemaError(path, "unknown model in reference: %q", reference)
+	}
+	return &Ref{
+		BaseSchema:  d.parseBaseSchema(s, path),
+		reference:   reference,
+		definitions: d,
+	}, nil
+}
+
+func (d *Definitions) parseBaseSchema(s *openapi_v2.Schema, path *Path) BaseSchema {
+	return BaseSchema{
+		Description: s.GetDescription(),
+		Extensions:  VendorExtensionToMap(s.GetVendorExtension()),
+		Path:        *path,
+	}
+}
+
+// We believe the schema is a map, verify and return a new schema
+func (d *Definitions) parseMap(s *openapi_v2.Schema, path *Path) (Schema, error) {
+	if len(s.GetType().GetValue()) != 0 && s.GetType().GetValue()[0] != object {
+		return nil, newSchemaError(path, "invalid object type")
+	}
+	var sub Schema
+	if s.GetAdditionalProperties().GetSchema() == nil {
+		sub = &Arbitrary{
+			BaseSchema: d.parseBaseSchema(s, path),
+		}
+	} else {
+		var err error
+		sub, err = d.ParseSchema(s.GetAdditionalProperties().GetSchema(), path)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return &Map{
+		BaseSchema: d.parseBaseSchema(s, path),
+		SubType:    sub,
+	}, nil
+}
+
+func (d *Definitions) parsePrimitive(s *openapi_v2.Schema, path *Path) (Schema, error) {
+	var t string
+	if len(s.GetType().GetValue()) > 1 {
+		return nil, newSchemaError(path, "primitive can't have more than 1 type")
+	}
+	if len(s.GetType().GetValue()) == 1 {
+		t = s.GetType().GetValue()[0]
+	}
+	switch t {
+	case String: // do nothing
+	case Number: // do nothing
+	case Integer: // do nothing
+	case Boolean: // do nothing
+	default:
+		return nil, newSchemaError(path, "Unknown primitive type: %q", t)
+	}
+	return &Primitive{
+		BaseSchema: d.parseBaseSchema(s, path),
+		Type:       t,
+		Format:     s.GetFormat(),
+	}, nil
+}
+
+func (d *Definitions) parseArray(s *openapi_v2.Schema, path *Path) (Schema, error) {
+	if len(s.GetType().GetValue()) != 1 {
+		return nil, newSchemaError(path, "array should have exactly one type")
+	}
+	if s.GetType().GetValue()[0] != array {
+		return nil, newSchemaError(path, `array should have type "array"`)
+	}
+	if len(s.GetItems().GetSchema()) != 1 {
+		return nil, newSchemaError(path, "array should have exactly one sub-item")
+	}
+	sub, err := d.ParseSchema(s.GetItems().GetSchema()[0], path)
+	if err != nil {
+		return nil, err
+	}
+	return &Array{
+		BaseSchema: d.parseBaseSchema(s, path),
+		SubType:    sub,
+	}, nil
+}
+
+func (d *Definitions) parseKind(s *openapi_v2.Schema, path *Path) (Schema, error) {
+	if len(s.GetType().GetValue()) != 0 && s.GetType().GetValue()[0] != object {
+		return nil, newSchemaError(path, "invalid object type")
+	}
+	if s.GetProperties() == nil {
+		return nil, newSchemaError(path, "object doesn't have properties")
+	}
+
+	fields := map[string]Schema{}
+
+	for _, namedSchema := range s.GetProperties().GetAdditionalProperties() {
+		var err error
+		path := path.FieldPath(namedSchema.GetName())
+		fields[namedSchema.GetName()], err = d.ParseSchema(namedSchema.GetValue(), &path)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	return &Kind{
+		BaseSchema:     d.parseBaseSchema(s, path),
+		RequiredFields: s.GetRequired(),
+		Fields:         fields,
+	}, nil
+}
+
+func (d *Definitions) parseArbitrary(s *openapi_v2.Schema, path *Path) (Schema, error) {
+	return &Arbitrary{
+		BaseSchema: d.parseBaseSchema(s, path),
+	}, nil
+}
+
+// ParseSchema creates a walkable Schema from an openapi schema. While
+// this function is public, it doesn't leak through the interface.
+func (d *Definitions) ParseSchema(s *openapi_v2.Schema, path *Path) (Schema, error) {
+	if s.GetXRef() != "" {
+		return d.parseReference(s, path)
+	}
+	objectTypes := s.GetType().GetValue()
+	switch len(objectTypes) {
+	case 0:
+		// in the OpenAPI schema served by older k8s versions, object definitions created from structs did not include
+		// the type:object property (they only included the "properties" property), so we need to handle this case
+		if s.GetProperties() != nil {
+			return d.parseKind(s, path)
+		} else {
+			// Definition has no type and no properties. Treat it as an arbitrary value
+			// TODO: what if it has additionalProperties or patternProperties?
+			return d.parseArbitrary(s, path)
+		}
+	case 1:
+		t := objectTypes[0]
+		switch t {
+		case object:
+			if s.GetProperties() != nil {
+				return d.parseKind(s, path)
+			} else {
+				return d.parseMap(s, path)
+			}
+		case array:
+			return d.parseArray(s, path)
+		}
+		return d.parsePrimitive(s, path)
+	default:
+		// the OpenAPI generator never generates (nor it ever did in the past) OpenAPI type definitions with multiple types
+		return nil, newSchemaError(path, "definitions with multiple types aren't supported")
+	}
+}
+
+// LookupModel is public through the interface of Models. It
+// returns a visitable schema from the given model name.
+func (d *Definitions) LookupModel(model string) Schema {
+	return d.models[model]
+}
+
+func (d *Definitions) ListModels() []string {
+	models := []string{}
+
+	for model := range d.models {
+		models = append(models, model)
+	}
+
+	sort.Strings(models)
+	return models
+}
+
+type Ref struct {
+	BaseSchema
+
+	reference   string
+	definitions *Definitions
+}
+
+var _ Reference = &Ref{}
+
+func (r *Ref) Reference() string {
+	return r.reference
+}
+
+func (r *Ref) SubSchema() Schema {
+	return r.definitions.models[r.reference]
+}
+
+func (r *Ref) Accept(v SchemaVisitor) {
+	v.VisitReference(r)
+}
+
+func (r *Ref) GetName() string {
+	return fmt.Sprintf("Reference to %q", r.reference)
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/proto/openapi.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/proto/openapi.go
new file mode 100644
index 0000000..f26b5ef
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/proto/openapi.go
@@ -0,0 +1,276 @@
+/*
+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 proto
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+// Defines openapi types.
+const (
+	Integer = "integer"
+	Number  = "number"
+	String  = "string"
+	Boolean = "boolean"
+
+	// These types are private as they should never leak, and are
+	// represented by actual structs.
+	array  = "array"
+	object = "object"
+)
+
+// Models interface describe a model provider. They can give you the
+// schema for a specific model.
+type Models interface {
+	LookupModel(string) Schema
+	ListModels() []string
+}
+
+// SchemaVisitor is an interface that you need to implement if you want
+// to "visit" an openapi schema. A dispatch on the Schema type will call
+// the appropriate function based on its actual type:
+// - Array is a list of one and only one given subtype
+// - Map is a map of string to one and only one given subtype
+// - Primitive can be string, integer, number and boolean.
+// - Kind is an object with specific fields mapping to specific types.
+// - Reference is a link to another definition.
+type SchemaVisitor interface {
+	VisitArray(*Array)
+	VisitMap(*Map)
+	VisitPrimitive(*Primitive)
+	VisitKind(*Kind)
+	VisitReference(Reference)
+}
+
+// SchemaVisitorArbitrary is an additional visitor interface which handles
+// arbitrary types. For backwards compatibility, it's a separate interface
+// which is checked for at runtime.
+type SchemaVisitorArbitrary interface {
+	SchemaVisitor
+	VisitArbitrary(*Arbitrary)
+}
+
+// Schema is the base definition of an openapi type.
+type Schema interface {
+	// Giving a visitor here will let you visit the actual type.
+	Accept(SchemaVisitor)
+
+	// Pretty print the name of the type.
+	GetName() string
+	// Describes how to access this field.
+	GetPath() *Path
+	// Describes the field.
+	GetDescription() string
+	// Returns type extensions.
+	GetExtensions() map[string]interface{}
+}
+
+// Path helps us keep track of type paths
+type Path struct {
+	parent *Path
+	key    string
+}
+
+func NewPath(key string) Path {
+	return Path{key: key}
+}
+
+func (p *Path) Get() []string {
+	if p == nil {
+		return []string{}
+	}
+	if p.key == "" {
+		return p.parent.Get()
+	}
+	return append(p.parent.Get(), p.key)
+}
+
+func (p *Path) Len() int {
+	return len(p.Get())
+}
+
+func (p *Path) String() string {
+	return strings.Join(p.Get(), "")
+}
+
+// ArrayPath appends an array index and creates a new path
+func (p *Path) ArrayPath(i int) Path {
+	return Path{
+		parent: p,
+		key:    fmt.Sprintf("[%d]", i),
+	}
+}
+
+// FieldPath appends a field name and creates a new path
+func (p *Path) FieldPath(field string) Path {
+	return Path{
+		parent: p,
+		key:    fmt.Sprintf(".%s", field),
+	}
+}
+
+// BaseSchema holds data used by each types of schema.
+type BaseSchema struct {
+	Description string
+	Extensions  map[string]interface{}
+
+	Path Path
+}
+
+func (b *BaseSchema) GetDescription() string {
+	return b.Description
+}
+
+func (b *BaseSchema) GetExtensions() map[string]interface{} {
+	return b.Extensions
+}
+
+func (b *BaseSchema) GetPath() *Path {
+	return &b.Path
+}
+
+// Array must have all its element of the same `SubType`.
+type Array struct {
+	BaseSchema
+
+	SubType Schema
+}
+
+var _ Schema = &Array{}
+
+func (a *Array) Accept(v SchemaVisitor) {
+	v.VisitArray(a)
+}
+
+func (a *Array) GetName() string {
+	return fmt.Sprintf("Array of %s", a.SubType.GetName())
+}
+
+// Kind is a complex object. It can have multiple different
+// subtypes for each field, as defined in the `Fields` field. Mandatory
+// fields are listed in `RequiredFields`. The key of the object is
+// always of type `string`.
+type Kind struct {
+	BaseSchema
+
+	// Lists names of required fields.
+	RequiredFields []string
+	// Maps field names to types.
+	Fields map[string]Schema
+}
+
+var _ Schema = &Kind{}
+
+func (k *Kind) Accept(v SchemaVisitor) {
+	v.VisitKind(k)
+}
+
+func (k *Kind) GetName() string {
+	properties := []string{}
+	for key := range k.Fields {
+		properties = append(properties, key)
+	}
+	return fmt.Sprintf("Kind(%v)", properties)
+}
+
+// IsRequired returns true if `field` is a required field for this type.
+func (k *Kind) IsRequired(field string) bool {
+	for _, f := range k.RequiredFields {
+		if f == field {
+			return true
+		}
+	}
+	return false
+}
+
+// Keys returns a alphabetically sorted list of keys.
+func (k *Kind) Keys() []string {
+	keys := make([]string, 0)
+	for key := range k.Fields {
+		keys = append(keys, key)
+	}
+	sort.Strings(keys)
+	return keys
+}
+
+// Map is an object who values must all be of the same `SubType`.
+// The key of the object is always of type `string`.
+type Map struct {
+	BaseSchema
+
+	SubType Schema
+}
+
+var _ Schema = &Map{}
+
+func (m *Map) Accept(v SchemaVisitor) {
+	v.VisitMap(m)
+}
+
+func (m *Map) GetName() string {
+	return fmt.Sprintf("Map of %s", m.SubType.GetName())
+}
+
+// Primitive is a literal. There can be multiple types of primitives,
+// and this subtype can be visited through the `subType` field.
+type Primitive struct {
+	BaseSchema
+
+	// Type of a primitive must be one of: integer, number, string, boolean.
+	Type   string
+	Format string
+}
+
+var _ Schema = &Primitive{}
+
+func (p *Primitive) Accept(v SchemaVisitor) {
+	v.VisitPrimitive(p)
+}
+
+func (p *Primitive) GetName() string {
+	if p.Format == "" {
+		return p.Type
+	}
+	return fmt.Sprintf("%s (%s)", p.Type, p.Format)
+}
+
+// Arbitrary is a value of any type (primitive, object or array)
+type Arbitrary struct {
+	BaseSchema
+}
+
+var _ Schema = &Arbitrary{}
+
+func (a *Arbitrary) Accept(v SchemaVisitor) {
+	if visitor, ok := v.(SchemaVisitorArbitrary); ok {
+		visitor.VisitArbitrary(a)
+	}
+}
+
+func (a *Arbitrary) GetName() string {
+	return "Arbitrary value (primitive, object or array)"
+}
+
+// Reference implementation depends on the type of document.
+type Reference interface {
+	Schema
+
+	Reference() string
+	SubSchema() Schema
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/trie.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/trie.go
new file mode 100644
index 0000000..a9a76c1
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/trie.go
@@ -0,0 +1,79 @@
+/*
+Copyright 2016 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 util
+
+// A simple trie implementation with Add and HasPrefix methods only.
+type Trie struct {
+	children map[byte]*Trie
+	wordTail bool
+	word     string
+}
+
+// NewTrie creates a Trie and add all strings in the provided list to it.
+func NewTrie(list []string) Trie {
+	ret := Trie{
+		children: make(map[byte]*Trie),
+		wordTail: false,
+	}
+	for _, v := range list {
+		ret.Add(v)
+	}
+	return ret
+}
+
+// Add adds a word to this trie
+func (t *Trie) Add(v string) {
+	root := t
+	for _, b := range []byte(v) {
+		child, exists := root.children[b]
+		if !exists {
+			child = &Trie{
+				children: make(map[byte]*Trie),
+				wordTail: false,
+			}
+			root.children[b] = child
+		}
+		root = child
+	}
+	root.wordTail = true
+	root.word = v
+}
+
+// HasPrefix returns true of v has any of the prefixes stored in this trie.
+func (t *Trie) HasPrefix(v string) bool {
+	_, has := t.GetPrefix(v)
+	return has
+}
+
+// GetPrefix is like HasPrefix but return the prefix in case of match or empty string otherwise.
+func (t *Trie) GetPrefix(v string) (string, bool) {
+	root := t
+	if root.wordTail {
+		return root.word, true
+	}
+	for _, b := range []byte(v) {
+		child, exists := root.children[b]
+		if !exists {
+			return "", false
+		}
+		if child.wordTail {
+			return child.word, true
+		}
+		root = child
+	}
+	return "", false
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/util.go b/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/util.go
new file mode 100644
index 0000000..bcc0c4d
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/pkg/util/util.go
@@ -0,0 +1,39 @@
+/*
+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 util
+
+import "strings"
+
+// ToCanonicalName converts Golang package/type name into canonical OpenAPI name.
+// Examples:
+//	Input:  k8s.io/api/core/v1.Pod
+//	Output: io.k8s.api.core.v1.Pod
+//
+//	Input:  k8s.io/api/core/v1
+//	Output: io.k8s.api.core.v1
+func ToCanonicalName(name string) string {
+	nameParts := strings.Split(name, "/")
+	// Reverse first part. e.g., io.k8s... instead of k8s.io...
+	if len(nameParts) > 0 && strings.Contains(nameParts[0], ".") {
+		parts := strings.Split(nameParts[0], ".")
+		for i, j := 0, len(parts)-1; i < j; i, j = i+1, j-1 {
+			parts[i], parts[j] = parts[j], parts[i]
+		}
+		nameParts[0] = strings.Join(parts, ".")
+	}
+	return strings.Join(nameParts, ".")
+}
