diff --git a/metrics-server/vendor/k8s.io/client-go/discovery/cached_discovery.go b/metrics-server/vendor/k8s.io/client-go/discovery/cached_discovery.go
new file mode 100644
index 0000000..aca4654
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/client-go/discovery/cached_discovery.go
@@ -0,0 +1,282 @@
+/*
+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 discovery
+
+import (
+	"errors"
+	"io/ioutil"
+	"net/http"
+	"os"
+	"path/filepath"
+	"sync"
+	"time"
+
+	"github.com/golang/glog"
+	"github.com/googleapis/gnostic/OpenAPIv2"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/version"
+	"k8s.io/client-go/kubernetes/scheme"
+	restclient "k8s.io/client-go/rest"
+)
+
+// CachedDiscoveryClient implements the functions that discovery server-supported API groups,
+// versions and resources.
+type CachedDiscoveryClient struct {
+	delegate DiscoveryInterface
+
+	// cacheDirectory is the directory where discovery docs are held.  It must be unique per host:port combination to work well.
+	cacheDirectory string
+
+	// ttl is how long the cache should be considered valid
+	ttl time.Duration
+
+	// mutex protects the variables below
+	mutex sync.Mutex
+
+	// ourFiles are all filenames of cache files created by this process
+	ourFiles map[string]struct{}
+	// invalidated is true if all cache files should be ignored that are not ours (e.g. after Invalidate() was called)
+	invalidated bool
+	// fresh is true if all used cache files were ours
+	fresh bool
+}
+
+var _ CachedDiscoveryInterface = &CachedDiscoveryClient{}
+
+// ServerResourcesForGroupVersion returns the supported resources for a group and version.
+func (d *CachedDiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
+	filename := filepath.Join(d.cacheDirectory, groupVersion, "serverresources.json")
+	cachedBytes, err := d.getCachedFile(filename)
+	// don't fail on errors, we either don't have a file or won't be able to run the cached check. Either way we can fallback.
+	if err == nil {
+		cachedResources := &metav1.APIResourceList{}
+		if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), cachedBytes, cachedResources); err == nil {
+			glog.V(10).Infof("returning cached discovery info from %v", filename)
+			return cachedResources, nil
+		}
+	}
+
+	liveResources, err := d.delegate.ServerResourcesForGroupVersion(groupVersion)
+	if err != nil {
+		glog.V(3).Infof("skipped caching discovery info due to %v", err)
+		return liveResources, err
+	}
+	if liveResources == nil || len(liveResources.APIResources) == 0 {
+		glog.V(3).Infof("skipped caching discovery info, no resources found")
+		return liveResources, err
+	}
+
+	if err := d.writeCachedFile(filename, liveResources); err != nil {
+		glog.V(3).Infof("failed to write cache to %v due to %v", filename, err)
+	}
+
+	return liveResources, nil
+}
+
+// ServerResources returns the supported resources for all groups and versions.
+func (d *CachedDiscoveryClient) ServerResources() ([]*metav1.APIResourceList, error) {
+	return ServerResources(d)
+}
+
+func (d *CachedDiscoveryClient) ServerGroups() (*metav1.APIGroupList, error) {
+	filename := filepath.Join(d.cacheDirectory, "servergroups.json")
+	cachedBytes, err := d.getCachedFile(filename)
+	// don't fail on errors, we either don't have a file or won't be able to run the cached check. Either way we can fallback.
+	if err == nil {
+		cachedGroups := &metav1.APIGroupList{}
+		if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), cachedBytes, cachedGroups); err == nil {
+			glog.V(10).Infof("returning cached discovery info from %v", filename)
+			return cachedGroups, nil
+		}
+	}
+
+	liveGroups, err := d.delegate.ServerGroups()
+	if err != nil {
+		glog.V(3).Infof("skipped caching discovery info due to %v", err)
+		return liveGroups, err
+	}
+	if liveGroups == nil || len(liveGroups.Groups) == 0 {
+		glog.V(3).Infof("skipped caching discovery info, no groups found")
+		return liveGroups, err
+	}
+
+	if err := d.writeCachedFile(filename, liveGroups); err != nil {
+		glog.V(3).Infof("failed to write cache to %v due to %v", filename, err)
+	}
+
+	return liveGroups, nil
+}
+
+func (d *CachedDiscoveryClient) getCachedFile(filename string) ([]byte, error) {
+	// after invalidation ignore cache files not created by this process
+	d.mutex.Lock()
+	_, ourFile := d.ourFiles[filename]
+	if d.invalidated && !ourFile {
+		d.mutex.Unlock()
+		return nil, errors.New("cache invalidated")
+	}
+	d.mutex.Unlock()
+
+	file, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer file.Close()
+
+	fileInfo, err := file.Stat()
+	if err != nil {
+		return nil, err
+	}
+
+	if time.Now().After(fileInfo.ModTime().Add(d.ttl)) {
+		return nil, errors.New("cache expired")
+	}
+
+	// the cache is present and its valid.  Try to read and use it.
+	cachedBytes, err := ioutil.ReadAll(file)
+	if err != nil {
+		return nil, err
+	}
+
+	d.mutex.Lock()
+	defer d.mutex.Unlock()
+	d.fresh = d.fresh && ourFile
+
+	return cachedBytes, nil
+}
+
+func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Object) error {
+	if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
+		return err
+	}
+
+	bytes, err := runtime.Encode(scheme.Codecs.LegacyCodec(), obj)
+	if err != nil {
+		return err
+	}
+
+	f, err := ioutil.TempFile(filepath.Dir(filename), filepath.Base(filename)+".")
+	if err != nil {
+		return err
+	}
+	defer os.Remove(f.Name())
+	_, err = f.Write(bytes)
+	if err != nil {
+		return err
+	}
+
+	err = os.Chmod(f.Name(), 0755)
+	if err != nil {
+		return err
+	}
+
+	name := f.Name()
+	err = f.Close()
+	if err != nil {
+		return err
+	}
+
+	// atomic rename
+	d.mutex.Lock()
+	defer d.mutex.Unlock()
+	err = os.Rename(name, filename)
+	if err == nil {
+		d.ourFiles[filename] = struct{}{}
+	}
+	return err
+}
+
+func (d *CachedDiscoveryClient) RESTClient() restclient.Interface {
+	return d.delegate.RESTClient()
+}
+
+func (d *CachedDiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
+	return ServerPreferredResources(d)
+}
+
+func (d *CachedDiscoveryClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
+	return ServerPreferredNamespacedResources(d)
+}
+
+func (d *CachedDiscoveryClient) ServerVersion() (*version.Info, error) {
+	return d.delegate.ServerVersion()
+}
+
+func (d *CachedDiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) {
+	return d.delegate.OpenAPISchema()
+}
+
+func (d *CachedDiscoveryClient) Fresh() bool {
+	d.mutex.Lock()
+	defer d.mutex.Unlock()
+
+	return d.fresh
+}
+
+func (d *CachedDiscoveryClient) Invalidate() {
+	d.mutex.Lock()
+	defer d.mutex.Unlock()
+
+	d.ourFiles = map[string]struct{}{}
+	d.fresh = true
+	d.invalidated = true
+}
+
+// NewCachedDiscoveryClientForConfig creates a new DiscoveryClient for the given config, and wraps
+// the created client in a CachedDiscoveryClient. The provided configuration is updated with a
+// custom transport that understands cache responses.
+// We receive two distinct cache directories for now, in order to preserve old behavior
+// which makes use of the --cache-dir flag value for storing cache data from the CacheRoundTripper,
+// and makes use of the hardcoded destination (~/.kube/cache/discovery/...) for storing
+// CachedDiscoveryClient cache data. If httpCacheDir is empty, the restconfig's transport will not
+// be updated with a roundtripper that understands cache responses.
+// If discoveryCacheDir is empty, cached server resource data will be looked up in the current directory.
+// TODO(juanvallejo): the value of "--cache-dir" should be honored. Consolidate discoveryCacheDir with httpCacheDir
+// so that server resources and http-cache data are stored in the same location, provided via config flags.
+func NewCachedDiscoveryClientForConfig(config *restclient.Config, discoveryCacheDir, httpCacheDir string, ttl time.Duration) (*CachedDiscoveryClient, error) {
+	if len(httpCacheDir) > 0 {
+		// update the given restconfig with a custom roundtripper that
+		// understands how to handle cache responses.
+		wt := config.WrapTransport
+		config.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
+			if wt != nil {
+				rt = wt(rt)
+			}
+			return newCacheRoundTripper(httpCacheDir, rt)
+		}
+	}
+
+	discoveryClient, err := NewDiscoveryClientForConfig(config)
+	if err != nil {
+		return nil, err
+	}
+
+	return newCachedDiscoveryClient(discoveryClient, discoveryCacheDir, ttl), nil
+}
+
+// NewCachedDiscoveryClient creates a new DiscoveryClient.  cacheDirectory is the directory where discovery docs are held.  It must be unique per host:port combination to work well.
+func newCachedDiscoveryClient(delegate DiscoveryInterface, cacheDirectory string, ttl time.Duration) *CachedDiscoveryClient {
+	return &CachedDiscoveryClient{
+		delegate:       delegate,
+		cacheDirectory: cacheDirectory,
+		ttl:            ttl,
+		ourFiles:       map[string]struct{}{},
+		fresh:          true,
+	}
+}
diff --git a/metrics-server/vendor/k8s.io/client-go/discovery/discovery_client.go b/metrics-server/vendor/k8s.io/client-go/discovery/discovery_client.go
new file mode 100644
index 0000000..a966029
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/client-go/discovery/discovery_client.go
@@ -0,0 +1,472 @@
+/*
+Copyright 2015 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package discovery
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/url"
+	"sort"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/golang/protobuf/proto"
+	"github.com/googleapis/gnostic/OpenAPIv2"
+
+	"k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/apimachinery/pkg/runtime/serializer"
+	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
+	"k8s.io/apimachinery/pkg/version"
+	"k8s.io/client-go/kubernetes/scheme"
+	restclient "k8s.io/client-go/rest"
+)
+
+const (
+	// defaultRetries is the number of times a resource discovery is repeated if an api group disappears on the fly (e.g. ThirdPartyResources).
+	defaultRetries = 2
+	// protobuf mime type
+	mimePb = "application/com.github.proto-openapi.spec.v2@v1.0+protobuf"
+	// defaultTimeout is the maximum amount of time per request when no timeout has been set on a RESTClient.
+	// Defaults to 32s in order to have a distinguishable length of time, relative to other timeouts that exist.
+	defaultTimeout = 32 * time.Second
+)
+
+// DiscoveryInterface holds the methods that discover server-supported API groups,
+// versions and resources.
+type DiscoveryInterface interface {
+	RESTClient() restclient.Interface
+	ServerGroupsInterface
+	ServerResourcesInterface
+	ServerVersionInterface
+	OpenAPISchemaInterface
+}
+
+// CachedDiscoveryInterface is a DiscoveryInterface with cache invalidation and freshness.
+type CachedDiscoveryInterface interface {
+	DiscoveryInterface
+	// Fresh is supposed to tell the caller whether or not to retry if the cache
+	// fails to find something (false = retry, true = no need to retry).
+	//
+	// TODO: this needs to be revisited, this interface can't be locked properly
+	// and doesn't make a lot of sense.
+	Fresh() bool
+	// Invalidate enforces that no cached data is used in the future that is older than the current time.
+	Invalidate()
+}
+
+// ServerGroupsInterface has methods for obtaining supported groups on the API server
+type ServerGroupsInterface interface {
+	// ServerGroups returns the supported groups, with information like supported versions and the
+	// preferred version.
+	ServerGroups() (*metav1.APIGroupList, error)
+}
+
+// ServerResourcesInterface has methods for obtaining supported resources on the API server
+type ServerResourcesInterface interface {
+	// ServerResourcesForGroupVersion returns the supported resources for a group and version.
+	ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error)
+	// ServerResources returns the supported resources for all groups and versions.
+	ServerResources() ([]*metav1.APIResourceList, error)
+	// ServerPreferredResources returns the supported resources with the version preferred by the
+	// server.
+	ServerPreferredResources() ([]*metav1.APIResourceList, error)
+	// ServerPreferredNamespacedResources returns the supported namespaced resources with the
+	// version preferred by the server.
+	ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error)
+}
+
+// ServerVersionInterface has a method for retrieving the server's version.
+type ServerVersionInterface interface {
+	// ServerVersion retrieves and parses the server's version (git version).
+	ServerVersion() (*version.Info, error)
+}
+
+// OpenAPISchemaInterface has a method to retrieve the open API schema.
+type OpenAPISchemaInterface interface {
+	// OpenAPISchema retrieves and parses the swagger API schema the server supports.
+	OpenAPISchema() (*openapi_v2.Document, error)
+}
+
+// DiscoveryClient implements the functions that discover server-supported API groups,
+// versions and resources.
+type DiscoveryClient struct {
+	restClient restclient.Interface
+
+	LegacyPrefix string
+}
+
+// Convert metav1.APIVersions to metav1.APIGroup. APIVersions is used by legacy v1, so
+// group would be "".
+func apiVersionsToAPIGroup(apiVersions *metav1.APIVersions) (apiGroup metav1.APIGroup) {
+	groupVersions := []metav1.GroupVersionForDiscovery{}
+	for _, version := range apiVersions.Versions {
+		groupVersion := metav1.GroupVersionForDiscovery{
+			GroupVersion: version,
+			Version:      version,
+		}
+		groupVersions = append(groupVersions, groupVersion)
+	}
+	apiGroup.Versions = groupVersions
+	// There should be only one groupVersion returned at /api
+	apiGroup.PreferredVersion = groupVersions[0]
+	return
+}
+
+// ServerGroups returns the supported groups, with information like supported versions and the
+// preferred version.
+func (d *DiscoveryClient) ServerGroups() (apiGroupList *metav1.APIGroupList, err error) {
+	// Get the groupVersions exposed at /api
+	v := &metav1.APIVersions{}
+	err = d.restClient.Get().AbsPath(d.LegacyPrefix).Do().Into(v)
+	apiGroup := metav1.APIGroup{}
+	if err == nil && len(v.Versions) != 0 {
+		apiGroup = apiVersionsToAPIGroup(v)
+	}
+	if err != nil && !errors.IsNotFound(err) && !errors.IsForbidden(err) {
+		return nil, err
+	}
+
+	// Get the groupVersions exposed at /apis
+	apiGroupList = &metav1.APIGroupList{}
+	err = d.restClient.Get().AbsPath("/apis").Do().Into(apiGroupList)
+	if err != nil && !errors.IsNotFound(err) && !errors.IsForbidden(err) {
+		return nil, err
+	}
+	// to be compatible with a v1.0 server, if it's a 403 or 404, ignore and return whatever we got from /api
+	if err != nil && (errors.IsNotFound(err) || errors.IsForbidden(err)) {
+		apiGroupList = &metav1.APIGroupList{}
+	}
+
+	// prepend the group retrieved from /api to the list if not empty
+	if len(v.Versions) != 0 {
+		apiGroupList.Groups = append([]metav1.APIGroup{apiGroup}, apiGroupList.Groups...)
+	}
+	return apiGroupList, nil
+}
+
+// ServerResourcesForGroupVersion returns the supported resources for a group and version.
+func (d *DiscoveryClient) ServerResourcesForGroupVersion(groupVersion string) (resources *metav1.APIResourceList, err error) {
+	url := url.URL{}
+	if len(groupVersion) == 0 {
+		return nil, fmt.Errorf("groupVersion shouldn't be empty")
+	}
+	if len(d.LegacyPrefix) > 0 && groupVersion == "v1" {
+		url.Path = d.LegacyPrefix + "/" + groupVersion
+	} else {
+		url.Path = "/apis/" + groupVersion
+	}
+	resources = &metav1.APIResourceList{
+		GroupVersion: groupVersion,
+	}
+	err = d.restClient.Get().AbsPath(url.String()).Do().Into(resources)
+	if err != nil {
+		// ignore 403 or 404 error to be compatible with an v1.0 server.
+		if groupVersion == "v1" && (errors.IsNotFound(err) || errors.IsForbidden(err)) {
+			return resources, nil
+		}
+		return nil, err
+	}
+	return resources, nil
+}
+
+// serverResources returns the supported resources for all groups and versions.
+func (d *DiscoveryClient) serverResources() ([]*metav1.APIResourceList, error) {
+	return ServerResources(d)
+}
+
+// ServerResources returns the supported resources for all groups and versions.
+func (d *DiscoveryClient) ServerResources() ([]*metav1.APIResourceList, error) {
+	return withRetries(defaultRetries, d.serverResources)
+}
+
+// ErrGroupDiscoveryFailed is returned if one or more API groups fail to load.
+type ErrGroupDiscoveryFailed struct {
+	// Groups is a list of the groups that failed to load and the error cause
+	Groups map[schema.GroupVersion]error
+}
+
+// Error implements the error interface
+func (e *ErrGroupDiscoveryFailed) Error() string {
+	var groups []string
+	for k, v := range e.Groups {
+		groups = append(groups, fmt.Sprintf("%s: %v", k, v))
+	}
+	sort.Strings(groups)
+	return fmt.Sprintf("unable to retrieve the complete list of server APIs: %s", strings.Join(groups, ", "))
+}
+
+// IsGroupDiscoveryFailedError returns true if the provided error indicates the server was unable to discover
+// a complete list of APIs for the client to use.
+func IsGroupDiscoveryFailedError(err error) bool {
+	_, ok := err.(*ErrGroupDiscoveryFailed)
+	return err != nil && ok
+}
+
+// serverPreferredResources returns the supported resources with the version preferred by the server.
+func (d *DiscoveryClient) serverPreferredResources() ([]*metav1.APIResourceList, error) {
+	return ServerPreferredResources(d)
+}
+
+// ServerResources uses the provided discovery interface to look up supported resources for all groups and versions.
+func ServerResources(d DiscoveryInterface) ([]*metav1.APIResourceList, error) {
+	apiGroups, err := d.ServerGroups()
+	if err != nil {
+		return nil, err
+	}
+
+	groupVersionResources, failedGroups := fetchGroupVersionResources(d, apiGroups)
+
+	// order results by group/version discovery order
+	result := []*metav1.APIResourceList{}
+	for _, apiGroup := range apiGroups.Groups {
+		for _, version := range apiGroup.Versions {
+			gv := schema.GroupVersion{Group: apiGroup.Name, Version: version.Version}
+			if resources, ok := groupVersionResources[gv]; ok {
+				result = append(result, resources)
+			}
+		}
+	}
+
+	if len(failedGroups) == 0 {
+		return result, nil
+	}
+
+	return result, &ErrGroupDiscoveryFailed{Groups: failedGroups}
+}
+
+// ServerPreferredResources uses the provided discovery interface to look up preferred resources
+func ServerPreferredResources(d DiscoveryInterface) ([]*metav1.APIResourceList, error) {
+	serverGroupList, err := d.ServerGroups()
+	if err != nil {
+		return nil, err
+	}
+
+	groupVersionResources, failedGroups := fetchGroupVersionResources(d, serverGroupList)
+
+	result := []*metav1.APIResourceList{}
+	grVersions := map[schema.GroupResource]string{}                         // selected version of a GroupResource
+	grApiResources := map[schema.GroupResource]*metav1.APIResource{}        // selected APIResource for a GroupResource
+	gvApiResourceLists := map[schema.GroupVersion]*metav1.APIResourceList{} // blueprint for a APIResourceList for later grouping
+
+	for _, apiGroup := range serverGroupList.Groups {
+		for _, version := range apiGroup.Versions {
+			groupVersion := schema.GroupVersion{Group: apiGroup.Name, Version: version.Version}
+
+			apiResourceList, ok := groupVersionResources[groupVersion]
+			if !ok {
+				continue
+			}
+
+			// create empty list which is filled later in another loop
+			emptyApiResourceList := metav1.APIResourceList{
+				GroupVersion: version.GroupVersion,
+			}
+			gvApiResourceLists[groupVersion] = &emptyApiResourceList
+			result = append(result, &emptyApiResourceList)
+
+			for i := range apiResourceList.APIResources {
+				apiResource := &apiResourceList.APIResources[i]
+				if strings.Contains(apiResource.Name, "/") {
+					continue
+				}
+				gv := schema.GroupResource{Group: apiGroup.Name, Resource: apiResource.Name}
+				if _, ok := grApiResources[gv]; ok && version.Version != apiGroup.PreferredVersion.Version {
+					// only override with preferred version
+					continue
+				}
+				grVersions[gv] = version.Version
+				grApiResources[gv] = apiResource
+			}
+		}
+	}
+
+	// group selected APIResources according to GroupVersion into APIResourceLists
+	for groupResource, apiResource := range grApiResources {
+		version := grVersions[groupResource]
+		groupVersion := schema.GroupVersion{Group: groupResource.Group, Version: version}
+		apiResourceList := gvApiResourceLists[groupVersion]
+		apiResourceList.APIResources = append(apiResourceList.APIResources, *apiResource)
+	}
+
+	if len(failedGroups) == 0 {
+		return result, nil
+	}
+
+	return result, &ErrGroupDiscoveryFailed{Groups: failedGroups}
+}
+
+// fetchServerResourcesForGroupVersions uses the discovery client to fetch the resources for the specified groups in parallel
+func fetchGroupVersionResources(d DiscoveryInterface, apiGroups *metav1.APIGroupList) (map[schema.GroupVersion]*metav1.APIResourceList, map[schema.GroupVersion]error) {
+	groupVersionResources := make(map[schema.GroupVersion]*metav1.APIResourceList)
+	failedGroups := make(map[schema.GroupVersion]error)
+
+	wg := &sync.WaitGroup{}
+	resultLock := &sync.Mutex{}
+	for _, apiGroup := range apiGroups.Groups {
+		for _, version := range apiGroup.Versions {
+			groupVersion := schema.GroupVersion{Group: apiGroup.Name, Version: version.Version}
+			wg.Add(1)
+			go func() {
+				defer wg.Done()
+				defer utilruntime.HandleCrash()
+
+				apiResourceList, err := d.ServerResourcesForGroupVersion(groupVersion.String())
+
+				// lock to record results
+				resultLock.Lock()
+				defer resultLock.Unlock()
+
+				if err != nil {
+					// TODO: maybe restrict this to NotFound errors
+					failedGroups[groupVersion] = err
+				} else {
+					groupVersionResources[groupVersion] = apiResourceList
+				}
+			}()
+		}
+	}
+	wg.Wait()
+
+	return groupVersionResources, failedGroups
+}
+
+// ServerPreferredResources returns the supported resources with the version preferred by the
+// server.
+func (d *DiscoveryClient) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
+	return withRetries(defaultRetries, d.serverPreferredResources)
+}
+
+// ServerPreferredNamespacedResources returns the supported namespaced resources with the
+// version preferred by the server.
+func (d *DiscoveryClient) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
+	return ServerPreferredNamespacedResources(d)
+}
+
+// ServerPreferredNamespacedResources uses the provided discovery interface to look up preferred namespaced resources
+func ServerPreferredNamespacedResources(d DiscoveryInterface) ([]*metav1.APIResourceList, error) {
+	all, err := ServerPreferredResources(d)
+	return FilteredBy(ResourcePredicateFunc(func(groupVersion string, r *metav1.APIResource) bool {
+		return r.Namespaced
+	}), all), err
+}
+
+// ServerVersion retrieves and parses the server's version (git version).
+func (d *DiscoveryClient) ServerVersion() (*version.Info, error) {
+	body, err := d.restClient.Get().AbsPath("/version").Do().Raw()
+	if err != nil {
+		return nil, err
+	}
+	var info version.Info
+	err = json.Unmarshal(body, &info)
+	if err != nil {
+		return nil, fmt.Errorf("got '%s': %v", string(body), err)
+	}
+	return &info, nil
+}
+
+// OpenAPISchema fetches the open api schema using a rest client and parses the proto.
+func (d *DiscoveryClient) OpenAPISchema() (*openapi_v2.Document, error) {
+	data, err := d.restClient.Get().AbsPath("/openapi/v2").SetHeader("Accept", mimePb).Do().Raw()
+	if err != nil {
+		if errors.IsForbidden(err) || errors.IsNotFound(err) || errors.IsNotAcceptable(err) {
+			// single endpoint not found/registered in old server, try to fetch old endpoint
+			// TODO(roycaihw): remove this in 1.11
+			data, err = d.restClient.Get().AbsPath("/swagger-2.0.0.pb-v1").Do().Raw()
+			if err != nil {
+				return nil, err
+			}
+		} else {
+			return nil, err
+		}
+	}
+	document := &openapi_v2.Document{}
+	err = proto.Unmarshal(data, document)
+	if err != nil {
+		return nil, err
+	}
+	return document, nil
+}
+
+// withRetries retries the given recovery function in case the groups supported by the server change after ServerGroup() returns.
+func withRetries(maxRetries int, f func() ([]*metav1.APIResourceList, error)) ([]*metav1.APIResourceList, error) {
+	var result []*metav1.APIResourceList
+	var err error
+	for i := 0; i < maxRetries; i++ {
+		result, err = f()
+		if err == nil {
+			return result, nil
+		}
+		if _, ok := err.(*ErrGroupDiscoveryFailed); !ok {
+			return nil, err
+		}
+	}
+	return result, err
+}
+
+func setDiscoveryDefaults(config *restclient.Config) error {
+	config.APIPath = ""
+	config.GroupVersion = nil
+	if config.Timeout == 0 {
+		config.Timeout = defaultTimeout
+	}
+	codec := runtime.NoopEncoder{Decoder: scheme.Codecs.UniversalDecoder()}
+	config.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec})
+	if len(config.UserAgent) == 0 {
+		config.UserAgent = restclient.DefaultKubernetesUserAgent()
+	}
+	return nil
+}
+
+// NewDiscoveryClientForConfig creates a new DiscoveryClient for the given config. This client
+// can be used to discover supported resources in the API server.
+func NewDiscoveryClientForConfig(c *restclient.Config) (*DiscoveryClient, error) {
+	config := *c
+	if err := setDiscoveryDefaults(&config); err != nil {
+		return nil, err
+	}
+	client, err := restclient.UnversionedRESTClientFor(&config)
+	return &DiscoveryClient{restClient: client, LegacyPrefix: "/api"}, err
+}
+
+// NewDiscoveryClientForConfigOrDie creates a new DiscoveryClient for the given config. If
+// there is an error, it panics.
+func NewDiscoveryClientForConfigOrDie(c *restclient.Config) *DiscoveryClient {
+	client, err := NewDiscoveryClientForConfig(c)
+	if err != nil {
+		panic(err)
+	}
+	return client
+
+}
+
+// NewDiscoveryClient returns  a new DiscoveryClient for the given RESTClient.
+func NewDiscoveryClient(c restclient.Interface) *DiscoveryClient {
+	return &DiscoveryClient{restClient: c, LegacyPrefix: "/api"}
+}
+
+// RESTClient returns a RESTClient that is used to communicate
+// with API server by this client implementation.
+func (c *DiscoveryClient) RESTClient() restclient.Interface {
+	if c == nil {
+		return nil
+	}
+	return c.restClient
+}
diff --git a/metrics-server/vendor/k8s.io/client-go/discovery/helper.go b/metrics-server/vendor/k8s.io/client-go/discovery/helper.go
new file mode 100644
index 0000000..353d34b
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/client-go/discovery/helper.go
@@ -0,0 +1,121 @@
+/*
+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 discovery
+
+import (
+	"fmt"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+	"k8s.io/apimachinery/pkg/util/sets"
+	apimachineryversion "k8s.io/apimachinery/pkg/version"
+)
+
+// MatchesServerVersion queries the server to compares the build version
+// (git hash) of the client with the server's build version. It returns an error
+// if it failed to contact the server or if the versions are not an exact match.
+func MatchesServerVersion(clientVersion apimachineryversion.Info, client DiscoveryInterface) error {
+	sVer, err := client.ServerVersion()
+	if err != nil {
+		return fmt.Errorf("couldn't read version from server: %v\n", err)
+	}
+	// GitVersion includes GitCommit and GitTreeState, but best to be safe?
+	if clientVersion.GitVersion != sVer.GitVersion || clientVersion.GitCommit != sVer.GitCommit || clientVersion.GitTreeState != sVer.GitTreeState {
+		return fmt.Errorf("server version (%#v) differs from client version (%#v)!\n", sVer, clientVersion)
+	}
+
+	return nil
+}
+
+// ServerSupportsVersion returns an error if the server doesn't have the required version
+func ServerSupportsVersion(client DiscoveryInterface, requiredGV schema.GroupVersion) error {
+	groups, err := client.ServerGroups()
+	if err != nil {
+		// This is almost always a connection error, and higher level code should treat this as a generic error,
+		// not a negotiation specific error.
+		return err
+	}
+	versions := metav1.ExtractGroupVersions(groups)
+	serverVersions := sets.String{}
+	for _, v := range versions {
+		serverVersions.Insert(v)
+	}
+
+	if serverVersions.Has(requiredGV.String()) {
+		return nil
+	}
+
+	// If the server supports no versions, then we should pretend it has the version because of old servers.
+	// This can happen because discovery fails due to 403 Forbidden errors
+	if len(serverVersions) == 0 {
+		return nil
+	}
+
+	return fmt.Errorf("server does not support API version %q", requiredGV)
+}
+
+// GroupVersionResources converts APIResourceLists to the GroupVersionResources.
+func GroupVersionResources(rls []*metav1.APIResourceList) (map[schema.GroupVersionResource]struct{}, error) {
+	gvrs := map[schema.GroupVersionResource]struct{}{}
+	for _, rl := range rls {
+		gv, err := schema.ParseGroupVersion(rl.GroupVersion)
+		if err != nil {
+			return nil, err
+		}
+		for i := range rl.APIResources {
+			gvrs[schema.GroupVersionResource{Group: gv.Group, Version: gv.Version, Resource: rl.APIResources[i].Name}] = struct{}{}
+		}
+	}
+	return gvrs, nil
+}
+
+// FilteredBy filters by the given predicate. Empty APIResourceLists are dropped.
+func FilteredBy(pred ResourcePredicate, rls []*metav1.APIResourceList) []*metav1.APIResourceList {
+	result := []*metav1.APIResourceList{}
+	for _, rl := range rls {
+		filtered := *rl
+		filtered.APIResources = nil
+		for i := range rl.APIResources {
+			if pred.Match(rl.GroupVersion, &rl.APIResources[i]) {
+				filtered.APIResources = append(filtered.APIResources, rl.APIResources[i])
+			}
+		}
+		if filtered.APIResources != nil {
+			result = append(result, &filtered)
+		}
+	}
+	return result
+}
+
+type ResourcePredicate interface {
+	Match(groupVersion string, r *metav1.APIResource) bool
+}
+
+type ResourcePredicateFunc func(groupVersion string, r *metav1.APIResource) bool
+
+func (fn ResourcePredicateFunc) Match(groupVersion string, r *metav1.APIResource) bool {
+	return fn(groupVersion, r)
+}
+
+// SupportsAllVerbs is a predicate matching a resource iff all given verbs are supported.
+type SupportsAllVerbs struct {
+	Verbs []string
+}
+
+func (p SupportsAllVerbs) Match(groupVersion string, r *metav1.APIResource) bool {
+	return sets.NewString([]string(r.Verbs)...).HasAll(p.Verbs...)
+}
diff --git a/metrics-server/vendor/k8s.io/client-go/discovery/round_tripper.go b/metrics-server/vendor/k8s.io/client-go/discovery/round_tripper.go
new file mode 100644
index 0000000..2e352b8
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/client-go/discovery/round_tripper.go
@@ -0,0 +1,51 @@
+/*
+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 transport provides a round tripper capable of caching HTTP responses.
+package discovery
+
+import (
+	"net/http"
+	"path/filepath"
+
+	"github.com/gregjones/httpcache"
+	"github.com/gregjones/httpcache/diskcache"
+	"github.com/peterbourgon/diskv"
+)
+
+type cacheRoundTripper struct {
+	rt *httpcache.Transport
+}
+
+// newCacheRoundTripper creates a roundtripper that reads the ETag on
+// response headers and send the If-None-Match header on subsequent
+// corresponding requests.
+func newCacheRoundTripper(cacheDir string, rt http.RoundTripper) http.RoundTripper {
+	d := diskv.New(diskv.Options{
+		BasePath: cacheDir,
+		TempDir:  filepath.Join(cacheDir, ".diskv-temp"),
+	})
+	t := httpcache.NewTransport(diskcache.NewWithDiskv(d))
+	t.Transport = rt
+
+	return &cacheRoundTripper{rt: t}
+}
+
+func (rt *cacheRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
+	return rt.rt.RoundTrip(req)
+}
+
+func (rt *cacheRoundTripper) WrappedRoundTripper() http.RoundTripper { return rt.rt.Transport }
diff --git a/metrics-server/vendor/k8s.io/client-go/discovery/unstructured.go b/metrics-server/vendor/k8s.io/client-go/discovery/unstructured.go
new file mode 100644
index 0000000..81913a4
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/client-go/discovery/unstructured.go
@@ -0,0 +1,81 @@
+/*
+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 discovery
+
+import (
+	"reflect"
+
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+// UnstructuredObjectTyper provides a runtime.ObjectTyper implementation for
+// runtime.Unstructured object based on discovery information.
+type UnstructuredObjectTyper struct {
+	typers []runtime.ObjectTyper
+}
+
+// NewUnstructuredObjectTyper returns a runtime.ObjectTyper for
+// unstructured objects based on discovery information. It accepts a list of fallback typers
+// for handling objects that are not runtime.Unstructured. It does not delegate the Recognizes
+// check, only ObjectKinds.
+// TODO this only works for the apiextensions server and doesn't recognize any types.  Move to point of use.
+func NewUnstructuredObjectTyper(typers ...runtime.ObjectTyper) *UnstructuredObjectTyper {
+	dot := &UnstructuredObjectTyper{
+		typers: typers,
+	}
+	return dot
+}
+
+// ObjectKinds returns a slice of one element with the group,version,kind of the
+// provided object, or an error if the object is not runtime.Unstructured or
+// has no group,version,kind information. unversionedType will always be false
+// because runtime.Unstructured object should always have group,version,kind
+// information set.
+func (d *UnstructuredObjectTyper) ObjectKinds(obj runtime.Object) (gvks []schema.GroupVersionKind, unversionedType bool, err error) {
+	if _, ok := obj.(runtime.Unstructured); ok {
+		gvk := obj.GetObjectKind().GroupVersionKind()
+		if len(gvk.Kind) == 0 {
+			return nil, false, runtime.NewMissingKindErr("object has no kind field ")
+		}
+		if len(gvk.Version) == 0 {
+			return nil, false, runtime.NewMissingVersionErr("object has no apiVersion field")
+		}
+		return []schema.GroupVersionKind{gvk}, false, nil
+	}
+	var lastErr error
+	for _, typer := range d.typers {
+		gvks, unversioned, err := typer.ObjectKinds(obj)
+		if err != nil {
+			lastErr = err
+			continue
+		}
+		return gvks, unversioned, nil
+	}
+	if lastErr == nil {
+		lastErr = runtime.NewNotRegisteredErrForType(reflect.TypeOf(obj))
+	}
+	return nil, false, lastErr
+}
+
+// Recognizes returns true if the provided group,version,kind was in the
+// discovery information.
+func (d *UnstructuredObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool {
+	return false
+}
+
+var _ runtime.ObjectTyper = &UnstructuredObjectTyper{}
