diff --git a/metrics-server/vendor/k8s.io/kube-openapi/LICENSE b/metrics-server/vendor/k8s.io/kube-openapi/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go b/metrics-server/vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go
new file mode 100644
index 0000000..f555bdd
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/cmd/openapi-gen/args/args.go
@@ -0,0 +1,73 @@
+/*
+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 args
+
+import (
+	"fmt"
+
+	"github.com/spf13/pflag"
+	"k8s.io/gengo/args"
+)
+
+// CustomArgs is used by the gengo framework to pass args specific to this generator.
+type CustomArgs struct {
+	// ReportFilename is added to CustomArgs for specifying name of report file used
+	// by API linter. If specified, API rule violations will be printed to report file.
+	// Otherwise default value "-" will be used which indicates stdout.
+	ReportFilename string
+}
+
+// NewDefaults returns default arguments for the generator. Returning the arguments instead
+// of using default flag parsing allows registering custom arguments afterwards
+func NewDefaults() (*args.GeneratorArgs, *CustomArgs) {
+	// Default() sets a couple of flag default values for example the boilerplate.
+	// WithoutDefaultFlagParsing() disables implicit addition of command line flags and parsing,
+	// which allows registering custom arguments afterwards
+	genericArgs := args.Default().WithoutDefaultFlagParsing()
+	customArgs := &CustomArgs{}
+	genericArgs.CustomArgs = customArgs
+
+	// Default value for report filename is "-", which stands for stdout
+	customArgs.ReportFilename = "-"
+	// Default value for output file base name
+	genericArgs.OutputFileBaseName = "openapi_generated"
+
+	return genericArgs, customArgs
+}
+
+// AddFlags add the generator flags to the flag set.
+func (c *CustomArgs) AddFlags(fs *pflag.FlagSet) {
+	fs.StringVarP(&c.ReportFilename, "report-filename", "r", c.ReportFilename, "Name of report file used by API linter to print API violations. Default \"-\" stands for standard output. NOTE that if valid filename other than \"-\" is specified, API linter won't return error on detected API violations. This allows further check of existing API violations without stopping the OpenAPI generation toolchain.")
+}
+
+// Validate checks the given arguments.
+func Validate(genericArgs *args.GeneratorArgs) error {
+	c, ok := genericArgs.CustomArgs.(*CustomArgs)
+	if !ok {
+		return fmt.Errorf("input arguments don't contain valid custom arguments")
+	}
+	if len(c.ReportFilename) == 0 {
+		return fmt.Errorf("report filename cannot be empty. specify a valid filename or use \"-\" for stdout")
+	}
+	if len(genericArgs.OutputFileBaseName) == 0 {
+		return fmt.Errorf("output file base name cannot be empty")
+	}
+	if len(genericArgs.OutputPackagePath) == 0 {
+		return fmt.Errorf("output package cannot be empty")
+	}
+	return nil
+}
diff --git a/metrics-server/vendor/k8s.io/kube-openapi/cmd/openapi-gen/openapi-gen.go b/metrics-server/vendor/k8s.io/kube-openapi/cmd/openapi-gen/openapi-gen.go
new file mode 100644
index 0000000..0f7563b
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/kube-openapi/cmd/openapi-gen/openapi-gen.go
@@ -0,0 +1,55 @@
+/*
+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.
+*/
+
+// This package generates openAPI definition file to be used in open API spec generation on API servers. 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 from a tagged package, add "+k8s:openapi-gen=false" tag to the type comment lines.
+
+package main
+
+import (
+	"flag"
+	"log"
+
+	generatorargs "k8s.io/kube-openapi/cmd/openapi-gen/args"
+	"k8s.io/kube-openapi/pkg/generators"
+
+	"github.com/spf13/pflag"
+)
+
+func main() {
+	genericArgs, customArgs := generatorargs.NewDefaults()
+
+	genericArgs.AddFlags(pflag.CommandLine)
+	customArgs.AddFlags(pflag.CommandLine)
+	flag.Set("logtostderr", "true")
+	pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
+	pflag.Parse()
+
+	if err := generatorargs.Validate(genericArgs); err != nil {
+		log.Fatalf("Arguments validation error: %v", err)
+	}
+
+	// Generates the code for the OpenAPIDefinitions.
+	if err := genericArgs.Execute(
+		generators.NameSystems(),
+		generators.DefaultNameSystem(),
+		generators.Packages,
+	); err != nil {
+		log.Fatalf("OpenAPI code generation error: %v", err)
+	}
+	log.Println("Code for OpenAPI definitions generated")
+}
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, ".")
+}
