git subrepo clone (merge) https://github.com/kubernetes-incubator/metrics-server.git metrics-server

subrepo:
  subdir:   "metrics-server"
  merged:   "92d8412"
upstream:
  origin:   "https://github.com/kubernetes-incubator/metrics-server.git"
  branch:   "master"
  commit:   "92d8412"
git-subrepo:
  version:  "0.4.0"
  origin:   "???"
  commit:   "???"
diff --git a/metrics-server/vendor/github.com/onsi/gomega/.gitignore b/metrics-server/vendor/github.com/onsi/gomega/.gitignore
new file mode 100644
index 0000000..720c13c
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/.gitignore
@@ -0,0 +1,5 @@
+.DS_Store
+*.test
+.
+.idea
+gomega.iml
diff --git a/metrics-server/vendor/github.com/onsi/gomega/.travis.yml b/metrics-server/vendor/github.com/onsi/gomega/.travis.yml
new file mode 100644
index 0000000..8b982a9
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/.travis.yml
@@ -0,0 +1,14 @@
+language: go
+go:
+  - 1.6.x
+  - 1.7.x
+  - 1.8.x
+  - 1.9.x
+  - 1.10.x
+
+install:
+  - go get -v ./...
+  - go get github.com/onsi/ginkgo
+  - go install github.com/onsi/ginkgo/ginkgo
+
+script: $HOME/gopath/bin/ginkgo -p -r --randomizeAllSpecs --failOnPending --randomizeSuites --race && go vet
diff --git a/metrics-server/vendor/github.com/onsi/gomega/CHANGELOG.md b/metrics-server/vendor/github.com/onsi/gomega/CHANGELOG.md
new file mode 100644
index 0000000..2ee5d9b
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -0,0 +1,99 @@
+## HEAD
+
+### Features
+- Make string pretty diff user configurable (#273) [eb112ce, 649b44d]
+
+### Fixes
+- Use httputil.DumpRequest to pretty-print unhandled requests (#278) [a4ff0fc, b7d1a52]
+- fix typo floa32 > float32 (#272) [041ae3b, 6e33911]
+- Fix link to documentation on adding your own matchers (#270) [bb2c830, fcebc62]
+- Use setters and getters to avoid race condition (#262) [13057c3, a9c79f1]
+- Avoid sending a signal if the process is not alive (#259) [b8043e5, 4fc1762]
+- Improve message from AssignableToTypeOf when expected value is nil (#281) [9c1fb20]
+
+## 1.3.0
+
+Improvements:
+
+- The `Equal` matcher matches byte slices more performantly.
+- Improved how `MatchError` matches error strings.
+- `MatchXML` ignores the order of xml node attributes.
+- Improve support for XUnit style golang tests. ([#254](https://github.com/onsi/gomega/issues/254))
+
+Bug Fixes:
+
+- Diff generation now handles multi-byte sequences correctly.
+- Multiple goroutines can now call `gexec.Build` concurrently.
+
+## 1.2.0
+
+Improvements:
+
+- Added `BeSent` which attempts to send a value down a channel and fails if the attempt blocks.  Can be paired with `Eventually` to safely send a value down a channel with a timeout.
+- `Ω`, `Expect`, `Eventually`, and `Consistently` now immediately `panic` if there is no registered fail handler.  This is always a mistake that can hide failing tests.
+- `Receive()` no longer errors when passed a closed channel, it's perfectly fine to attempt to read from a closed channel so Ω(c).Should(Receive()) always fails and Ω(c).ShoudlNot(Receive()) always passes with a closed channel.
+- Added `HavePrefix` and `HaveSuffix` matchers.
+- `ghttp` can now handle concurrent requests.
+- Added `Succeed` which allows one to write `Ω(MyFunction()).Should(Succeed())`.
+- Improved `ghttp`'s behavior around failing assertions and panics:
+    - If a registered handler makes a failing assertion `ghttp` will return `500`.
+    - If a registered handler panics, `ghttp` will return `500` *and* fail the test.  This is new behavior that may cause existing code to break.  This code is almost certainly incorrect and creating a false positive.
+- `ghttp` servers can take an `io.Writer`.  `ghttp` will write a line to the writer when each request arrives.
+- Added `WithTransform` matcher to allow munging input data before feeding into the relevant matcher
+- Added boolean `And`, `Or`, and `Not` matchers to allow creating composite matchers
+- Added `gbytes.TimeoutCloser`, `gbytes.TimeoutReader`, and `gbytes.TimeoutWriter` - these are convenience wrappers that timeout if the underlying Closer/Reader/Writer does not return within the alloted time.
+- Added `gbytes.BufferReader` - this constructs a `gbytes.Buffer` that asynchronously reads the passed-in `io.Reader` into its buffer.
+
+Bug Fixes:
+- gexec: `session.Wait` now uses `EventuallyWithOffset` to get the right line number in the failure.
+- `ContainElement` no longer bails if a passed-in matcher errors.
+
+## 1.0 (8/2/2014)
+
+No changes. Dropping "beta" from the version number.
+
+## 1.0.0-beta (7/8/2014)
+Breaking Changes:
+
+- Changed OmegaMatcher interface.  Instead of having `Match` return failure messages, two new methods `FailureMessage` and `NegatedFailureMessage` are called instead.
+- Moved and renamed OmegaFailHandler to types.GomegaFailHandler and OmegaMatcher to types.GomegaMatcher.  Any references to OmegaMatcher in any custom matchers will need to be changed to point to types.GomegaMatcher
+
+New Test-Support Features:
+
+- `ghttp`: supports testing http clients
+    - Provides a flexible fake http server
+    - Provides a collection of chainable http handlers that perform assertions.
+- `gbytes`: supports making ordered assertions against streams of data
+    - Provides a `gbytes.Buffer`
+    - Provides a `Say` matcher to perform ordered assertions against output data
+- `gexec`: supports testing external processes
+    - Provides support for building Go binaries
+    - Wraps and starts `exec.Cmd` commands
+    - Makes it easy to assert against stdout and stderr
+    - Makes it easy to send signals and wait for processes to exit
+    - Provides an `Exit` matcher to assert against exit code.
+
+DSL Changes:
+
+- `Eventually` and `Consistently` can accept `time.Duration` interval and polling inputs.
+- The default timeouts for `Eventually` and `Consistently` are now configurable.
+
+New Matchers:
+
+- `ConsistOf`: order-independent assertion against the elements of an array/slice or keys of a map.
+- `BeTemporally`: like `BeNumerically` but for `time.Time`
+- `HaveKeyWithValue`: asserts a map has a given key with the given value.
+
+Updated Matchers:
+
+- `Receive` matcher can take a matcher as an argument and passes only if the channel under test receives an objet that satisfies the passed-in matcher.
+- Matchers that implement `MatchMayChangeInTheFuture(actual interface{}) bool` can inform `Eventually` and/or `Consistently` when a match has no chance of changing status in the future.  For example, `Receive` returns `false` when a channel is closed.
+
+Misc:
+
+- Start using semantic versioning
+- Start maintaining changelog
+
+Major refactor:
+
+- Pull out Gomega's internal to `internal`
diff --git a/metrics-server/vendor/github.com/onsi/gomega/CONTRIBUTING.md b/metrics-server/vendor/github.com/onsi/gomega/CONTRIBUTING.md
new file mode 100644
index 0000000..0d7a099
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/CONTRIBUTING.md
@@ -0,0 +1,14 @@
+# Contributing to Gomega
+
+Your contributions to Gomega are essential for its long-term maintenance and improvement.  To make a contribution:
+
+- Please **open an issue first** - describe what problem you are trying to solve and give the community a forum for input and feedback ahead of investing time in writing code!
+- Ensure adequate test coverage:
+    - Make sure to add appropriate unit tests
+    - Please run all tests locally (`ginkgo -r -p`) and make sure they go green before submitting the PR
+    - Please run following linter locally `go vet ./...` and make sure output does not contain any warnings
+- Update the documentation.  In addition to standard `godoc` comments Gomega has extensive documentation on the `gh-pages` branch.  If relevant, please submit a docs PR to that branch alongside your code PR.
+
+If you're a committer, check out RELEASING.md to learn how to cut a release.
+
+Thanks for supporting Gomega!
diff --git a/metrics-server/vendor/github.com/onsi/gomega/LICENSE b/metrics-server/vendor/github.com/onsi/gomega/LICENSE
new file mode 100644
index 0000000..9415ee7
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2013-2014 Onsi Fakhouri
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/metrics-server/vendor/github.com/onsi/gomega/README.md b/metrics-server/vendor/github.com/onsi/gomega/README.md
new file mode 100644
index 0000000..159be35
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/README.md
@@ -0,0 +1,21 @@
+![Gomega: Ginkgo's Preferred Matcher Library](http://onsi.github.io/gomega/images/gomega.png)
+
+[![Build Status](https://travis-ci.org/onsi/gomega.svg)](https://travis-ci.org/onsi/gomega)
+
+Jump straight to the [docs](http://onsi.github.io/gomega/) to learn about Gomega, including a list of [all available matchers](http://onsi.github.io/gomega/#provided-matchers).
+
+If you have a question, comment, bug report, feature request, etc. please open a GitHub issue.
+
+## [Ginkgo](http://github.com/onsi/ginkgo): a BDD Testing Framework for Golang
+
+Learn more about Ginkgo [here](http://onsi.github.io/ginkgo/)
+
+## Community Matchers
+
+A collection of community matchers is available on the [wiki](https://github.com/onsi/gomega/wiki).
+
+## License
+
+Gomega is MIT-Licensed
+
+The `ConsistOf` matcher uses [goraph](https://github.com/amitkgupta/goraph) which is embedded in the source to simplify distribution.  goraph has an MIT license.
diff --git a/metrics-server/vendor/github.com/onsi/gomega/RELEASING.md b/metrics-server/vendor/github.com/onsi/gomega/RELEASING.md
new file mode 100644
index 0000000..998d64e
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/RELEASING.md
@@ -0,0 +1,12 @@
+A Gomega release is a tagged sha and a GitHub release.  To cut a release:
+
+1. Ensure CHANGELOG.md is up to date.
+  - Use `git log --pretty=format:'- %s [%h]' HEAD...vX.X.X` to list all the commits since the last release
+  - Categorize the changes into
+    - Breaking Changes (requires a major version)
+    - New Features (minor version)
+    - Fixes (fix version)
+    - Maintenance (which in general should not be mentioned in `CHANGELOG.md` as they have no user impact)
+2. Update GOMEGA_VERSION in `gomega_dsl.go`
+3. Push a commit with the version number as the commit message (e.g. `v1.3.0`)
+4. Create a new [GitHub release](https://help.github.com/articles/creating-releases/) with the version number as the tag  (e.g. `v1.3.0`).  List the key changes in the release notes.
diff --git a/metrics-server/vendor/github.com/onsi/gomega/format/format.go b/metrics-server/vendor/github.com/onsi/gomega/format/format.go
new file mode 100644
index 0000000..6559525
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/format/format.go
@@ -0,0 +1,382 @@
+/*
+Gomega's format package pretty-prints objects.  It explores input objects recursively and generates formatted, indented output with type information.
+*/
+package format
+
+import (
+	"fmt"
+	"reflect"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// Use MaxDepth to set the maximum recursion depth when printing deeply nested objects
+var MaxDepth = uint(10)
+
+/*
+By default, all objects (even those that implement fmt.Stringer and fmt.GoStringer) are recursively inspected to generate output.
+
+Set UseStringerRepresentation = true to use GoString (for fmt.GoStringers) or String (for fmt.Stringer) instead.
+
+Note that GoString and String don't always have all the information you need to understand why a test failed!
+*/
+var UseStringerRepresentation = false
+
+/*
+Print the content of context objects. By default it will be suppressed.
+
+Set PrintContextObjects = true to enable printing of the context internals.
+*/
+var PrintContextObjects = false
+
+// TruncatedDiff choose if we should display a truncated pretty diff or not
+var TruncatedDiff = true
+
+// Ctx interface defined here to keep backwards compatability with go < 1.7
+// It matches the context.Context interface
+type Ctx interface {
+	Deadline() (deadline time.Time, ok bool)
+	Done() <-chan struct{}
+	Err() error
+	Value(key interface{}) interface{}
+}
+
+var contextType = reflect.TypeOf((*Ctx)(nil)).Elem()
+var timeType = reflect.TypeOf(time.Time{})
+
+//The default indentation string emitted by the format package
+var Indent = "    "
+
+var longFormThreshold = 20
+
+/*
+Generates a formatted matcher success/failure message of the form:
+
+	Expected
+		<pretty printed actual>
+	<message>
+		<pretty printed expected>
+
+If expected is omited, then the message looks like:
+
+	Expected
+		<pretty printed actual>
+	<message>
+*/
+func Message(actual interface{}, message string, expected ...interface{}) string {
+	if len(expected) == 0 {
+		return fmt.Sprintf("Expected\n%s\n%s", Object(actual, 1), message)
+	}
+	return fmt.Sprintf("Expected\n%s\n%s\n%s", Object(actual, 1), message, Object(expected[0], 1))
+}
+
+/*
+
+Generates a nicely formatted matcher success / failure message
+
+Much like Message(...), but it attempts to pretty print diffs in strings
+
+Expected
+    <string>: "...aaaaabaaaaa..."
+to equal               |
+    <string>: "...aaaaazaaaaa..."
+
+*/
+
+func MessageWithDiff(actual, message, expected string) string {
+	if TruncatedDiff && len(actual) >= truncateThreshold && len(expected) >= truncateThreshold {
+		diffPoint := findFirstMismatch(actual, expected)
+		formattedActual := truncateAndFormat(actual, diffPoint)
+		formattedExpected := truncateAndFormat(expected, diffPoint)
+
+		spacesBeforeFormattedMismatch := findFirstMismatch(formattedActual, formattedExpected)
+
+		tabLength := 4
+		spaceFromMessageToActual := tabLength + len("<string>: ") - len(message)
+		padding := strings.Repeat(" ", spaceFromMessageToActual+spacesBeforeFormattedMismatch) + "|"
+		return Message(formattedActual, message+padding, formattedExpected)
+	}
+	return Message(actual, message, expected)
+}
+
+func truncateAndFormat(str string, index int) string {
+	leftPadding := `...`
+	rightPadding := `...`
+
+	start := index - charactersAroundMismatchToInclude
+	if start < 0 {
+		start = 0
+		leftPadding = ""
+	}
+
+	// slice index must include the mis-matched character
+	lengthOfMismatchedCharacter := 1
+	end := index + charactersAroundMismatchToInclude + lengthOfMismatchedCharacter
+	if end > len(str) {
+		end = len(str)
+		rightPadding = ""
+
+	}
+	return fmt.Sprintf("\"%s\"", leftPadding+str[start:end]+rightPadding)
+}
+
+func findFirstMismatch(a, b string) int {
+	aSlice := strings.Split(a, "")
+	bSlice := strings.Split(b, "")
+
+	for index, str := range aSlice {
+		if index > len(bSlice)-1 {
+			return index
+		}
+		if str != bSlice[index] {
+			return index
+		}
+	}
+
+	if len(b) > len(a) {
+		return len(a) + 1
+	}
+
+	return 0
+}
+
+const (
+	truncateThreshold                 = 50
+	charactersAroundMismatchToInclude = 5
+)
+
+/*
+Pretty prints the passed in object at the passed in indentation level.
+
+Object recurses into deeply nested objects emitting pretty-printed representations of their components.
+
+Modify format.MaxDepth to control how deep the recursion is allowed to go
+Set format.UseStringerRepresentation to true to return object.GoString() or object.String() when available instead of
+recursing into the object.
+
+Set PrintContextObjects to true to print the content of objects implementing context.Context
+*/
+func Object(object interface{}, indentation uint) string {
+	indent := strings.Repeat(Indent, int(indentation))
+	value := reflect.ValueOf(object)
+	return fmt.Sprintf("%s<%s>: %s", indent, formatType(object), formatValue(value, indentation))
+}
+
+/*
+IndentString takes a string and indents each line by the specified amount.
+*/
+func IndentString(s string, indentation uint) string {
+	components := strings.Split(s, "\n")
+	result := ""
+	indent := strings.Repeat(Indent, int(indentation))
+	for i, component := range components {
+		result += indent + component
+		if i < len(components)-1 {
+			result += "\n"
+		}
+	}
+
+	return result
+}
+
+func formatType(object interface{}) string {
+	t := reflect.TypeOf(object)
+	if t == nil {
+		return "nil"
+	}
+	switch t.Kind() {
+	case reflect.Chan:
+		v := reflect.ValueOf(object)
+		return fmt.Sprintf("%T | len:%d, cap:%d", object, v.Len(), v.Cap())
+	case reflect.Ptr:
+		return fmt.Sprintf("%T | %p", object, object)
+	case reflect.Slice:
+		v := reflect.ValueOf(object)
+		return fmt.Sprintf("%T | len:%d, cap:%d", object, v.Len(), v.Cap())
+	case reflect.Map:
+		v := reflect.ValueOf(object)
+		return fmt.Sprintf("%T | len:%d", object, v.Len())
+	default:
+		return fmt.Sprintf("%T", object)
+	}
+}
+
+func formatValue(value reflect.Value, indentation uint) string {
+	if indentation > MaxDepth {
+		return "..."
+	}
+
+	if isNilValue(value) {
+		return "nil"
+	}
+
+	if UseStringerRepresentation {
+		if value.CanInterface() {
+			obj := value.Interface()
+			switch x := obj.(type) {
+			case fmt.GoStringer:
+				return x.GoString()
+			case fmt.Stringer:
+				return x.String()
+			}
+		}
+	}
+
+	if !PrintContextObjects {
+		if value.Type().Implements(contextType) && indentation > 1 {
+			return "<suppressed context>"
+		}
+	}
+
+	switch value.Kind() {
+	case reflect.Bool:
+		return fmt.Sprintf("%v", value.Bool())
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return fmt.Sprintf("%v", value.Int())
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		return fmt.Sprintf("%v", value.Uint())
+	case reflect.Uintptr:
+		return fmt.Sprintf("0x%x", value.Uint())
+	case reflect.Float32, reflect.Float64:
+		return fmt.Sprintf("%v", value.Float())
+	case reflect.Complex64, reflect.Complex128:
+		return fmt.Sprintf("%v", value.Complex())
+	case reflect.Chan:
+		return fmt.Sprintf("0x%x", value.Pointer())
+	case reflect.Func:
+		return fmt.Sprintf("0x%x", value.Pointer())
+	case reflect.Ptr:
+		return formatValue(value.Elem(), indentation)
+	case reflect.Slice:
+		return formatSlice(value, indentation)
+	case reflect.String:
+		return formatString(value.String(), indentation)
+	case reflect.Array:
+		return formatSlice(value, indentation)
+	case reflect.Map:
+		return formatMap(value, indentation)
+	case reflect.Struct:
+		if value.Type() == timeType && value.CanInterface() {
+			t, _ := value.Interface().(time.Time)
+			return t.Format(time.RFC3339Nano)
+		}
+		return formatStruct(value, indentation)
+	case reflect.Interface:
+		return formatValue(value.Elem(), indentation)
+	default:
+		if value.CanInterface() {
+			return fmt.Sprintf("%#v", value.Interface())
+		}
+		return fmt.Sprintf("%#v", value)
+	}
+}
+
+func formatString(object interface{}, indentation uint) string {
+	if indentation == 1 {
+		s := fmt.Sprintf("%s", object)
+		components := strings.Split(s, "\n")
+		result := ""
+		for i, component := range components {
+			if i == 0 {
+				result += component
+			} else {
+				result += Indent + component
+			}
+			if i < len(components)-1 {
+				result += "\n"
+			}
+		}
+
+		return fmt.Sprintf("%s", result)
+	} else {
+		return fmt.Sprintf("%q", object)
+	}
+}
+
+func formatSlice(v reflect.Value, indentation uint) string {
+	if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 && isPrintableString(string(v.Bytes())) {
+		return formatString(v.Bytes(), indentation)
+	}
+
+	l := v.Len()
+	result := make([]string, l)
+	longest := 0
+	for i := 0; i < l; i++ {
+		result[i] = formatValue(v.Index(i), indentation+1)
+		if len(result[i]) > longest {
+			longest = len(result[i])
+		}
+	}
+
+	if longest > longFormThreshold {
+		indenter := strings.Repeat(Indent, int(indentation))
+		return fmt.Sprintf("[\n%s%s,\n%s]", indenter+Indent, strings.Join(result, ",\n"+indenter+Indent), indenter)
+	}
+	return fmt.Sprintf("[%s]", strings.Join(result, ", "))
+}
+
+func formatMap(v reflect.Value, indentation uint) string {
+	l := v.Len()
+	result := make([]string, l)
+
+	longest := 0
+	for i, key := range v.MapKeys() {
+		value := v.MapIndex(key)
+		result[i] = fmt.Sprintf("%s: %s", formatValue(key, indentation+1), formatValue(value, indentation+1))
+		if len(result[i]) > longest {
+			longest = len(result[i])
+		}
+	}
+
+	if longest > longFormThreshold {
+		indenter := strings.Repeat(Indent, int(indentation))
+		return fmt.Sprintf("{\n%s%s,\n%s}", indenter+Indent, strings.Join(result, ",\n"+indenter+Indent), indenter)
+	}
+	return fmt.Sprintf("{%s}", strings.Join(result, ", "))
+}
+
+func formatStruct(v reflect.Value, indentation uint) string {
+	t := v.Type()
+
+	l := v.NumField()
+	result := []string{}
+	longest := 0
+	for i := 0; i < l; i++ {
+		structField := t.Field(i)
+		fieldEntry := v.Field(i)
+		representation := fmt.Sprintf("%s: %s", structField.Name, formatValue(fieldEntry, indentation+1))
+		result = append(result, representation)
+		if len(representation) > longest {
+			longest = len(representation)
+		}
+	}
+	if longest > longFormThreshold {
+		indenter := strings.Repeat(Indent, int(indentation))
+		return fmt.Sprintf("{\n%s%s,\n%s}", indenter+Indent, strings.Join(result, ",\n"+indenter+Indent), indenter)
+	}
+	return fmt.Sprintf("{%s}", strings.Join(result, ", "))
+}
+
+func isNilValue(a reflect.Value) bool {
+	switch a.Kind() {
+	case reflect.Invalid:
+		return true
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+		return a.IsNil()
+	}
+
+	return false
+}
+
+/*
+Returns true when the string is entirely made of printable runes, false otherwise.
+*/
+func isPrintableString(str string) bool {
+	for _, runeValue := range str {
+		if !strconv.IsPrint(runeValue) {
+			return false
+		}
+	}
+	return true
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/gomega_dsl.go b/metrics-server/vendor/github.com/onsi/gomega/gomega_dsl.go
new file mode 100644
index 0000000..6c75d78
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -0,0 +1,396 @@
+/*
+Gomega is the Ginkgo BDD-style testing framework's preferred matcher library.
+
+The godoc documentation describes Gomega's API.  More comprehensive documentation (with examples!) is available at http://onsi.github.io/gomega/
+
+Gomega on Github: http://github.com/onsi/gomega
+
+Learn more about Ginkgo online: http://onsi.github.io/ginkgo
+
+Ginkgo on Github: http://github.com/onsi/ginkgo
+
+Gomega is MIT-Licensed
+*/
+package gomega
+
+import (
+	"fmt"
+	"reflect"
+	"time"
+
+	"github.com/onsi/gomega/internal/assertion"
+	"github.com/onsi/gomega/internal/asyncassertion"
+	"github.com/onsi/gomega/internal/testingtsupport"
+	"github.com/onsi/gomega/types"
+)
+
+const GOMEGA_VERSION = "1.4.0"
+
+const nilFailHandlerPanic = `You are trying to make an assertion, but Gomega's fail handler is nil.
+If you're using Ginkgo then you probably forgot to put your assertion in an It().
+Alternatively, you may have forgotten to register a fail handler with RegisterFailHandler() or RegisterTestingT().
+Depending on your vendoring solution you may be inadvertently importing gomega and subpackages (e.g. ghhtp, gexec,...) from different locations.
+`
+
+var globalFailHandler types.GomegaFailHandler
+
+var defaultEventuallyTimeout = time.Second
+var defaultEventuallyPollingInterval = 10 * time.Millisecond
+var defaultConsistentlyDuration = 100 * time.Millisecond
+var defaultConsistentlyPollingInterval = 10 * time.Millisecond
+
+//RegisterFailHandler connects Ginkgo to Gomega.  When a matcher fails
+//the fail handler passed into RegisterFailHandler is called.
+func RegisterFailHandler(handler types.GomegaFailHandler) {
+	globalFailHandler = handler
+}
+
+//RegisterTestingT connects Gomega to Golang's XUnit style
+//Testing.T tests.  It is now deprecated and you should use NewGomegaWithT() instead.
+//
+//Legacy Documentation:
+//
+//You'll need to call this at the top of each XUnit style test:
+//
+// func TestFarmHasCow(t *testing.T) {
+//     RegisterTestingT(t)
+//
+//	   f := farm.New([]string{"Cow", "Horse"})
+//     Expect(f.HasCow()).To(BeTrue(), "Farm should have cow")
+// }
+//
+// Note that this *testing.T is registered *globally* by Gomega (this is why you don't have to
+// pass `t` down to the matcher itself).  This means that you cannot run the XUnit style tests
+// in parallel as the global fail handler cannot point to more than one testing.T at a time.
+//
+// NewGomegaWithT() does not have this limitation
+//
+// (As an aside: Ginkgo gets around this limitation by running parallel tests in different *processes*).
+func RegisterTestingT(t types.GomegaTestingT) {
+	RegisterFailHandler(testingtsupport.BuildTestingTGomegaFailHandler(t))
+}
+
+//InterceptGomegaHandlers runs a given callback and returns an array of
+//failure messages generated by any Gomega assertions within the callback.
+//
+//This is accomplished by temporarily replacing the *global* fail handler
+//with a fail handler that simply annotates failures.  The original fail handler
+//is reset when InterceptGomegaFailures returns.
+//
+//This is most useful when testing custom matchers, but can also be used to check
+//on a value using a Gomega assertion without causing a test failure.
+func InterceptGomegaFailures(f func()) []string {
+	originalHandler := globalFailHandler
+	failures := []string{}
+	RegisterFailHandler(func(message string, callerSkip ...int) {
+		failures = append(failures, message)
+	})
+	f()
+	RegisterFailHandler(originalHandler)
+	return failures
+}
+
+//Ω wraps an actual value allowing assertions to be made on it:
+//	Ω("foo").Should(Equal("foo"))
+//
+//If Ω is passed more than one argument it will pass the *first* argument to the matcher.
+//All subsequent arguments will be required to be nil/zero.
+//
+//This is convenient if you want to make an assertion on a method/function that returns
+//a value and an error - a common patter in Go.
+//
+//For example, given a function with signature:
+//  func MyAmazingThing() (int, error)
+//
+//Then:
+//    Ω(MyAmazingThing()).Should(Equal(3))
+//Will succeed only if `MyAmazingThing()` returns `(3, nil)`
+//
+//Ω and Expect are identical
+func Ω(actual interface{}, extra ...interface{}) GomegaAssertion {
+	return ExpectWithOffset(0, actual, extra...)
+}
+
+//Expect wraps an actual value allowing assertions to be made on it:
+//	Expect("foo").To(Equal("foo"))
+//
+//If Expect is passed more than one argument it will pass the *first* argument to the matcher.
+//All subsequent arguments will be required to be nil/zero.
+//
+//This is convenient if you want to make an assertion on a method/function that returns
+//a value and an error - a common patter in Go.
+//
+//For example, given a function with signature:
+//  func MyAmazingThing() (int, error)
+//
+//Then:
+//    Expect(MyAmazingThing()).Should(Equal(3))
+//Will succeed only if `MyAmazingThing()` returns `(3, nil)`
+//
+//Expect and Ω are identical
+func Expect(actual interface{}, extra ...interface{}) GomegaAssertion {
+	return ExpectWithOffset(0, actual, extra...)
+}
+
+//ExpectWithOffset wraps an actual value allowing assertions to be made on it:
+//    ExpectWithOffset(1, "foo").To(Equal("foo"))
+//
+//Unlike `Expect` and `Ω`, `ExpectWithOffset` takes an additional integer argument
+//this is used to modify the call-stack offset when computing line numbers.
+//
+//This is most useful in helper functions that make assertions.  If you want Gomega's
+//error message to refer to the calling line in the test (as opposed to the line in the helper function)
+//set the first argument of `ExpectWithOffset` appropriately.
+func ExpectWithOffset(offset int, actual interface{}, extra ...interface{}) GomegaAssertion {
+	if globalFailHandler == nil {
+		panic(nilFailHandlerPanic)
+	}
+	return assertion.New(actual, globalFailHandler, offset, extra...)
+}
+
+//Eventually wraps an actual value allowing assertions to be made on it.
+//The assertion is tried periodically until it passes or a timeout occurs.
+//
+//Both the timeout and polling interval are configurable as optional arguments:
+//The first optional argument is the timeout
+//The second optional argument is the polling interval
+//
+//Both intervals can either be specified as time.Duration, parsable duration strings or as floats/integers.  In the
+//last case they are interpreted as seconds.
+//
+//If Eventually is passed an actual that is a function taking no arguments and returning at least one value,
+//then Eventually will call the function periodically and try the matcher against the function's first return value.
+//
+//Example:
+//
+//    Eventually(func() int {
+//        return thingImPolling.Count()
+//    }).Should(BeNumerically(">=", 17))
+//
+//Note that this example could be rewritten:
+//
+//    Eventually(thingImPolling.Count).Should(BeNumerically(">=", 17))
+//
+//If the function returns more than one value, then Eventually will pass the first value to the matcher and
+//assert that all other values are nil/zero.
+//This allows you to pass Eventually a function that returns a value and an error - a common pattern in Go.
+//
+//For example, consider a method that returns a value and an error:
+//    func FetchFromDB() (string, error)
+//
+//Then
+//    Eventually(FetchFromDB).Should(Equal("hasselhoff"))
+//
+//Will pass only if the the returned error is nil and the returned string passes the matcher.
+//
+//Eventually's default timeout is 1 second, and its default polling interval is 10ms
+func Eventually(actual interface{}, intervals ...interface{}) GomegaAsyncAssertion {
+	return EventuallyWithOffset(0, actual, intervals...)
+}
+
+//EventuallyWithOffset operates like Eventually but takes an additional
+//initial argument to indicate an offset in the call stack.  This is useful when building helper
+//functions that contain matchers.  To learn more, read about `ExpectWithOffset`.
+func EventuallyWithOffset(offset int, actual interface{}, intervals ...interface{}) GomegaAsyncAssertion {
+	if globalFailHandler == nil {
+		panic(nilFailHandlerPanic)
+	}
+	timeoutInterval := defaultEventuallyTimeout
+	pollingInterval := defaultEventuallyPollingInterval
+	if len(intervals) > 0 {
+		timeoutInterval = toDuration(intervals[0])
+	}
+	if len(intervals) > 1 {
+		pollingInterval = toDuration(intervals[1])
+	}
+	return asyncassertion.New(asyncassertion.AsyncAssertionTypeEventually, actual, globalFailHandler, timeoutInterval, pollingInterval, offset)
+}
+
+//Consistently wraps an actual value allowing assertions to be made on it.
+//The assertion is tried periodically and is required to pass for a period of time.
+//
+//Both the total time and polling interval are configurable as optional arguments:
+//The first optional argument is the duration that Consistently will run for
+//The second optional argument is the polling interval
+//
+//Both intervals can either be specified as time.Duration, parsable duration strings or as floats/integers.  In the
+//last case they are interpreted as seconds.
+//
+//If Consistently is passed an actual that is a function taking no arguments and returning at least one value,
+//then Consistently will call the function periodically and try the matcher against the function's first return value.
+//
+//If the function returns more than one value, then Consistently will pass the first value to the matcher and
+//assert that all other values are nil/zero.
+//This allows you to pass Consistently a function that returns a value and an error - a common pattern in Go.
+//
+//Consistently is useful in cases where you want to assert that something *does not happen* over a period of tiem.
+//For example, you want to assert that a goroutine does *not* send data down a channel.  In this case, you could:
+//
+//  Consistently(channel).ShouldNot(Receive())
+//
+//Consistently's default duration is 100ms, and its default polling interval is 10ms
+func Consistently(actual interface{}, intervals ...interface{}) GomegaAsyncAssertion {
+	return ConsistentlyWithOffset(0, actual, intervals...)
+}
+
+//ConsistentlyWithOffset operates like Consistnetly but takes an additional
+//initial argument to indicate an offset in the call stack.  This is useful when building helper
+//functions that contain matchers.  To learn more, read about `ExpectWithOffset`.
+func ConsistentlyWithOffset(offset int, actual interface{}, intervals ...interface{}) GomegaAsyncAssertion {
+	if globalFailHandler == nil {
+		panic(nilFailHandlerPanic)
+	}
+	timeoutInterval := defaultConsistentlyDuration
+	pollingInterval := defaultConsistentlyPollingInterval
+	if len(intervals) > 0 {
+		timeoutInterval = toDuration(intervals[0])
+	}
+	if len(intervals) > 1 {
+		pollingInterval = toDuration(intervals[1])
+	}
+	return asyncassertion.New(asyncassertion.AsyncAssertionTypeConsistently, actual, globalFailHandler, timeoutInterval, pollingInterval, offset)
+}
+
+//Set the default timeout duration for Eventually.  Eventually will repeatedly poll your condition until it succeeds, or until this timeout elapses.
+func SetDefaultEventuallyTimeout(t time.Duration) {
+	defaultEventuallyTimeout = t
+}
+
+//Set the default polling interval for Eventually.
+func SetDefaultEventuallyPollingInterval(t time.Duration) {
+	defaultEventuallyPollingInterval = t
+}
+
+//Set the default duration for Consistently.  Consistently will verify that your condition is satsified for this long.
+func SetDefaultConsistentlyDuration(t time.Duration) {
+	defaultConsistentlyDuration = t
+}
+
+//Set the default polling interval for Consistently.
+func SetDefaultConsistentlyPollingInterval(t time.Duration) {
+	defaultConsistentlyPollingInterval = t
+}
+
+//GomegaAsyncAssertion is returned by Eventually and Consistently and polls the actual value passed into Eventually against
+//the matcher passed to the Should and ShouldNot methods.
+//
+//Both Should and ShouldNot take a variadic optionalDescription argument.  This is passed on to
+//fmt.Sprintf() and is used to annotate failure messages.  This allows you to make your failure messages more
+//descriptive
+//
+//Both Should and ShouldNot return a boolean that is true if the assertion passed and false if it failed.
+//
+//Example:
+//
+//  Eventually(myChannel).Should(Receive(), "Something should have come down the pipe.")
+//  Consistently(myChannel).ShouldNot(Receive(), "Nothing should have come down the pipe.")
+type GomegaAsyncAssertion interface {
+	Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool
+	ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool
+}
+
+//GomegaAssertion is returned by Ω and Expect and compares the actual value to the matcher
+//passed to the Should/ShouldNot and To/ToNot/NotTo methods.
+//
+//Typically Should/ShouldNot are used with Ω and To/ToNot/NotTo are used with Expect
+//though this is not enforced.
+//
+//All methods take a variadic optionalDescription argument.  This is passed on to fmt.Sprintf()
+//and is used to annotate failure messages.
+//
+//All methods return a bool that is true if hte assertion passed and false if it failed.
+//
+//Example:
+//
+//   Ω(farm.HasCow()).Should(BeTrue(), "Farm %v should have a cow", farm)
+type GomegaAssertion interface {
+	Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool
+	ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool
+
+	To(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool
+	ToNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool
+	NotTo(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool
+}
+
+//OmegaMatcher is deprecated in favor of the better-named and better-organized types.GomegaMatcher but sticks around to support existing code that uses it
+type OmegaMatcher types.GomegaMatcher
+
+//GomegaWithT wraps a *testing.T and provides `Expect`, `Eventually`, and `Consistently` methods.  This allows you to leverage
+//Gomega's rich ecosystem of matchers in standard `testing` test suites.
+//
+//Use `NewGomegaWithT` to instantiate a `GomegaWithT`
+type GomegaWithT struct {
+	t types.GomegaTestingT
+}
+
+//NewGomegaWithT takes a *testing.T and returngs a `GomegaWithT` allowing you to use `Expect`, `Eventually`, and `Consistently` along with
+//Gomega's rich ecosystem of matchers in standard `testing` test suits.
+//
+// func TestFarmHasCow(t *testing.T) {
+//     g := GomegaWithT(t)
+//
+//	   f := farm.New([]string{"Cow", "Horse"})
+//     g.Expect(f.HasCow()).To(BeTrue(), "Farm should have cow")
+// }
+func NewGomegaWithT(t types.GomegaTestingT) *GomegaWithT {
+	return &GomegaWithT{
+		t: t,
+	}
+}
+
+//See documentation for Expect
+func (g *GomegaWithT) Expect(actual interface{}, extra ...interface{}) GomegaAssertion {
+	return assertion.New(actual, testingtsupport.BuildTestingTGomegaFailHandler(g.t), 0, extra...)
+}
+
+//See documentation for Eventually
+func (g *GomegaWithT) Eventually(actual interface{}, intervals ...interface{}) GomegaAsyncAssertion {
+	timeoutInterval := defaultEventuallyTimeout
+	pollingInterval := defaultEventuallyPollingInterval
+	if len(intervals) > 0 {
+		timeoutInterval = toDuration(intervals[0])
+	}
+	if len(intervals) > 1 {
+		pollingInterval = toDuration(intervals[1])
+	}
+	return asyncassertion.New(asyncassertion.AsyncAssertionTypeEventually, actual, testingtsupport.BuildTestingTGomegaFailHandler(g.t), timeoutInterval, pollingInterval, 0)
+}
+
+//See documentation for Consistently
+func (g *GomegaWithT) Consistently(actual interface{}, intervals ...interface{}) GomegaAsyncAssertion {
+	timeoutInterval := defaultConsistentlyDuration
+	pollingInterval := defaultConsistentlyPollingInterval
+	if len(intervals) > 0 {
+		timeoutInterval = toDuration(intervals[0])
+	}
+	if len(intervals) > 1 {
+		pollingInterval = toDuration(intervals[1])
+	}
+	return asyncassertion.New(asyncassertion.AsyncAssertionTypeConsistently, actual, testingtsupport.BuildTestingTGomegaFailHandler(g.t), timeoutInterval, pollingInterval, 0)
+}
+
+func toDuration(input interface{}) time.Duration {
+	duration, ok := input.(time.Duration)
+	if ok {
+		return duration
+	}
+
+	value := reflect.ValueOf(input)
+	kind := reflect.TypeOf(input).Kind()
+
+	if reflect.Int <= kind && kind <= reflect.Int64 {
+		return time.Duration(value.Int()) * time.Second
+	} else if reflect.Uint <= kind && kind <= reflect.Uint64 {
+		return time.Duration(value.Uint()) * time.Second
+	} else if reflect.Float32 <= kind && kind <= reflect.Float64 {
+		return time.Duration(value.Float() * float64(time.Second))
+	} else if reflect.String == kind {
+		duration, err := time.ParseDuration(value.String())
+		if err != nil {
+			panic(fmt.Sprintf("%#v is not a valid parsable duration string.", input))
+		}
+		return duration
+	}
+
+	panic(fmt.Sprintf("%v is not a valid interval.  Must be time.Duration, parsable duration string or a number.", input))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/internal/assertion/assertion.go b/metrics-server/vendor/github.com/onsi/gomega/internal/assertion/assertion.go
new file mode 100644
index 0000000..b73673f
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/internal/assertion/assertion.go
@@ -0,0 +1,98 @@
+package assertion
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/types"
+)
+
+type Assertion struct {
+	actualInput interface{}
+	fail        types.GomegaFailHandler
+	offset      int
+	extra       []interface{}
+}
+
+func New(actualInput interface{}, fail types.GomegaFailHandler, offset int, extra ...interface{}) *Assertion {
+	return &Assertion{
+		actualInput: actualInput,
+		fail:        fail,
+		offset:      offset,
+		extra:       extra,
+	}
+}
+
+func (assertion *Assertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
+	return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...)
+}
+
+func (assertion *Assertion) ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
+	return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
+}
+
+func (assertion *Assertion) To(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
+	return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...)
+}
+
+func (assertion *Assertion) ToNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
+	return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
+}
+
+func (assertion *Assertion) NotTo(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
+	return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
+}
+
+func (assertion *Assertion) buildDescription(optionalDescription ...interface{}) string {
+	switch len(optionalDescription) {
+	case 0:
+		return ""
+	default:
+		return fmt.Sprintf(optionalDescription[0].(string), optionalDescription[1:]...) + "\n"
+	}
+}
+
+func (assertion *Assertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool {
+	matches, err := matcher.Match(assertion.actualInput)
+	description := assertion.buildDescription(optionalDescription...)
+	if err != nil {
+		assertion.fail(description+err.Error(), 2+assertion.offset)
+		return false
+	}
+	if matches != desiredMatch {
+		var message string
+		if desiredMatch {
+			message = matcher.FailureMessage(assertion.actualInput)
+		} else {
+			message = matcher.NegatedFailureMessage(assertion.actualInput)
+		}
+		assertion.fail(description+message, 2+assertion.offset)
+		return false
+	}
+
+	return true
+}
+
+func (assertion *Assertion) vetExtras(optionalDescription ...interface{}) bool {
+	success, message := vetExtras(assertion.extra)
+	if success {
+		return true
+	}
+
+	description := assertion.buildDescription(optionalDescription...)
+	assertion.fail(description+message, 2+assertion.offset)
+	return false
+}
+
+func vetExtras(extras []interface{}) (bool, string) {
+	for i, extra := range extras {
+		if extra != nil {
+			zeroValue := reflect.Zero(reflect.TypeOf(extra)).Interface()
+			if !reflect.DeepEqual(zeroValue, extra) {
+				message := fmt.Sprintf("Unexpected non-nil/non-zero extra argument at index %d:\n\t<%T>: %#v", i+1, extra, extra)
+				return false, message
+			}
+		}
+	}
+	return true, ""
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/internal/asyncassertion/async_assertion.go b/metrics-server/vendor/github.com/onsi/gomega/internal/asyncassertion/async_assertion.go
new file mode 100644
index 0000000..bce0853
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/internal/asyncassertion/async_assertion.go
@@ -0,0 +1,189 @@
+package asyncassertion
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"time"
+
+	"github.com/onsi/gomega/internal/oraclematcher"
+	"github.com/onsi/gomega/types"
+)
+
+type AsyncAssertionType uint
+
+const (
+	AsyncAssertionTypeEventually AsyncAssertionType = iota
+	AsyncAssertionTypeConsistently
+)
+
+type AsyncAssertion struct {
+	asyncType       AsyncAssertionType
+	actualInput     interface{}
+	timeoutInterval time.Duration
+	pollingInterval time.Duration
+	fail            types.GomegaFailHandler
+	offset          int
+}
+
+func New(asyncType AsyncAssertionType, actualInput interface{}, fail types.GomegaFailHandler, timeoutInterval time.Duration, pollingInterval time.Duration, offset int) *AsyncAssertion {
+	actualType := reflect.TypeOf(actualInput)
+	if actualType.Kind() == reflect.Func {
+		if actualType.NumIn() != 0 || actualType.NumOut() == 0 {
+			panic("Expected a function with no arguments and one or more return values.")
+		}
+	}
+
+	return &AsyncAssertion{
+		asyncType:       asyncType,
+		actualInput:     actualInput,
+		fail:            fail,
+		timeoutInterval: timeoutInterval,
+		pollingInterval: pollingInterval,
+		offset:          offset,
+	}
+}
+
+func (assertion *AsyncAssertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
+	return assertion.match(matcher, true, optionalDescription...)
+}
+
+func (assertion *AsyncAssertion) ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
+	return assertion.match(matcher, false, optionalDescription...)
+}
+
+func (assertion *AsyncAssertion) buildDescription(optionalDescription ...interface{}) string {
+	switch len(optionalDescription) {
+	case 0:
+		return ""
+	default:
+		return fmt.Sprintf(optionalDescription[0].(string), optionalDescription[1:]...) + "\n"
+	}
+}
+
+func (assertion *AsyncAssertion) actualInputIsAFunction() bool {
+	actualType := reflect.TypeOf(assertion.actualInput)
+	return actualType.Kind() == reflect.Func && actualType.NumIn() == 0 && actualType.NumOut() > 0
+}
+
+func (assertion *AsyncAssertion) pollActual() (interface{}, error) {
+	if assertion.actualInputIsAFunction() {
+		values := reflect.ValueOf(assertion.actualInput).Call([]reflect.Value{})
+
+		extras := []interface{}{}
+		for _, value := range values[1:] {
+			extras = append(extras, value.Interface())
+		}
+
+		success, message := vetExtras(extras)
+
+		if !success {
+			return nil, errors.New(message)
+		}
+
+		return values[0].Interface(), nil
+	}
+
+	return assertion.actualInput, nil
+}
+
+func (assertion *AsyncAssertion) matcherMayChange(matcher types.GomegaMatcher, value interface{}) bool {
+	if assertion.actualInputIsAFunction() {
+		return true
+	}
+
+	return oraclematcher.MatchMayChangeInTheFuture(matcher, value)
+}
+
+func (assertion *AsyncAssertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool {
+	timer := time.Now()
+	timeout := time.After(assertion.timeoutInterval)
+
+	description := assertion.buildDescription(optionalDescription...)
+
+	var matches bool
+	var err error
+	mayChange := true
+	value, err := assertion.pollActual()
+	if err == nil {
+		mayChange = assertion.matcherMayChange(matcher, value)
+		matches, err = matcher.Match(value)
+	}
+
+	fail := func(preamble string) {
+		errMsg := ""
+		message := ""
+		if err != nil {
+			errMsg = "Error: " + err.Error()
+		} else {
+			if desiredMatch {
+				message = matcher.FailureMessage(value)
+			} else {
+				message = matcher.NegatedFailureMessage(value)
+			}
+		}
+		assertion.fail(fmt.Sprintf("%s after %.3fs.\n%s%s%s", preamble, time.Since(timer).Seconds(), description, message, errMsg), 3+assertion.offset)
+	}
+
+	if assertion.asyncType == AsyncAssertionTypeEventually {
+		for {
+			if err == nil && matches == desiredMatch {
+				return true
+			}
+
+			if !mayChange {
+				fail("No future change is possible.  Bailing out early")
+				return false
+			}
+
+			select {
+			case <-time.After(assertion.pollingInterval):
+				value, err = assertion.pollActual()
+				if err == nil {
+					mayChange = assertion.matcherMayChange(matcher, value)
+					matches, err = matcher.Match(value)
+				}
+			case <-timeout:
+				fail("Timed out")
+				return false
+			}
+		}
+	} else if assertion.asyncType == AsyncAssertionTypeConsistently {
+		for {
+			if !(err == nil && matches == desiredMatch) {
+				fail("Failed")
+				return false
+			}
+
+			if !mayChange {
+				return true
+			}
+
+			select {
+			case <-time.After(assertion.pollingInterval):
+				value, err = assertion.pollActual()
+				if err == nil {
+					mayChange = assertion.matcherMayChange(matcher, value)
+					matches, err = matcher.Match(value)
+				}
+			case <-timeout:
+				return true
+			}
+		}
+	}
+
+	return false
+}
+
+func vetExtras(extras []interface{}) (bool, string) {
+	for i, extra := range extras {
+		if extra != nil {
+			zeroValue := reflect.Zero(reflect.TypeOf(extra)).Interface()
+			if !reflect.DeepEqual(zeroValue, extra) {
+				message := fmt.Sprintf("Unexpected non-nil/non-zero extra argument at index %d:\n\t<%T>: %#v", i+1, extra, extra)
+				return false, message
+			}
+		}
+	}
+	return true, ""
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/internal/oraclematcher/oracle_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/internal/oraclematcher/oracle_matcher.go
new file mode 100644
index 0000000..66cad88
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/internal/oraclematcher/oracle_matcher.go
@@ -0,0 +1,25 @@
+package oraclematcher
+
+import "github.com/onsi/gomega/types"
+
+/*
+GomegaMatchers that also match the OracleMatcher interface can convey information about
+whether or not their result will change upon future attempts.
+
+This allows `Eventually` and `Consistently` to short circuit if success becomes impossible.
+
+For example, a process' exit code can never change.  So, gexec's Exit matcher returns `true`
+for `MatchMayChangeInTheFuture` until the process exits, at which point it returns `false` forevermore.
+*/
+type OracleMatcher interface {
+	MatchMayChangeInTheFuture(actual interface{}) bool
+}
+
+func MatchMayChangeInTheFuture(matcher types.GomegaMatcher, value interface{}) bool {
+	oracleMatcher, ok := matcher.(OracleMatcher)
+	if !ok {
+		return true
+	}
+
+	return oracleMatcher.MatchMayChangeInTheFuture(value)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/internal/testingtsupport/testing_t_support.go b/metrics-server/vendor/github.com/onsi/gomega/internal/testingtsupport/testing_t_support.go
new file mode 100644
index 0000000..ac89125
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/internal/testingtsupport/testing_t_support.go
@@ -0,0 +1,40 @@
+package testingtsupport
+
+import (
+	"regexp"
+	"runtime/debug"
+	"strings"
+
+	"github.com/onsi/gomega/types"
+)
+
+type gomegaTestingT interface {
+	Fatalf(format string, args ...interface{})
+}
+
+func BuildTestingTGomegaFailHandler(t gomegaTestingT) types.GomegaFailHandler {
+	return func(message string, callerSkip ...int) {
+		skip := 1
+		if len(callerSkip) > 0 {
+			skip = callerSkip[0]
+		}
+		stackTrace := pruneStack(string(debug.Stack()), skip)
+		t.Fatalf("\n%s\n%s", stackTrace, message)
+	}
+}
+
+func pruneStack(fullStackTrace string, skip int) string {
+	stack := strings.Split(fullStackTrace, "\n")
+	if len(stack) > 2*(skip+1) {
+		stack = stack[2*(skip+1):]
+	}
+	prunedStack := []string{}
+	re := regexp.MustCompile(`\/ginkgo\/|\/pkg\/testing\/|\/pkg\/runtime\/`)
+	for i := 0; i < len(stack)/2; i++ {
+		if !re.Match([]byte(stack[i*2])) {
+			prunedStack = append(prunedStack, stack[i*2])
+			prunedStack = append(prunedStack, stack[i*2+1])
+		}
+	}
+	return strings.Join(prunedStack, "\n")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers.go b/metrics-server/vendor/github.com/onsi/gomega/matchers.go
new file mode 100644
index 0000000..761ec33
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers.go
@@ -0,0 +1,427 @@
+package gomega
+
+import (
+	"time"
+
+	"github.com/onsi/gomega/matchers"
+	"github.com/onsi/gomega/types"
+)
+
+//Equal uses reflect.DeepEqual to compare actual with expected.  Equal is strict about
+//types when performing comparisons.
+//It is an error for both actual and expected to be nil.  Use BeNil() instead.
+func Equal(expected interface{}) types.GomegaMatcher {
+	return &matchers.EqualMatcher{
+		Expected: expected,
+	}
+}
+
+//BeEquivalentTo is more lax than Equal, allowing equality between different types.
+//This is done by converting actual to have the type of expected before
+//attempting equality with reflect.DeepEqual.
+//It is an error for actual and expected to be nil.  Use BeNil() instead.
+func BeEquivalentTo(expected interface{}) types.GomegaMatcher {
+	return &matchers.BeEquivalentToMatcher{
+		Expected: expected,
+	}
+}
+
+//BeIdenticalTo uses the == operator to compare actual with expected.
+//BeIdenticalTo is strict about types when performing comparisons.
+//It is an error for both actual and expected to be nil.  Use BeNil() instead.
+func BeIdenticalTo(expected interface{}) types.GomegaMatcher {
+	return &matchers.BeIdenticalToMatcher{
+		Expected: expected,
+	}
+}
+
+//BeNil succeeds if actual is nil
+func BeNil() types.GomegaMatcher {
+	return &matchers.BeNilMatcher{}
+}
+
+//BeTrue succeeds if actual is true
+func BeTrue() types.GomegaMatcher {
+	return &matchers.BeTrueMatcher{}
+}
+
+//BeFalse succeeds if actual is false
+func BeFalse() types.GomegaMatcher {
+	return &matchers.BeFalseMatcher{}
+}
+
+//HaveOccurred succeeds if actual is a non-nil error
+//The typical Go error checking pattern looks like:
+//    err := SomethingThatMightFail()
+//    Expect(err).ShouldNot(HaveOccurred())
+func HaveOccurred() types.GomegaMatcher {
+	return &matchers.HaveOccurredMatcher{}
+}
+
+//Succeed passes if actual is a nil error
+//Succeed is intended to be used with functions that return a single error value. Instead of
+//    err := SomethingThatMightFail()
+//    Expect(err).ShouldNot(HaveOccurred())
+//
+//You can write:
+//    Expect(SomethingThatMightFail()).Should(Succeed())
+//
+//It is a mistake to use Succeed with a function that has multiple return values.  Gomega's Ω and Expect
+//functions automatically trigger failure if any return values after the first return value are non-zero/non-nil.
+//This means that Ω(MultiReturnFunc()).ShouldNot(Succeed()) can never pass.
+func Succeed() types.GomegaMatcher {
+	return &matchers.SucceedMatcher{}
+}
+
+//MatchError succeeds if actual is a non-nil error that matches the passed in string/error.
+//
+//These are valid use-cases:
+//  Expect(err).Should(MatchError("an error")) //asserts that err.Error() == "an error"
+//  Expect(err).Should(MatchError(SomeError)) //asserts that err == SomeError (via reflect.DeepEqual)
+//
+//It is an error for err to be nil or an object that does not implement the Error interface
+func MatchError(expected interface{}) types.GomegaMatcher {
+	return &matchers.MatchErrorMatcher{
+		Expected: expected,
+	}
+}
+
+//BeClosed succeeds if actual is a closed channel.
+//It is an error to pass a non-channel to BeClosed, it is also an error to pass nil
+//
+//In order to check whether or not the channel is closed, Gomega must try to read from the channel
+//(even in the `ShouldNot(BeClosed())` case).  You should keep this in mind if you wish to make subsequent assertions about
+//values coming down the channel.
+//
+//Also, if you are testing that a *buffered* channel is closed you must first read all values out of the channel before
+//asserting that it is closed (it is not possible to detect that a buffered-channel has been closed until all its buffered values are read).
+//
+//Finally, as a corollary: it is an error to check whether or not a send-only channel is closed.
+func BeClosed() types.GomegaMatcher {
+	return &matchers.BeClosedMatcher{}
+}
+
+//Receive succeeds if there is a value to be received on actual.
+//Actual must be a channel (and cannot be a send-only channel) -- anything else is an error.
+//
+//Receive returns immediately and never blocks:
+//
+//- If there is nothing on the channel `c` then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass.
+//
+//- If the channel `c` is closed then Expect(c).Should(Receive()) will fail and Ω(c).ShouldNot(Receive()) will pass.
+//
+//- If there is something on the channel `c` ready to be read, then Expect(c).Should(Receive()) will pass and Ω(c).ShouldNot(Receive()) will fail.
+//
+//If you have a go-routine running in the background that will write to channel `c` you can:
+//    Eventually(c).Should(Receive())
+//
+//This will timeout if nothing gets sent to `c` (you can modify the timeout interval as you normally do with `Eventually`)
+//
+//A similar use-case is to assert that no go-routine writes to a channel (for a period of time).  You can do this with `Consistently`:
+//    Consistently(c).ShouldNot(Receive())
+//
+//You can pass `Receive` a matcher.  If you do so, it will match the received object against the matcher.  For example:
+//    Expect(c).Should(Receive(Equal("foo")))
+//
+//When given a matcher, `Receive` will always fail if there is nothing to be received on the channel.
+//
+//Passing Receive a matcher is especially useful when paired with Eventually:
+//
+//    Eventually(c).Should(Receive(ContainSubstring("bar")))
+//
+//will repeatedly attempt to pull values out of `c` until a value matching "bar" is received.
+//
+//Finally, if you want to have a reference to the value *sent* to the channel you can pass the `Receive` matcher a pointer to a variable of the appropriate type:
+//    var myThing thing
+//    Eventually(thingChan).Should(Receive(&myThing))
+//    Expect(myThing.Sprocket).Should(Equal("foo"))
+//    Expect(myThing.IsValid()).Should(BeTrue())
+func Receive(args ...interface{}) types.GomegaMatcher {
+	var arg interface{}
+	if len(args) > 0 {
+		arg = args[0]
+	}
+
+	return &matchers.ReceiveMatcher{
+		Arg: arg,
+	}
+}
+
+//BeSent succeeds if a value can be sent to actual.
+//Actual must be a channel (and cannot be a receive-only channel) that can sent the type of the value passed into BeSent -- anything else is an error.
+//In addition, actual must not be closed.
+//
+//BeSent never blocks:
+//
+//- If the channel `c` is not ready to receive then Expect(c).Should(BeSent("foo")) will fail immediately
+//- If the channel `c` is eventually ready to receive then Eventually(c).Should(BeSent("foo")) will succeed.. presuming the channel becomes ready to receive  before Eventually's timeout
+//- If the channel `c` is closed then Expect(c).Should(BeSent("foo")) and Ω(c).ShouldNot(BeSent("foo")) will both fail immediately
+//
+//Of course, the value is actually sent to the channel.  The point of `BeSent` is less to make an assertion about the availability of the channel (which is typically an implementation detail that your test should not be concerned with).
+//Rather, the point of `BeSent` is to make it possible to easily and expressively write tests that can timeout on blocked channel sends.
+func BeSent(arg interface{}) types.GomegaMatcher {
+	return &matchers.BeSentMatcher{
+		Arg: arg,
+	}
+}
+
+//MatchRegexp succeeds if actual is a string or stringer that matches the
+//passed-in regexp.  Optional arguments can be provided to construct a regexp
+//via fmt.Sprintf().
+func MatchRegexp(regexp string, args ...interface{}) types.GomegaMatcher {
+	return &matchers.MatchRegexpMatcher{
+		Regexp: regexp,
+		Args:   args,
+	}
+}
+
+//ContainSubstring succeeds if actual is a string or stringer that contains the
+//passed-in substring.  Optional arguments can be provided to construct the substring
+//via fmt.Sprintf().
+func ContainSubstring(substr string, args ...interface{}) types.GomegaMatcher {
+	return &matchers.ContainSubstringMatcher{
+		Substr: substr,
+		Args:   args,
+	}
+}
+
+//HavePrefix succeeds if actual is a string or stringer that contains the
+//passed-in string as a prefix.  Optional arguments can be provided to construct
+//via fmt.Sprintf().
+func HavePrefix(prefix string, args ...interface{}) types.GomegaMatcher {
+	return &matchers.HavePrefixMatcher{
+		Prefix: prefix,
+		Args:   args,
+	}
+}
+
+//HaveSuffix succeeds if actual is a string or stringer that contains the
+//passed-in string as a suffix.  Optional arguments can be provided to construct
+//via fmt.Sprintf().
+func HaveSuffix(suffix string, args ...interface{}) types.GomegaMatcher {
+	return &matchers.HaveSuffixMatcher{
+		Suffix: suffix,
+		Args:   args,
+	}
+}
+
+//MatchJSON succeeds if actual is a string or stringer of JSON that matches
+//the expected JSON.  The JSONs are decoded and the resulting objects are compared via
+//reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter.
+func MatchJSON(json interface{}) types.GomegaMatcher {
+	return &matchers.MatchJSONMatcher{
+		JSONToMatch: json,
+	}
+}
+
+//MatchXML succeeds if actual is a string or stringer of XML that matches
+//the expected XML.  The XMLs are decoded and the resulting objects are compared via
+//reflect.DeepEqual so things like whitespaces shouldn't matter.
+func MatchXML(xml interface{}) types.GomegaMatcher {
+	return &matchers.MatchXMLMatcher{
+		XMLToMatch: xml,
+	}
+}
+
+//MatchYAML succeeds if actual is a string or stringer of YAML that matches
+//the expected YAML.  The YAML's are decoded and the resulting objects are compared via
+//reflect.DeepEqual so things like key-ordering and whitespace shouldn't matter.
+func MatchYAML(yaml interface{}) types.GomegaMatcher {
+	return &matchers.MatchYAMLMatcher{
+		YAMLToMatch: yaml,
+	}
+}
+
+//BeEmpty succeeds if actual is empty.  Actual must be of type string, array, map, chan, or slice.
+func BeEmpty() types.GomegaMatcher {
+	return &matchers.BeEmptyMatcher{}
+}
+
+//HaveLen succeeds if actual has the passed-in length.  Actual must be of type string, array, map, chan, or slice.
+func HaveLen(count int) types.GomegaMatcher {
+	return &matchers.HaveLenMatcher{
+		Count: count,
+	}
+}
+
+//HaveCap succeeds if actual has the passed-in capacity.  Actual must be of type array, chan, or slice.
+func HaveCap(count int) types.GomegaMatcher {
+	return &matchers.HaveCapMatcher{
+		Count: count,
+	}
+}
+
+//BeZero succeeds if actual is the zero value for its type or if actual is nil.
+func BeZero() types.GomegaMatcher {
+	return &matchers.BeZeroMatcher{}
+}
+
+//ContainElement succeeds if actual contains the passed in element.
+//By default ContainElement() uses Equal() to perform the match, however a
+//matcher can be passed in instead:
+//    Expect([]string{"Foo", "FooBar"}).Should(ContainElement(ContainSubstring("Bar")))
+//
+//Actual must be an array, slice or map.
+//For maps, ContainElement searches through the map's values.
+func ContainElement(element interface{}) types.GomegaMatcher {
+	return &matchers.ContainElementMatcher{
+		Element: element,
+	}
+}
+
+//ConsistOf succeeds if actual contains precisely the elements passed into the matcher.  The ordering of the elements does not matter.
+//By default ConsistOf() uses Equal() to match the elements, however custom matchers can be passed in instead.  Here are some examples:
+//
+//    Expect([]string{"Foo", "FooBar"}).Should(ConsistOf("FooBar", "Foo"))
+//    Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Bar"), "Foo"))
+//    Expect([]string{"Foo", "FooBar"}).Should(ConsistOf(ContainSubstring("Foo"), ContainSubstring("Foo")))
+//
+//Actual must be an array, slice or map.  For maps, ConsistOf matches against the map's values.
+//
+//You typically pass variadic arguments to ConsistOf (as in the examples above).  However, if you need to pass in a slice you can provided that it
+//is the only element passed in to ConsistOf:
+//
+//    Expect([]string{"Foo", "FooBar"}).Should(ConsistOf([]string{"FooBar", "Foo"}))
+//
+//Note that Go's type system does not allow you to write this as ConsistOf([]string{"FooBar", "Foo"}...) as []string and []interface{} are different types - hence the need for this special rule.
+func ConsistOf(elements ...interface{}) types.GomegaMatcher {
+	return &matchers.ConsistOfMatcher{
+		Elements: elements,
+	}
+}
+
+//HaveKey succeeds if actual is a map with the passed in key.
+//By default HaveKey uses Equal() to perform the match, however a
+//matcher can be passed in instead:
+//    Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKey(MatchRegexp(`.+Foo$`)))
+func HaveKey(key interface{}) types.GomegaMatcher {
+	return &matchers.HaveKeyMatcher{
+		Key: key,
+	}
+}
+
+//HaveKeyWithValue succeeds if actual is a map with the passed in key and value.
+//By default HaveKeyWithValue uses Equal() to perform the match, however a
+//matcher can be passed in instead:
+//    Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue("Foo", "Bar"))
+//    Expect(map[string]string{"Foo": "Bar", "BazFoo": "Duck"}).Should(HaveKeyWithValue(MatchRegexp(`.+Foo$`), "Bar"))
+func HaveKeyWithValue(key interface{}, value interface{}) types.GomegaMatcher {
+	return &matchers.HaveKeyWithValueMatcher{
+		Key:   key,
+		Value: value,
+	}
+}
+
+//BeNumerically performs numerical assertions in a type-agnostic way.
+//Actual and expected should be numbers, though the specific type of
+//number is irrelevant (float32, float64, uint8, etc...).
+//
+//There are six, self-explanatory, supported comparators:
+//    Expect(1.0).Should(BeNumerically("==", 1))
+//    Expect(1.0).Should(BeNumerically("~", 0.999, 0.01))
+//    Expect(1.0).Should(BeNumerically(">", 0.9))
+//    Expect(1.0).Should(BeNumerically(">=", 1.0))
+//    Expect(1.0).Should(BeNumerically("<", 3))
+//    Expect(1.0).Should(BeNumerically("<=", 1.0))
+func BeNumerically(comparator string, compareTo ...interface{}) types.GomegaMatcher {
+	return &matchers.BeNumericallyMatcher{
+		Comparator: comparator,
+		CompareTo:  compareTo,
+	}
+}
+
+//BeTemporally compares time.Time's like BeNumerically
+//Actual and expected must be time.Time. The comparators are the same as for BeNumerically
+//    Expect(time.Now()).Should(BeTemporally(">", time.Time{}))
+//    Expect(time.Now()).Should(BeTemporally("~", time.Now(), time.Second))
+func BeTemporally(comparator string, compareTo time.Time, threshold ...time.Duration) types.GomegaMatcher {
+	return &matchers.BeTemporallyMatcher{
+		Comparator: comparator,
+		CompareTo:  compareTo,
+		Threshold:  threshold,
+	}
+}
+
+//BeAssignableToTypeOf succeeds if actual is assignable to the type of expected.
+//It will return an error when one of the values is nil.
+//	  Expect(0).Should(BeAssignableToTypeOf(0))         // Same values
+//	  Expect(5).Should(BeAssignableToTypeOf(-1))        // different values same type
+//	  Expect("foo").Should(BeAssignableToTypeOf("bar")) // different values same type
+//    Expect(struct{ Foo string }{}).Should(BeAssignableToTypeOf(struct{ Foo string }{}))
+func BeAssignableToTypeOf(expected interface{}) types.GomegaMatcher {
+	return &matchers.AssignableToTypeOfMatcher{
+		Expected: expected,
+	}
+}
+
+//Panic succeeds if actual is a function that, when invoked, panics.
+//Actual must be a function that takes no arguments and returns no results.
+func Panic() types.GomegaMatcher {
+	return &matchers.PanicMatcher{}
+}
+
+//BeAnExistingFile succeeds if a file exists.
+//Actual must be a string representing the abs path to the file being checked.
+func BeAnExistingFile() types.GomegaMatcher {
+	return &matchers.BeAnExistingFileMatcher{}
+}
+
+//BeARegularFile succeeds if a file exists and is a regular file.
+//Actual must be a string representing the abs path to the file being checked.
+func BeARegularFile() types.GomegaMatcher {
+	return &matchers.BeARegularFileMatcher{}
+}
+
+//BeADirectory succeeds if a file exists and is a directory.
+//Actual must be a string representing the abs path to the file being checked.
+func BeADirectory() types.GomegaMatcher {
+	return &matchers.BeADirectoryMatcher{}
+}
+
+//And succeeds only if all of the given matchers succeed.
+//The matchers are tried in order, and will fail-fast if one doesn't succeed.
+//  Expect("hi").To(And(HaveLen(2), Equal("hi"))
+//
+//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
+func And(ms ...types.GomegaMatcher) types.GomegaMatcher {
+	return &matchers.AndMatcher{Matchers: ms}
+}
+
+//SatisfyAll is an alias for And().
+//  Expect("hi").Should(SatisfyAll(HaveLen(2), Equal("hi")))
+func SatisfyAll(matchers ...types.GomegaMatcher) types.GomegaMatcher {
+	return And(matchers...)
+}
+
+//Or succeeds if any of the given matchers succeed.
+//The matchers are tried in order and will return immediately upon the first successful match.
+//  Expect("hi").To(Or(HaveLen(3), HaveLen(2))
+//
+//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
+func Or(ms ...types.GomegaMatcher) types.GomegaMatcher {
+	return &matchers.OrMatcher{Matchers: ms}
+}
+
+//SatisfyAny is an alias for Or().
+//  Expect("hi").SatisfyAny(Or(HaveLen(3), HaveLen(2))
+func SatisfyAny(matchers ...types.GomegaMatcher) types.GomegaMatcher {
+	return Or(matchers...)
+}
+
+//Not negates the given matcher; it succeeds if the given matcher fails.
+//  Expect(1).To(Not(Equal(2))
+//
+//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
+func Not(matcher types.GomegaMatcher) types.GomegaMatcher {
+	return &matchers.NotMatcher{Matcher: matcher}
+}
+
+//WithTransform applies the `transform` to the actual value and matches it against `matcher`.
+//The given transform must be a function of one parameter that returns one value.
+//  var plus1 = func(i int) int { return i + 1 }
+//  Expect(1).To(WithTransform(plus1, Equal(2))
+//
+//And(), Or(), Not() and WithTransform() allow matchers to be composed into complex expressions.
+func WithTransform(transform interface{}, matcher types.GomegaMatcher) types.GomegaMatcher {
+	return matchers.NewWithTransformMatcher(transform, matcher)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/and.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/and.go
new file mode 100644
index 0000000..d83a291
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/and.go
@@ -0,0 +1,63 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+	"github.com/onsi/gomega/internal/oraclematcher"
+	"github.com/onsi/gomega/types"
+)
+
+type AndMatcher struct {
+	Matchers []types.GomegaMatcher
+
+	// state
+	firstFailedMatcher types.GomegaMatcher
+}
+
+func (m *AndMatcher) Match(actual interface{}) (success bool, err error) {
+	m.firstFailedMatcher = nil
+	for _, matcher := range m.Matchers {
+		success, err := matcher.Match(actual)
+		if !success || err != nil {
+			m.firstFailedMatcher = matcher
+			return false, err
+		}
+	}
+	return true, nil
+}
+
+func (m *AndMatcher) FailureMessage(actual interface{}) (message string) {
+	return m.firstFailedMatcher.FailureMessage(actual)
+}
+
+func (m *AndMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	// not the most beautiful list of matchers, but not bad either...
+	return format.Message(actual, fmt.Sprintf("To not satisfy all of these matchers: %s", m.Matchers))
+}
+
+func (m *AndMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	/*
+		Example with 3 matchers: A, B, C
+
+		Match evaluates them: T, F, <?>  => F
+		So match is currently F, what should MatchMayChangeInTheFuture() return?
+		Seems like it only depends on B, since currently B MUST change to allow the result to become T
+
+		Match eval: T, T, T  => T
+		So match is currently T, what should MatchMayChangeInTheFuture() return?
+		Seems to depend on ANY of them being able to change to F.
+	*/
+
+	if m.firstFailedMatcher == nil {
+		// so all matchers succeeded.. Any one of them changing would change the result.
+		for _, matcher := range m.Matchers {
+			if oraclematcher.MatchMayChangeInTheFuture(matcher, actual) {
+				return true
+			}
+		}
+		return false // none of were going to change
+	}
+	// one of the matchers failed.. it must be able to change in order to affect the result
+	return oraclematcher.MatchMayChangeInTheFuture(m.firstFailedMatcher, actual)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go
new file mode 100644
index 0000000..51f8be6
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/assignable_to_type_of_matcher.go
@@ -0,0 +1,35 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type AssignableToTypeOfMatcher struct {
+	Expected interface{}
+}
+
+func (matcher *AssignableToTypeOfMatcher) Match(actual interface{}) (success bool, err error) {
+	if actual == nil && matcher.Expected == nil {
+		return false, fmt.Errorf("Refusing to compare <nil> to <nil>.\nBe explicit and use BeNil() instead.  This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.")
+	} else if matcher.Expected == nil {
+		return false, fmt.Errorf("Refusing to compare type to <nil>.\nBe explicit and use BeNil() instead.  This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.")
+	} else if actual == nil {
+		return false, nil
+	}
+
+	actualType := reflect.TypeOf(actual)
+	expectedType := reflect.TypeOf(matcher.Expected)
+
+	return actualType.AssignableTo(expectedType), nil
+}
+
+func (matcher *AssignableToTypeOfMatcher) FailureMessage(actual interface{}) string {
+	return format.Message(actual, fmt.Sprintf("to be assignable to the type: %T", matcher.Expected))
+}
+
+func (matcher *AssignableToTypeOfMatcher) NegatedFailureMessage(actual interface{}) string {
+	return format.Message(actual, fmt.Sprintf("not to be assignable to the type: %T", matcher.Expected))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/attributes_slice.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/attributes_slice.go
new file mode 100644
index 0000000..355b362
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/attributes_slice.go
@@ -0,0 +1,14 @@
+package matchers
+
+import (
+	"encoding/xml"
+	"strings"
+)
+
+type attributesSlice []xml.Attr
+
+func (attrs attributesSlice) Len() int { return len(attrs) }
+func (attrs attributesSlice) Less(i, j int) bool {
+	return strings.Compare(attrs[i].Name.Local, attrs[j].Name.Local) == -1
+}
+func (attrs attributesSlice) Swap(i, j int) { attrs[i], attrs[j] = attrs[j], attrs[i] }
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_directory.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_directory.go
new file mode 100644
index 0000000..7b6975e
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_directory.go
@@ -0,0 +1,54 @@
+package matchers
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/onsi/gomega/format"
+)
+
+type notADirectoryError struct {
+	os.FileInfo
+}
+
+func (t notADirectoryError) Error() string {
+	fileInfo := os.FileInfo(t)
+	switch {
+	case fileInfo.Mode().IsRegular():
+		return "file is a regular file"
+	default:
+		return fmt.Sprintf("file mode is: %s", fileInfo.Mode().String())
+	}
+}
+
+type BeADirectoryMatcher struct {
+	expected interface{}
+	err      error
+}
+
+func (matcher *BeADirectoryMatcher) Match(actual interface{}) (success bool, err error) {
+	actualFilename, ok := actual.(string)
+	if !ok {
+		return false, fmt.Errorf("BeADirectoryMatcher matcher expects a file path")
+	}
+
+	fileInfo, err := os.Stat(actualFilename)
+	if err != nil {
+		matcher.err = err
+		return false, nil
+	}
+
+	if !fileInfo.Mode().IsDir() {
+		matcher.err = notADirectoryError{fileInfo}
+		return false, nil
+	}
+	return true, nil
+}
+
+func (matcher *BeADirectoryMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("to be a directory: %s", matcher.err))
+}
+
+func (matcher *BeADirectoryMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not be a directory"))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go
new file mode 100644
index 0000000..e239131
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_a_regular_file.go
@@ -0,0 +1,54 @@
+package matchers
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/onsi/gomega/format"
+)
+
+type notARegularFileError struct {
+	os.FileInfo
+}
+
+func (t notARegularFileError) Error() string {
+	fileInfo := os.FileInfo(t)
+	switch {
+	case fileInfo.IsDir():
+		return "file is a directory"
+	default:
+		return fmt.Sprintf("file mode is: %s", fileInfo.Mode().String())
+	}
+}
+
+type BeARegularFileMatcher struct {
+	expected interface{}
+	err      error
+}
+
+func (matcher *BeARegularFileMatcher) Match(actual interface{}) (success bool, err error) {
+	actualFilename, ok := actual.(string)
+	if !ok {
+		return false, fmt.Errorf("BeARegularFileMatcher matcher expects a file path")
+	}
+
+	fileInfo, err := os.Stat(actualFilename)
+	if err != nil {
+		matcher.err = err
+		return false, nil
+	}
+
+	if !fileInfo.Mode().IsRegular() {
+		matcher.err = notARegularFileError{fileInfo}
+		return false, nil
+	}
+	return true, nil
+}
+
+func (matcher *BeARegularFileMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("to be a regular file: %s", matcher.err))
+}
+
+func (matcher *BeARegularFileMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not be a regular file"))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go
new file mode 100644
index 0000000..d42eba2
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_an_existing_file.go
@@ -0,0 +1,38 @@
+package matchers
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeAnExistingFileMatcher struct {
+	expected interface{}
+}
+
+func (matcher *BeAnExistingFileMatcher) Match(actual interface{}) (success bool, err error) {
+	actualFilename, ok := actual.(string)
+	if !ok {
+		return false, fmt.Errorf("BeAnExistingFileMatcher matcher expects a file path")
+	}
+
+	if _, err = os.Stat(actualFilename); err != nil {
+		switch {
+		case os.IsNotExist(err):
+			return false, nil
+		default:
+			return false, err
+		}
+	}
+
+	return true, nil
+}
+
+func (matcher *BeAnExistingFileMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("to exist"))
+}
+
+func (matcher *BeAnExistingFileMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not to exist"))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go
new file mode 100644
index 0000000..ed6f692
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_closed_matcher.go
@@ -0,0 +1,46 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeClosedMatcher struct {
+}
+
+func (matcher *BeClosedMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isChan(actual) {
+		return false, fmt.Errorf("BeClosed matcher expects a channel.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	channelType := reflect.TypeOf(actual)
+	channelValue := reflect.ValueOf(actual)
+
+	if channelType.ChanDir() == reflect.SendDir {
+		return false, fmt.Errorf("BeClosed matcher cannot determine if a send-only channel is closed or open.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	winnerIndex, _, open := reflect.Select([]reflect.SelectCase{
+		reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue},
+		reflect.SelectCase{Dir: reflect.SelectDefault},
+	})
+
+	var closed bool
+	if winnerIndex == 0 {
+		closed = !open
+	} else if winnerIndex == 1 {
+		closed = false
+	}
+
+	return closed, nil
+}
+
+func (matcher *BeClosedMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be closed")
+}
+
+func (matcher *BeClosedMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be open")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go
new file mode 100644
index 0000000..8b00311
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_empty_matcher.go
@@ -0,0 +1,27 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeEmptyMatcher struct {
+}
+
+func (matcher *BeEmptyMatcher) Match(actual interface{}) (success bool, err error) {
+	length, ok := lengthOf(actual)
+	if !ok {
+		return false, fmt.Errorf("BeEmpty matcher expects a string/array/map/channel/slice.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return length == 0, nil
+}
+
+func (matcher *BeEmptyMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be empty")
+}
+
+func (matcher *BeEmptyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be empty")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go
new file mode 100644
index 0000000..97ab20a
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_equivalent_to_matcher.go
@@ -0,0 +1,34 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeEquivalentToMatcher struct {
+	Expected interface{}
+}
+
+func (matcher *BeEquivalentToMatcher) Match(actual interface{}) (success bool, err error) {
+	if actual == nil && matcher.Expected == nil {
+		return false, fmt.Errorf("Both actual and expected must not be nil.")
+	}
+
+	convertedActual := actual
+
+	if actual != nil && matcher.Expected != nil && reflect.TypeOf(actual).ConvertibleTo(reflect.TypeOf(matcher.Expected)) {
+		convertedActual = reflect.ValueOf(actual).Convert(reflect.TypeOf(matcher.Expected)).Interface()
+	}
+
+	return reflect.DeepEqual(convertedActual, matcher.Expected), nil
+}
+
+func (matcher *BeEquivalentToMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be equivalent to", matcher.Expected)
+}
+
+func (matcher *BeEquivalentToMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be equivalent to", matcher.Expected)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go
new file mode 100644
index 0000000..91d3b77
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_false_matcher.go
@@ -0,0 +1,26 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeFalseMatcher struct {
+}
+
+func (matcher *BeFalseMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isBool(actual) {
+		return false, fmt.Errorf("Expected a boolean.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return actual == false, nil
+}
+
+func (matcher *BeFalseMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be false")
+}
+
+func (matcher *BeFalseMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be false")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_identical_to.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_identical_to.go
new file mode 100644
index 0000000..fdcda4d
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_identical_to.go
@@ -0,0 +1,37 @@
+package matchers
+
+import (
+	"fmt"
+	"runtime"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeIdenticalToMatcher struct {
+	Expected interface{}
+}
+
+func (matcher *BeIdenticalToMatcher) Match(actual interface{}) (success bool, matchErr error) {
+	if actual == nil && matcher.Expected == nil {
+		return false, fmt.Errorf("Refusing to compare <nil> to <nil>.\nBe explicit and use BeNil() instead.  This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.")
+	}
+
+	defer func() {
+		if r := recover(); r != nil {
+			if _, ok := r.(runtime.Error); ok {
+				success = false
+				matchErr = nil
+			}
+		}
+	}()
+
+	return actual == matcher.Expected, nil
+}
+
+func (matcher *BeIdenticalToMatcher) FailureMessage(actual interface{}) string {
+	return format.Message(actual, "to be identical to", matcher.Expected)
+}
+
+func (matcher *BeIdenticalToMatcher) NegatedFailureMessage(actual interface{}) string {
+	return format.Message(actual, "not to be identical to", matcher.Expected)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go
new file mode 100644
index 0000000..7ee84fe
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_nil_matcher.go
@@ -0,0 +1,18 @@
+package matchers
+
+import "github.com/onsi/gomega/format"
+
+type BeNilMatcher struct {
+}
+
+func (matcher *BeNilMatcher) Match(actual interface{}) (success bool, err error) {
+	return isNil(actual), nil
+}
+
+func (matcher *BeNilMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be nil")
+}
+
+func (matcher *BeNilMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be nil")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go
new file mode 100644
index 0000000..0c157f6
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_numerically_matcher.go
@@ -0,0 +1,120 @@
+package matchers
+
+import (
+	"fmt"
+	"math"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeNumericallyMatcher struct {
+	Comparator string
+	CompareTo  []interface{}
+}
+
+func (matcher *BeNumericallyMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("to be %s", matcher.Comparator), matcher.CompareTo[0])
+}
+
+func (matcher *BeNumericallyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not to be %s", matcher.Comparator), matcher.CompareTo[0])
+}
+
+func (matcher *BeNumericallyMatcher) Match(actual interface{}) (success bool, err error) {
+	if len(matcher.CompareTo) == 0 || len(matcher.CompareTo) > 2 {
+		return false, fmt.Errorf("BeNumerically requires 1 or 2 CompareTo arguments.  Got:\n%s", format.Object(matcher.CompareTo, 1))
+	}
+	if !isNumber(actual) {
+		return false, fmt.Errorf("Expected a number.  Got:\n%s", format.Object(actual, 1))
+	}
+	if !isNumber(matcher.CompareTo[0]) {
+		return false, fmt.Errorf("Expected a number.  Got:\n%s", format.Object(matcher.CompareTo[0], 1))
+	}
+	if len(matcher.CompareTo) == 2 && !isNumber(matcher.CompareTo[1]) {
+		return false, fmt.Errorf("Expected a number.  Got:\n%s", format.Object(matcher.CompareTo[0], 1))
+	}
+
+	switch matcher.Comparator {
+	case "==", "~", ">", ">=", "<", "<=":
+	default:
+		return false, fmt.Errorf("Unknown comparator: %s", matcher.Comparator)
+	}
+
+	if isFloat(actual) || isFloat(matcher.CompareTo[0]) {
+		var secondOperand float64 = 1e-8
+		if len(matcher.CompareTo) == 2 {
+			secondOperand = toFloat(matcher.CompareTo[1])
+		}
+		success = matcher.matchFloats(toFloat(actual), toFloat(matcher.CompareTo[0]), secondOperand)
+	} else if isInteger(actual) {
+		var secondOperand int64 = 0
+		if len(matcher.CompareTo) == 2 {
+			secondOperand = toInteger(matcher.CompareTo[1])
+		}
+		success = matcher.matchIntegers(toInteger(actual), toInteger(matcher.CompareTo[0]), secondOperand)
+	} else if isUnsignedInteger(actual) {
+		var secondOperand uint64 = 0
+		if len(matcher.CompareTo) == 2 {
+			secondOperand = toUnsignedInteger(matcher.CompareTo[1])
+		}
+		success = matcher.matchUnsignedIntegers(toUnsignedInteger(actual), toUnsignedInteger(matcher.CompareTo[0]), secondOperand)
+	} else {
+		return false, fmt.Errorf("Failed to compare:\n%s\n%s:\n%s", format.Object(actual, 1), matcher.Comparator, format.Object(matcher.CompareTo[0], 1))
+	}
+
+	return success, nil
+}
+
+func (matcher *BeNumericallyMatcher) matchIntegers(actual, compareTo, threshold int64) (success bool) {
+	switch matcher.Comparator {
+	case "==", "~":
+		diff := actual - compareTo
+		return -threshold <= diff && diff <= threshold
+	case ">":
+		return (actual > compareTo)
+	case ">=":
+		return (actual >= compareTo)
+	case "<":
+		return (actual < compareTo)
+	case "<=":
+		return (actual <= compareTo)
+	}
+	return false
+}
+
+func (matcher *BeNumericallyMatcher) matchUnsignedIntegers(actual, compareTo, threshold uint64) (success bool) {
+	switch matcher.Comparator {
+	case "==", "~":
+		if actual < compareTo {
+			actual, compareTo = compareTo, actual
+		}
+		return actual-compareTo <= threshold
+	case ">":
+		return (actual > compareTo)
+	case ">=":
+		return (actual >= compareTo)
+	case "<":
+		return (actual < compareTo)
+	case "<=":
+		return (actual <= compareTo)
+	}
+	return false
+}
+
+func (matcher *BeNumericallyMatcher) matchFloats(actual, compareTo, threshold float64) (success bool) {
+	switch matcher.Comparator {
+	case "~":
+		return math.Abs(actual-compareTo) <= threshold
+	case "==":
+		return (actual == compareTo)
+	case ">":
+		return (actual > compareTo)
+	case ">=":
+		return (actual >= compareTo)
+	case "<":
+		return (actual < compareTo)
+	case "<=":
+		return (actual <= compareTo)
+	}
+	return false
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go
new file mode 100644
index 0000000..d7c3223
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_sent_matcher.go
@@ -0,0 +1,71 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeSentMatcher struct {
+	Arg           interface{}
+	channelClosed bool
+}
+
+func (matcher *BeSentMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isChan(actual) {
+		return false, fmt.Errorf("BeSent expects a channel.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	channelType := reflect.TypeOf(actual)
+	channelValue := reflect.ValueOf(actual)
+
+	if channelType.ChanDir() == reflect.RecvDir {
+		return false, fmt.Errorf("BeSent matcher cannot be passed a receive-only channel.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	argType := reflect.TypeOf(matcher.Arg)
+	assignable := argType.AssignableTo(channelType.Elem())
+
+	if !assignable {
+		return false, fmt.Errorf("Cannot pass:\n%s to the channel:\n%s\nThe types don't match.", format.Object(matcher.Arg, 1), format.Object(actual, 1))
+	}
+
+	argValue := reflect.ValueOf(matcher.Arg)
+
+	defer func() {
+		if e := recover(); e != nil {
+			success = false
+			err = fmt.Errorf("Cannot send to a closed channel")
+			matcher.channelClosed = true
+		}
+	}()
+
+	winnerIndex, _, _ := reflect.Select([]reflect.SelectCase{
+		reflect.SelectCase{Dir: reflect.SelectSend, Chan: channelValue, Send: argValue},
+		reflect.SelectCase{Dir: reflect.SelectDefault},
+	})
+
+	var didSend bool
+	if winnerIndex == 0 {
+		didSend = true
+	}
+
+	return didSend, nil
+}
+
+func (matcher *BeSentMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to send:", matcher.Arg)
+}
+
+func (matcher *BeSentMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to send:", matcher.Arg)
+}
+
+func (matcher *BeSentMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	if !isChan(actual) {
+		return false
+	}
+
+	return !matcher.channelClosed
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go
new file mode 100644
index 0000000..cb7c038
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_temporally_matcher.go
@@ -0,0 +1,66 @@
+package matchers
+
+import (
+	"fmt"
+	"time"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeTemporallyMatcher struct {
+	Comparator string
+	CompareTo  time.Time
+	Threshold  []time.Duration
+}
+
+func (matcher *BeTemporallyMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("to be %s", matcher.Comparator), matcher.CompareTo)
+}
+
+func (matcher *BeTemporallyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not to be %s", matcher.Comparator), matcher.CompareTo)
+}
+
+func (matcher *BeTemporallyMatcher) Match(actual interface{}) (bool, error) {
+	// predicate to test for time.Time type
+	isTime := func(t interface{}) bool {
+		_, ok := t.(time.Time)
+		return ok
+	}
+
+	if !isTime(actual) {
+		return false, fmt.Errorf("Expected a time.Time.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	switch matcher.Comparator {
+	case "==", "~", ">", ">=", "<", "<=":
+	default:
+		return false, fmt.Errorf("Unknown comparator: %s", matcher.Comparator)
+	}
+
+	var threshold = time.Millisecond
+	if len(matcher.Threshold) == 1 {
+		threshold = matcher.Threshold[0]
+	}
+
+	return matcher.matchTimes(actual.(time.Time), matcher.CompareTo, threshold), nil
+}
+
+func (matcher *BeTemporallyMatcher) matchTimes(actual, compareTo time.Time, threshold time.Duration) (success bool) {
+	switch matcher.Comparator {
+	case "==":
+		return actual.Equal(compareTo)
+	case "~":
+		diff := actual.Sub(compareTo)
+		return -threshold <= diff && diff <= threshold
+	case ">":
+		return actual.After(compareTo)
+	case ">=":
+		return !actual.Before(compareTo)
+	case "<":
+		return actual.Before(compareTo)
+	case "<=":
+		return !actual.After(compareTo)
+	}
+	return false
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go
new file mode 100644
index 0000000..ec57c5d
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_true_matcher.go
@@ -0,0 +1,26 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeTrueMatcher struct {
+}
+
+func (matcher *BeTrueMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isBool(actual) {
+		return false, fmt.Errorf("Expected a boolean.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return actual.(bool), nil
+}
+
+func (matcher *BeTrueMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be true")
+}
+
+func (matcher *BeTrueMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be true")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go
new file mode 100644
index 0000000..26196f1
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/be_zero_matcher.go
@@ -0,0 +1,28 @@
+package matchers
+
+import (
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type BeZeroMatcher struct {
+}
+
+func (matcher *BeZeroMatcher) Match(actual interface{}) (success bool, err error) {
+	if actual == nil {
+		return true, nil
+	}
+	zeroValue := reflect.Zero(reflect.TypeOf(actual)).Interface()
+
+	return reflect.DeepEqual(zeroValue, actual), nil
+
+}
+
+func (matcher *BeZeroMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to be zero-valued")
+}
+
+func (matcher *BeZeroMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to be zero-valued")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/consist_of.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/consist_of.go
new file mode 100644
index 0000000..7b0e088
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/consist_of.go
@@ -0,0 +1,80 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+	"github.com/onsi/gomega/matchers/support/goraph/bipartitegraph"
+)
+
+type ConsistOfMatcher struct {
+	Elements []interface{}
+}
+
+func (matcher *ConsistOfMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isArrayOrSlice(actual) && !isMap(actual) {
+		return false, fmt.Errorf("ConsistOf matcher expects an array/slice/map.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	elements := matcher.Elements
+	if len(matcher.Elements) == 1 && isArrayOrSlice(matcher.Elements[0]) {
+		elements = []interface{}{}
+		value := reflect.ValueOf(matcher.Elements[0])
+		for i := 0; i < value.Len(); i++ {
+			elements = append(elements, value.Index(i).Interface())
+		}
+	}
+
+	matchers := []interface{}{}
+	for _, element := range elements {
+		matcher, isMatcher := element.(omegaMatcher)
+		if !isMatcher {
+			matcher = &EqualMatcher{Expected: element}
+		}
+		matchers = append(matchers, matcher)
+	}
+
+	values := matcher.valuesOf(actual)
+
+	if len(values) != len(matchers) {
+		return false, nil
+	}
+
+	neighbours := func(v, m interface{}) (bool, error) {
+		match, err := m.(omegaMatcher).Match(v)
+		return match && err == nil, nil
+	}
+
+	bipartiteGraph, err := bipartitegraph.NewBipartiteGraph(values, matchers, neighbours)
+	if err != nil {
+		return false, err
+	}
+
+	return len(bipartiteGraph.LargestMatching()) == len(values), nil
+}
+
+func (matcher *ConsistOfMatcher) valuesOf(actual interface{}) []interface{} {
+	value := reflect.ValueOf(actual)
+	values := []interface{}{}
+	if isMap(actual) {
+		keys := value.MapKeys()
+		for i := 0; i < value.Len(); i++ {
+			values = append(values, value.MapIndex(keys[i]).Interface())
+		}
+	} else {
+		for i := 0; i < value.Len(); i++ {
+			values = append(values, value.Index(i).Interface())
+		}
+	}
+
+	return values
+}
+
+func (matcher *ConsistOfMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to consist of", matcher.Elements)
+}
+
+func (matcher *ConsistOfMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to consist of", matcher.Elements)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go
new file mode 100644
index 0000000..4159335
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_element_matcher.go
@@ -0,0 +1,56 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type ContainElementMatcher struct {
+	Element interface{}
+}
+
+func (matcher *ContainElementMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isArrayOrSlice(actual) && !isMap(actual) {
+		return false, fmt.Errorf("ContainElement matcher expects an array/slice/map.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	elemMatcher, elementIsMatcher := matcher.Element.(omegaMatcher)
+	if !elementIsMatcher {
+		elemMatcher = &EqualMatcher{Expected: matcher.Element}
+	}
+
+	value := reflect.ValueOf(actual)
+	var keys []reflect.Value
+	if isMap(actual) {
+		keys = value.MapKeys()
+	}
+	var lastError error
+	for i := 0; i < value.Len(); i++ {
+		var success bool
+		var err error
+		if isMap(actual) {
+			success, err = elemMatcher.Match(value.MapIndex(keys[i]).Interface())
+		} else {
+			success, err = elemMatcher.Match(value.Index(i).Interface())
+		}
+		if err != nil {
+			lastError = err
+			continue
+		}
+		if success {
+			return true, nil
+		}
+	}
+
+	return false, lastError
+}
+
+func (matcher *ContainElementMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to contain element matching", matcher.Element)
+}
+
+func (matcher *ContainElementMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to contain element matching", matcher.Element)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go
new file mode 100644
index 0000000..f8dc41e
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/contain_substring_matcher.go
@@ -0,0 +1,38 @@
+package matchers
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/onsi/gomega/format"
+)
+
+type ContainSubstringMatcher struct {
+	Substr string
+	Args   []interface{}
+}
+
+func (matcher *ContainSubstringMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return false, fmt.Errorf("ContainSubstring matcher requires a string or stringer.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return strings.Contains(actualString, matcher.stringToMatch()), nil
+}
+
+func (matcher *ContainSubstringMatcher) stringToMatch() string {
+	stringToMatch := matcher.Substr
+	if len(matcher.Args) > 0 {
+		stringToMatch = fmt.Sprintf(matcher.Substr, matcher.Args...)
+	}
+	return stringToMatch
+}
+
+func (matcher *ContainSubstringMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to contain substring", matcher.stringToMatch())
+}
+
+func (matcher *ContainSubstringMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to contain substring", matcher.stringToMatch())
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/equal_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/equal_matcher.go
new file mode 100644
index 0000000..befb7bd
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/equal_matcher.go
@@ -0,0 +1,42 @@
+package matchers
+
+import (
+	"bytes"
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type EqualMatcher struct {
+	Expected interface{}
+}
+
+func (matcher *EqualMatcher) Match(actual interface{}) (success bool, err error) {
+	if actual == nil && matcher.Expected == nil {
+		return false, fmt.Errorf("Refusing to compare <nil> to <nil>.\nBe explicit and use BeNil() instead.  This is to avoid mistakes where both sides of an assertion are erroneously uninitialized.")
+	}
+	// Shortcut for byte slices.
+	// Comparing long byte slices with reflect.DeepEqual is very slow,
+	// so use bytes.Equal if actual and expected are both byte slices.
+	if actualByteSlice, ok := actual.([]byte); ok {
+		if expectedByteSlice, ok := matcher.Expected.([]byte); ok {
+			return bytes.Equal(actualByteSlice, expectedByteSlice), nil
+		}
+	}
+	return reflect.DeepEqual(actual, matcher.Expected), nil
+}
+
+func (matcher *EqualMatcher) FailureMessage(actual interface{}) (message string) {
+	actualString, actualOK := actual.(string)
+	expectedString, expectedOK := matcher.Expected.(string)
+	if actualOK && expectedOK {
+		return format.MessageWithDiff(actualString, "to equal", expectedString)
+	}
+
+	return format.Message(actual, "to equal", matcher.Expected)
+}
+
+func (matcher *EqualMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to equal", matcher.Expected)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go
new file mode 100644
index 0000000..7ace93d
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_cap_matcher.go
@@ -0,0 +1,28 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveCapMatcher struct {
+	Count int
+}
+
+func (matcher *HaveCapMatcher) Match(actual interface{}) (success bool, err error) {
+	length, ok := capOf(actual)
+	if !ok {
+		return false, fmt.Errorf("HaveCap matcher expects a array/channel/slice.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return length == matcher.Count, nil
+}
+
+func (matcher *HaveCapMatcher) FailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected\n%s\nto have capacity %d", format.Object(actual, 1), matcher.Count)
+}
+
+func (matcher *HaveCapMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected\n%s\nnot to have capacity %d", format.Object(actual, 1), matcher.Count)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go
new file mode 100644
index 0000000..ea5b923
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_matcher.go
@@ -0,0 +1,54 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveKeyMatcher struct {
+	Key interface{}
+}
+
+func (matcher *HaveKeyMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isMap(actual) {
+		return false, fmt.Errorf("HaveKey matcher expects a map.  Got:%s", format.Object(actual, 1))
+	}
+
+	keyMatcher, keyIsMatcher := matcher.Key.(omegaMatcher)
+	if !keyIsMatcher {
+		keyMatcher = &EqualMatcher{Expected: matcher.Key}
+	}
+
+	keys := reflect.ValueOf(actual).MapKeys()
+	for i := 0; i < len(keys); i++ {
+		success, err := keyMatcher.Match(keys[i].Interface())
+		if err != nil {
+			return false, fmt.Errorf("HaveKey's key matcher failed with:\n%s%s", format.Indent, err.Error())
+		}
+		if success {
+			return true, nil
+		}
+	}
+
+	return false, nil
+}
+
+func (matcher *HaveKeyMatcher) FailureMessage(actual interface{}) (message string) {
+	switch matcher.Key.(type) {
+	case omegaMatcher:
+		return format.Message(actual, "to have key matching", matcher.Key)
+	default:
+		return format.Message(actual, "to have key", matcher.Key)
+	}
+}
+
+func (matcher *HaveKeyMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	switch matcher.Key.(type) {
+	case omegaMatcher:
+		return format.Message(actual, "not to have key matching", matcher.Key)
+	default:
+		return format.Message(actual, "not to have key", matcher.Key)
+	}
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go
new file mode 100644
index 0000000..06355b1
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_key_with_value_matcher.go
@@ -0,0 +1,74 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveKeyWithValueMatcher struct {
+	Key   interface{}
+	Value interface{}
+}
+
+func (matcher *HaveKeyWithValueMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isMap(actual) {
+		return false, fmt.Errorf("HaveKeyWithValue matcher expects a map.  Got:%s", format.Object(actual, 1))
+	}
+
+	keyMatcher, keyIsMatcher := matcher.Key.(omegaMatcher)
+	if !keyIsMatcher {
+		keyMatcher = &EqualMatcher{Expected: matcher.Key}
+	}
+
+	valueMatcher, valueIsMatcher := matcher.Value.(omegaMatcher)
+	if !valueIsMatcher {
+		valueMatcher = &EqualMatcher{Expected: matcher.Value}
+	}
+
+	keys := reflect.ValueOf(actual).MapKeys()
+	for i := 0; i < len(keys); i++ {
+		success, err := keyMatcher.Match(keys[i].Interface())
+		if err != nil {
+			return false, fmt.Errorf("HaveKeyWithValue's key matcher failed with:\n%s%s", format.Indent, err.Error())
+		}
+		if success {
+			actualValue := reflect.ValueOf(actual).MapIndex(keys[i])
+			success, err := valueMatcher.Match(actualValue.Interface())
+			if err != nil {
+				return false, fmt.Errorf("HaveKeyWithValue's value matcher failed with:\n%s%s", format.Indent, err.Error())
+			}
+			return success, nil
+		}
+	}
+
+	return false, nil
+}
+
+func (matcher *HaveKeyWithValueMatcher) FailureMessage(actual interface{}) (message string) {
+	str := "to have {key: value}"
+	if _, ok := matcher.Key.(omegaMatcher); ok {
+		str += " matching"
+	} else if _, ok := matcher.Value.(omegaMatcher); ok {
+		str += " matching"
+	}
+
+	expect := make(map[interface{}]interface{}, 1)
+	expect[matcher.Key] = matcher.Value
+	return format.Message(actual, str, expect)
+}
+
+func (matcher *HaveKeyWithValueMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	kStr := "not to have key"
+	if _, ok := matcher.Key.(omegaMatcher); ok {
+		kStr = "not to have key matching"
+	}
+
+	vStr := "or that key's value not be"
+	if _, ok := matcher.Value.(omegaMatcher); ok {
+		vStr = "or to have that key's value not matching"
+	}
+
+	return format.Message(actual, kStr, matcher.Key, vStr, matcher.Value)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go
new file mode 100644
index 0000000..ee42761
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_len_matcher.go
@@ -0,0 +1,28 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveLenMatcher struct {
+	Count int
+}
+
+func (matcher *HaveLenMatcher) Match(actual interface{}) (success bool, err error) {
+	length, ok := lengthOf(actual)
+	if !ok {
+		return false, fmt.Errorf("HaveLen matcher expects a string/array/map/channel/slice.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	return length == matcher.Count, nil
+}
+
+func (matcher *HaveLenMatcher) FailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected\n%s\nto have length %d", format.Object(actual, 1), matcher.Count)
+}
+
+func (matcher *HaveLenMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected\n%s\nnot to have length %d", format.Object(actual, 1), matcher.Count)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go
new file mode 100644
index 0000000..ebdd717
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_occurred_matcher.go
@@ -0,0 +1,33 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveOccurredMatcher struct {
+}
+
+func (matcher *HaveOccurredMatcher) Match(actual interface{}) (success bool, err error) {
+	// is purely nil?
+	if actual == nil {
+		return false, nil
+	}
+
+	// must be an 'error' type
+	if !isError(actual) {
+		return false, fmt.Errorf("Expected an error-type.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	// must be non-nil (or a pointer to a non-nil)
+	return !isNil(actual), nil
+}
+
+func (matcher *HaveOccurredMatcher) FailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected an error to have occurred.  Got:\n%s", format.Object(actual, 1))
+}
+
+func (matcher *HaveOccurredMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected error:\n%s\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1), "not to have occurred")
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go
new file mode 100644
index 0000000..1d8e802
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_prefix_matcher.go
@@ -0,0 +1,36 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HavePrefixMatcher struct {
+	Prefix string
+	Args   []interface{}
+}
+
+func (matcher *HavePrefixMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return false, fmt.Errorf("HavePrefix matcher requires a string or stringer.  Got:\n%s", format.Object(actual, 1))
+	}
+	prefix := matcher.prefix()
+	return len(actualString) >= len(prefix) && actualString[0:len(prefix)] == prefix, nil
+}
+
+func (matcher *HavePrefixMatcher) prefix() string {
+	if len(matcher.Args) > 0 {
+		return fmt.Sprintf(matcher.Prefix, matcher.Args...)
+	}
+	return matcher.Prefix
+}
+
+func (matcher *HavePrefixMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to have prefix", matcher.prefix())
+}
+
+func (matcher *HavePrefixMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to have prefix", matcher.prefix())
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go
new file mode 100644
index 0000000..40a3526
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/have_suffix_matcher.go
@@ -0,0 +1,36 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type HaveSuffixMatcher struct {
+	Suffix string
+	Args   []interface{}
+}
+
+func (matcher *HaveSuffixMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return false, fmt.Errorf("HaveSuffix matcher requires a string or stringer.  Got:\n%s", format.Object(actual, 1))
+	}
+	suffix := matcher.suffix()
+	return len(actualString) >= len(suffix) && actualString[len(actualString)-len(suffix):] == suffix, nil
+}
+
+func (matcher *HaveSuffixMatcher) suffix() string {
+	if len(matcher.Args) > 0 {
+		return fmt.Sprintf(matcher.Suffix, matcher.Args...)
+	}
+	return matcher.Suffix
+}
+
+func (matcher *HaveSuffixMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to have suffix", matcher.suffix())
+}
+
+func (matcher *HaveSuffixMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to have suffix", matcher.suffix())
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go
new file mode 100644
index 0000000..07499ac
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_error_matcher.go
@@ -0,0 +1,51 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type MatchErrorMatcher struct {
+	Expected interface{}
+}
+
+func (matcher *MatchErrorMatcher) Match(actual interface{}) (success bool, err error) {
+	if isNil(actual) {
+		return false, fmt.Errorf("Expected an error, got nil")
+	}
+
+	if !isError(actual) {
+		return false, fmt.Errorf("Expected an error.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	actualErr := actual.(error)
+
+	if isError(matcher.Expected) {
+		return reflect.DeepEqual(actualErr, matcher.Expected), nil
+	}
+
+	if isString(matcher.Expected) {
+		return actualErr.Error() == matcher.Expected, nil
+	}
+
+	var subMatcher omegaMatcher
+	var hasSubMatcher bool
+	if matcher.Expected != nil {
+		subMatcher, hasSubMatcher = (matcher.Expected).(omegaMatcher)
+		if hasSubMatcher {
+			return subMatcher.Match(actualErr.Error())
+		}
+	}
+
+	return false, fmt.Errorf("MatchError must be passed an error, string, or Matcher that can match on strings.  Got:\n%s", format.Object(matcher.Expected, 1))
+}
+
+func (matcher *MatchErrorMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to match error", matcher.Expected)
+}
+
+func (matcher *MatchErrorMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to match error", matcher.Expected)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/match_json_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_json_matcher.go
new file mode 100644
index 0000000..499bb58
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_json_matcher.go
@@ -0,0 +1,135 @@
+package matchers
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"reflect"
+	"strings"
+
+	"github.com/onsi/gomega/format"
+)
+
+type MatchJSONMatcher struct {
+	JSONToMatch      interface{}
+	firstFailurePath []interface{}
+}
+
+func (matcher *MatchJSONMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, expectedString, err := matcher.prettyPrint(actual)
+	if err != nil {
+		return false, err
+	}
+
+	var aval interface{}
+	var eval interface{}
+
+	// this is guarded by prettyPrint
+	json.Unmarshal([]byte(actualString), &aval)
+	json.Unmarshal([]byte(expectedString), &eval)
+	var equal bool
+	equal, matcher.firstFailurePath = deepEqual(aval, eval)
+	return equal, nil
+}
+
+func (matcher *MatchJSONMatcher) FailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.prettyPrint(actual)
+	return formattedMessage(format.Message(actualString, "to match JSON of", expectedString), matcher.firstFailurePath)
+}
+
+func (matcher *MatchJSONMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.prettyPrint(actual)
+	return formattedMessage(format.Message(actualString, "not to match JSON of", expectedString), matcher.firstFailurePath)
+}
+
+func formattedMessage(comparisonMessage string, failurePath []interface{}) string {
+	var diffMessage string
+	if len(failurePath) == 0 {
+		diffMessage = ""
+	} else {
+		diffMessage = fmt.Sprintf("\n\nfirst mismatched key: %s", formattedFailurePath(failurePath))
+	}
+	return fmt.Sprintf("%s%s", comparisonMessage, diffMessage)
+}
+
+func formattedFailurePath(failurePath []interface{}) string {
+	formattedPaths := []string{}
+	for i := len(failurePath) - 1; i >= 0; i-- {
+		switch p := failurePath[i].(type) {
+		case int:
+			formattedPaths = append(formattedPaths, fmt.Sprintf(`[%d]`, p))
+		default:
+			if i != len(failurePath)-1 {
+				formattedPaths = append(formattedPaths, ".")
+			}
+			formattedPaths = append(formattedPaths, fmt.Sprintf(`"%s"`, p))
+		}
+	}
+	return strings.Join(formattedPaths, "")
+}
+
+func (matcher *MatchJSONMatcher) prettyPrint(actual interface{}) (actualFormatted, expectedFormatted string, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return "", "", fmt.Errorf("MatchJSONMatcher matcher requires a string, stringer, or []byte.  Got actual:\n%s", format.Object(actual, 1))
+	}
+	expectedString, ok := toString(matcher.JSONToMatch)
+	if !ok {
+		return "", "", fmt.Errorf("MatchJSONMatcher matcher requires a string, stringer, or []byte.  Got expected:\n%s", format.Object(matcher.JSONToMatch, 1))
+	}
+
+	abuf := new(bytes.Buffer)
+	ebuf := new(bytes.Buffer)
+
+	if err := json.Indent(abuf, []byte(actualString), "", "  "); err != nil {
+		return "", "", fmt.Errorf("Actual '%s' should be valid JSON, but it is not.\nUnderlying error:%s", actualString, err)
+	}
+
+	if err := json.Indent(ebuf, []byte(expectedString), "", "  "); err != nil {
+		return "", "", fmt.Errorf("Expected '%s' should be valid JSON, but it is not.\nUnderlying error:%s", expectedString, err)
+	}
+
+	return abuf.String(), ebuf.String(), nil
+}
+
+func deepEqual(a interface{}, b interface{}) (bool, []interface{}) {
+	var errorPath []interface{}
+	if reflect.TypeOf(a) != reflect.TypeOf(b) {
+		return false, errorPath
+	}
+
+	switch a.(type) {
+	case []interface{}:
+		if len(a.([]interface{})) != len(b.([]interface{})) {
+			return false, errorPath
+		}
+
+		for i, v := range a.([]interface{}) {
+			elementEqual, keyPath := deepEqual(v, b.([]interface{})[i])
+			if !elementEqual {
+				return false, append(keyPath, i)
+			}
+		}
+		return true, errorPath
+
+	case map[string]interface{}:
+		if len(a.(map[string]interface{})) != len(b.(map[string]interface{})) {
+			return false, errorPath
+		}
+
+		for k, v1 := range a.(map[string]interface{}) {
+			v2, ok := b.(map[string]interface{})[k]
+			if !ok {
+				return false, errorPath
+			}
+			elementEqual, keyPath := deepEqual(v1, v2)
+			if !elementEqual {
+				return false, append(keyPath, k)
+			}
+		}
+		return true, errorPath
+
+	default:
+		return a == b, errorPath
+	}
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go
new file mode 100644
index 0000000..adac5db
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_regexp_matcher.go
@@ -0,0 +1,43 @@
+package matchers
+
+import (
+	"fmt"
+	"regexp"
+
+	"github.com/onsi/gomega/format"
+)
+
+type MatchRegexpMatcher struct {
+	Regexp string
+	Args   []interface{}
+}
+
+func (matcher *MatchRegexpMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return false, fmt.Errorf("RegExp matcher requires a string or stringer.\nGot:%s", format.Object(actual, 1))
+	}
+
+	match, err := regexp.Match(matcher.regexp(), []byte(actualString))
+	if err != nil {
+		return false, fmt.Errorf("RegExp match failed to compile with error:\n\t%s", err.Error())
+	}
+
+	return match, nil
+}
+
+func (matcher *MatchRegexpMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to match regular expression", matcher.regexp())
+}
+
+func (matcher *MatchRegexpMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "not to match regular expression", matcher.regexp())
+}
+
+func (matcher *MatchRegexpMatcher) regexp() string {
+	re := matcher.Regexp
+	if len(matcher.Args) > 0 {
+		re = fmt.Sprintf(matcher.Regexp, matcher.Args...)
+	}
+	return re
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go
new file mode 100644
index 0000000..3b412ce
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_xml_matcher.go
@@ -0,0 +1,134 @@
+package matchers
+
+import (
+	"bytes"
+	"encoding/xml"
+	"errors"
+	"fmt"
+	"io"
+	"reflect"
+	"sort"
+	"strings"
+
+	"github.com/onsi/gomega/format"
+	"golang.org/x/net/html/charset"
+)
+
+type MatchXMLMatcher struct {
+	XMLToMatch interface{}
+}
+
+func (matcher *MatchXMLMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, expectedString, err := matcher.formattedPrint(actual)
+	if err != nil {
+		return false, err
+	}
+
+	aval, err := parseXmlContent(actualString)
+	if err != nil {
+		return false, fmt.Errorf("Actual '%s' should be valid XML, but it is not.\nUnderlying error:%s", actualString, err)
+	}
+
+	eval, err := parseXmlContent(expectedString)
+	if err != nil {
+		return false, fmt.Errorf("Expected '%s' should be valid XML, but it is not.\nUnderlying error:%s", expectedString, err)
+	}
+
+	return reflect.DeepEqual(aval, eval), nil
+}
+
+func (matcher *MatchXMLMatcher) FailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.formattedPrint(actual)
+	return fmt.Sprintf("Expected\n%s\nto match XML of\n%s", actualString, expectedString)
+}
+
+func (matcher *MatchXMLMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.formattedPrint(actual)
+	return fmt.Sprintf("Expected\n%s\nnot to match XML of\n%s", actualString, expectedString)
+}
+
+func (matcher *MatchXMLMatcher) formattedPrint(actual interface{}) (actualString, expectedString string, err error) {
+	var ok bool
+	actualString, ok = toString(actual)
+	if !ok {
+		return "", "", fmt.Errorf("MatchXMLMatcher matcher requires a string, stringer, or []byte.  Got actual:\n%s", format.Object(actual, 1))
+	}
+	expectedString, ok = toString(matcher.XMLToMatch)
+	if !ok {
+		return "", "", fmt.Errorf("MatchXMLMatcher matcher requires a string, stringer, or []byte.  Got expected:\n%s", format.Object(matcher.XMLToMatch, 1))
+	}
+	return actualString, expectedString, nil
+}
+
+func parseXmlContent(content string) (*xmlNode, error) {
+	allNodes := []*xmlNode{}
+
+	dec := newXmlDecoder(strings.NewReader(content))
+	for {
+		tok, err := dec.Token()
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			return nil, fmt.Errorf("failed to decode next token: %v", err)
+		}
+
+		lastNodeIndex := len(allNodes) - 1
+		var lastNode *xmlNode
+		if len(allNodes) > 0 {
+			lastNode = allNodes[lastNodeIndex]
+		} else {
+			lastNode = &xmlNode{}
+		}
+
+		switch tok := tok.(type) {
+		case xml.StartElement:
+			attrs := attributesSlice(tok.Attr)
+			sort.Sort(attrs)
+			allNodes = append(allNodes, &xmlNode{XMLName: tok.Name, XMLAttr: tok.Attr})
+		case xml.EndElement:
+			if len(allNodes) > 1 {
+				allNodes[lastNodeIndex-1].Nodes = append(allNodes[lastNodeIndex-1].Nodes, lastNode)
+				allNodes = allNodes[:lastNodeIndex]
+			}
+		case xml.CharData:
+			lastNode.Content = append(lastNode.Content, tok.Copy()...)
+		case xml.Comment:
+			lastNode.Comments = append(lastNode.Comments, tok.Copy())
+		case xml.ProcInst:
+			lastNode.ProcInsts = append(lastNode.ProcInsts, tok.Copy())
+		}
+	}
+
+	if len(allNodes) == 0 {
+		return nil, errors.New("found no nodes")
+	}
+	firstNode := allNodes[0]
+	trimParentNodesContentSpaces(firstNode)
+
+	return firstNode, nil
+}
+
+func newXmlDecoder(reader io.Reader) *xml.Decoder {
+	dec := xml.NewDecoder(reader)
+	dec.CharsetReader = charset.NewReaderLabel
+	return dec
+}
+
+func trimParentNodesContentSpaces(node *xmlNode) {
+	if len(node.Nodes) > 0 {
+		node.Content = bytes.TrimSpace(node.Content)
+		for _, childNode := range node.Nodes {
+			trimParentNodesContentSpaces(childNode)
+		}
+	}
+}
+
+type xmlNode struct {
+	XMLName   xml.Name
+	Comments  []xml.Comment
+	ProcInsts []xml.ProcInst
+	XMLAttr   []xml.Attr
+	Content   []byte
+	Nodes     []*xmlNode
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go
new file mode 100644
index 0000000..69fb51a
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/match_yaml_matcher.go
@@ -0,0 +1,74 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+
+	"github.com/onsi/gomega/format"
+	"gopkg.in/yaml.v2"
+)
+
+type MatchYAMLMatcher struct {
+	YAMLToMatch interface{}
+}
+
+func (matcher *MatchYAMLMatcher) Match(actual interface{}) (success bool, err error) {
+	actualString, expectedString, err := matcher.toStrings(actual)
+	if err != nil {
+		return false, err
+	}
+
+	var aval interface{}
+	var eval interface{}
+
+	if err := yaml.Unmarshal([]byte(actualString), &aval); err != nil {
+		return false, fmt.Errorf("Actual '%s' should be valid YAML, but it is not.\nUnderlying error:%s", actualString, err)
+	}
+	if err := yaml.Unmarshal([]byte(expectedString), &eval); err != nil {
+		return false, fmt.Errorf("Expected '%s' should be valid YAML, but it is not.\nUnderlying error:%s", expectedString, err)
+	}
+
+	return reflect.DeepEqual(aval, eval), nil
+}
+
+func (matcher *MatchYAMLMatcher) FailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.toNormalisedStrings(actual)
+	return format.Message(actualString, "to match YAML of", expectedString)
+}
+
+func (matcher *MatchYAMLMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	actualString, expectedString, _ := matcher.toNormalisedStrings(actual)
+	return format.Message(actualString, "not to match YAML of", expectedString)
+}
+
+func (matcher *MatchYAMLMatcher) toNormalisedStrings(actual interface{}) (actualFormatted, expectedFormatted string, err error) {
+	actualString, expectedString, err := matcher.toStrings(actual)
+	return normalise(actualString), normalise(expectedString), err
+}
+
+func normalise(input string) string {
+	var val interface{}
+	err := yaml.Unmarshal([]byte(input), &val)
+	if err != nil {
+		panic(err) // guarded by Match
+	}
+	output, err := yaml.Marshal(val)
+	if err != nil {
+		panic(err) // guarded by Unmarshal
+	}
+	return strings.TrimSpace(string(output))
+}
+
+func (matcher *MatchYAMLMatcher) toStrings(actual interface{}) (actualFormatted, expectedFormatted string, err error) {
+	actualString, ok := toString(actual)
+	if !ok {
+		return "", "", fmt.Errorf("MatchYAMLMatcher matcher requires a string, stringer, or []byte.  Got actual:\n%s", format.Object(actual, 1))
+	}
+	expectedString, ok := toString(matcher.YAMLToMatch)
+	if !ok {
+		return "", "", fmt.Errorf("MatchYAMLMatcher matcher requires a string, stringer, or []byte.  Got expected:\n%s", format.Object(matcher.YAMLToMatch, 1))
+	}
+
+	return actualString, expectedString, nil
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/not.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/not.go
new file mode 100644
index 0000000..2c91670
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/not.go
@@ -0,0 +1,30 @@
+package matchers
+
+import (
+	"github.com/onsi/gomega/internal/oraclematcher"
+	"github.com/onsi/gomega/types"
+)
+
+type NotMatcher struct {
+	Matcher types.GomegaMatcher
+}
+
+func (m *NotMatcher) Match(actual interface{}) (bool, error) {
+	success, err := m.Matcher.Match(actual)
+	if err != nil {
+		return false, err
+	}
+	return !success, nil
+}
+
+func (m *NotMatcher) FailureMessage(actual interface{}) (message string) {
+	return m.Matcher.NegatedFailureMessage(actual) // works beautifully
+}
+
+func (m *NotMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return m.Matcher.FailureMessage(actual) // works beautifully
+}
+
+func (m *NotMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	return oraclematcher.MatchMayChangeInTheFuture(m.Matcher, actual) // just return m.Matcher's value
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/or.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/or.go
new file mode 100644
index 0000000..3bf7998
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/or.go
@@ -0,0 +1,67 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+	"github.com/onsi/gomega/internal/oraclematcher"
+	"github.com/onsi/gomega/types"
+)
+
+type OrMatcher struct {
+	Matchers []types.GomegaMatcher
+
+	// state
+	firstSuccessfulMatcher types.GomegaMatcher
+}
+
+func (m *OrMatcher) Match(actual interface{}) (success bool, err error) {
+	m.firstSuccessfulMatcher = nil
+	for _, matcher := range m.Matchers {
+		success, err := matcher.Match(actual)
+		if err != nil {
+			return false, err
+		}
+		if success {
+			m.firstSuccessfulMatcher = matcher
+			return true, nil
+		}
+	}
+	return false, nil
+}
+
+func (m *OrMatcher) FailureMessage(actual interface{}) (message string) {
+	// not the most beautiful list of matchers, but not bad either...
+	return format.Message(actual, fmt.Sprintf("To satisfy at least one of these matchers: %s", m.Matchers))
+}
+
+func (m *OrMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return m.firstSuccessfulMatcher.NegatedFailureMessage(actual)
+}
+
+func (m *OrMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	/*
+		Example with 3 matchers: A, B, C
+
+		Match evaluates them: F, T, <?>  => T
+		So match is currently T, what should MatchMayChangeInTheFuture() return?
+		Seems like it only depends on B, since currently B MUST change to allow the result to become F
+
+		Match eval: F, F, F  => F
+		So match is currently F, what should MatchMayChangeInTheFuture() return?
+		Seems to depend on ANY of them being able to change to T.
+	*/
+
+	if m.firstSuccessfulMatcher != nil {
+		// one of the matchers succeeded.. it must be able to change in order to affect the result
+		return oraclematcher.MatchMayChangeInTheFuture(m.firstSuccessfulMatcher, actual)
+	} else {
+		// so all matchers failed.. Any one of them changing would change the result.
+		for _, matcher := range m.Matchers {
+			if oraclematcher.MatchMayChangeInTheFuture(matcher, actual) {
+				return true
+			}
+		}
+		return false // none of were going to change
+	}
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/panic_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/panic_matcher.go
new file mode 100644
index 0000000..640f4db
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/panic_matcher.go
@@ -0,0 +1,46 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type PanicMatcher struct {
+	object interface{}
+}
+
+func (matcher *PanicMatcher) Match(actual interface{}) (success bool, err error) {
+	if actual == nil {
+		return false, fmt.Errorf("PanicMatcher expects a non-nil actual.")
+	}
+
+	actualType := reflect.TypeOf(actual)
+	if actualType.Kind() != reflect.Func {
+		return false, fmt.Errorf("PanicMatcher expects a function.  Got:\n%s", format.Object(actual, 1))
+	}
+	if !(actualType.NumIn() == 0 && actualType.NumOut() == 0) {
+		return false, fmt.Errorf("PanicMatcher expects a function with no arguments and no return value.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	success = false
+	defer func() {
+		if e := recover(); e != nil {
+			matcher.object = e
+			success = true
+		}
+	}()
+
+	reflect.ValueOf(actual).Call([]reflect.Value{})
+
+	return
+}
+
+func (matcher *PanicMatcher) FailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, "to panic")
+}
+
+func (matcher *PanicMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return format.Message(actual, fmt.Sprintf("not to panic, but panicked with\n%s", format.Object(matcher.object, 1)))
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/receive_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/receive_matcher.go
new file mode 100644
index 0000000..74e9e7e
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/receive_matcher.go
@@ -0,0 +1,122 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/format"
+)
+
+type ReceiveMatcher struct {
+	Arg           interface{}
+	receivedValue reflect.Value
+	channelClosed bool
+}
+
+func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err error) {
+	if !isChan(actual) {
+		return false, fmt.Errorf("ReceiveMatcher expects a channel.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	channelType := reflect.TypeOf(actual)
+	channelValue := reflect.ValueOf(actual)
+
+	if channelType.ChanDir() == reflect.SendDir {
+		return false, fmt.Errorf("ReceiveMatcher matcher cannot be passed a send-only channel.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	var subMatcher omegaMatcher
+	var hasSubMatcher bool
+
+	if matcher.Arg != nil {
+		subMatcher, hasSubMatcher = (matcher.Arg).(omegaMatcher)
+		if !hasSubMatcher {
+			argType := reflect.TypeOf(matcher.Arg)
+			if argType.Kind() != reflect.Ptr {
+				return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s\nYou need to pass a pointer!", format.Object(actual, 1), format.Object(matcher.Arg, 1))
+			}
+
+			assignable := channelType.Elem().AssignableTo(argType.Elem())
+			if !assignable {
+				return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s", format.Object(actual, 1), format.Object(matcher.Arg, 1))
+			}
+		}
+	}
+
+	winnerIndex, value, open := reflect.Select([]reflect.SelectCase{
+		reflect.SelectCase{Dir: reflect.SelectRecv, Chan: channelValue},
+		reflect.SelectCase{Dir: reflect.SelectDefault},
+	})
+
+	var closed bool
+	var didReceive bool
+	if winnerIndex == 0 {
+		closed = !open
+		didReceive = open
+	}
+	matcher.channelClosed = closed
+
+	if closed {
+		return false, nil
+	}
+
+	if hasSubMatcher {
+		if didReceive {
+			matcher.receivedValue = value
+			return subMatcher.Match(matcher.receivedValue.Interface())
+		}
+		return false, nil
+	}
+
+	if didReceive {
+		if matcher.Arg != nil {
+			outValue := reflect.ValueOf(matcher.Arg)
+			reflect.Indirect(outValue).Set(value)
+		}
+
+		return true, nil
+	}
+	return false, nil
+}
+
+func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message string) {
+	subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher)
+
+	closedAddendum := ""
+	if matcher.channelClosed {
+		closedAddendum = " The channel is closed."
+	}
+
+	if hasSubMatcher {
+		if matcher.receivedValue.IsValid() {
+			return subMatcher.FailureMessage(matcher.receivedValue.Interface())
+		}
+		return "When passed a matcher, ReceiveMatcher's channel *must* receive something."
+	}
+	return format.Message(actual, "to receive something."+closedAddendum)
+}
+
+func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher)
+
+	closedAddendum := ""
+	if matcher.channelClosed {
+		closedAddendum = " The channel is closed."
+	}
+
+	if hasSubMatcher {
+		if matcher.receivedValue.IsValid() {
+			return subMatcher.NegatedFailureMessage(matcher.receivedValue.Interface())
+		}
+		return "When passed a matcher, ReceiveMatcher's channel *must* receive something."
+	}
+	return format.Message(actual, "not to receive anything."+closedAddendum)
+}
+
+func (matcher *ReceiveMatcher) MatchMayChangeInTheFuture(actual interface{}) bool {
+	if !isChan(actual) {
+		return false
+	}
+
+	return !matcher.channelClosed
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go
new file mode 100644
index 0000000..721ed55
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/succeed_matcher.go
@@ -0,0 +1,33 @@
+package matchers
+
+import (
+	"fmt"
+
+	"github.com/onsi/gomega/format"
+)
+
+type SucceedMatcher struct {
+}
+
+func (matcher *SucceedMatcher) Match(actual interface{}) (success bool, err error) {
+	// is purely nil?
+	if actual == nil {
+		return true, nil
+	}
+
+	// must be an 'error' type
+	if !isError(actual) {
+		return false, fmt.Errorf("Expected an error-type.  Got:\n%s", format.Object(actual, 1))
+	}
+
+	// must be nil (or a pointer to a nil)
+	return isNil(actual), nil
+}
+
+func (matcher *SucceedMatcher) FailureMessage(actual interface{}) (message string) {
+	return fmt.Sprintf("Expected success, but got an error:\n%s\n%s", format.Object(actual, 1), format.IndentString(actual.(error).Error(), 1))
+}
+
+func (matcher *SucceedMatcher) NegatedFailureMessage(actual interface{}) (message string) {
+	return "Expected failure, but got no error."
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go
new file mode 100644
index 0000000..81b3771
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraph.go
@@ -0,0 +1,41 @@
+package bipartitegraph
+
+import "errors"
+import "fmt"
+
+import . "github.com/onsi/gomega/matchers/support/goraph/node"
+import . "github.com/onsi/gomega/matchers/support/goraph/edge"
+
+type BipartiteGraph struct {
+	Left  NodeOrderedSet
+	Right NodeOrderedSet
+	Edges EdgeSet
+}
+
+func NewBipartiteGraph(leftValues, rightValues []interface{}, neighbours func(interface{}, interface{}) (bool, error)) (*BipartiteGraph, error) {
+	left := NodeOrderedSet{}
+	for i, _ := range leftValues {
+		left = append(left, Node{Id: i})
+	}
+
+	right := NodeOrderedSet{}
+	for j, _ := range rightValues {
+		right = append(right, Node{Id: j + len(left)})
+	}
+
+	edges := EdgeSet{}
+	for i, leftValue := range leftValues {
+		for j, rightValue := range rightValues {
+			neighbours, err := neighbours(leftValue, rightValue)
+			if err != nil {
+				return nil, errors.New(fmt.Sprintf("error determining adjacency for %v and %v: %s", leftValue, rightValue, err.Error()))
+			}
+
+			if neighbours {
+				edges = append(edges, Edge{Node1: left[i], Node2: right[j]})
+			}
+		}
+	}
+
+	return &BipartiteGraph{left, right, edges}, nil
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go
new file mode 100644
index 0000000..8181f43
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/bipartitegraph/bipartitegraphmatching.go
@@ -0,0 +1,159 @@
+package bipartitegraph
+
+import . "github.com/onsi/gomega/matchers/support/goraph/node"
+import . "github.com/onsi/gomega/matchers/support/goraph/edge"
+import "github.com/onsi/gomega/matchers/support/goraph/util"
+
+func (bg *BipartiteGraph) LargestMatching() (matching EdgeSet) {
+	paths := bg.maximalDisjointSLAPCollection(matching)
+
+	for len(paths) > 0 {
+		for _, path := range paths {
+			matching = matching.SymmetricDifference(path)
+		}
+		paths = bg.maximalDisjointSLAPCollection(matching)
+	}
+
+	return
+}
+
+func (bg *BipartiteGraph) maximalDisjointSLAPCollection(matching EdgeSet) (result []EdgeSet) {
+	guideLayers := bg.createSLAPGuideLayers(matching)
+	if len(guideLayers) == 0 {
+		return
+	}
+
+	used := make(map[Node]bool)
+
+	for _, u := range guideLayers[len(guideLayers)-1] {
+		slap, found := bg.findDisjointSLAP(u, matching, guideLayers, used)
+		if found {
+			for _, edge := range slap {
+				used[edge.Node1] = true
+				used[edge.Node2] = true
+			}
+			result = append(result, slap)
+		}
+	}
+
+	return
+}
+
+func (bg *BipartiteGraph) findDisjointSLAP(
+	start Node,
+	matching EdgeSet,
+	guideLayers []NodeOrderedSet,
+	used map[Node]bool,
+) ([]Edge, bool) {
+	return bg.findDisjointSLAPHelper(start, EdgeSet{}, len(guideLayers)-1, matching, guideLayers, used)
+}
+
+func (bg *BipartiteGraph) findDisjointSLAPHelper(
+	currentNode Node,
+	currentSLAP EdgeSet,
+	currentLevel int,
+	matching EdgeSet,
+	guideLayers []NodeOrderedSet,
+	used map[Node]bool,
+) (EdgeSet, bool) {
+	used[currentNode] = true
+
+	if currentLevel == 0 {
+		return currentSLAP, true
+	}
+
+	for _, nextNode := range guideLayers[currentLevel-1] {
+		if used[nextNode] {
+			continue
+		}
+
+		edge, found := bg.Edges.FindByNodes(currentNode, nextNode)
+		if !found {
+			continue
+		}
+
+		if matching.Contains(edge) == util.Odd(currentLevel) {
+			continue
+		}
+
+		currentSLAP = append(currentSLAP, edge)
+		slap, found := bg.findDisjointSLAPHelper(nextNode, currentSLAP, currentLevel-1, matching, guideLayers, used)
+		if found {
+			return slap, true
+		}
+		currentSLAP = currentSLAP[:len(currentSLAP)-1]
+	}
+
+	used[currentNode] = false
+	return nil, false
+}
+
+func (bg *BipartiteGraph) createSLAPGuideLayers(matching EdgeSet) (guideLayers []NodeOrderedSet) {
+	used := make(map[Node]bool)
+	currentLayer := NodeOrderedSet{}
+
+	for _, node := range bg.Left {
+		if matching.Free(node) {
+			used[node] = true
+			currentLayer = append(currentLayer, node)
+		}
+	}
+
+	if len(currentLayer) == 0 {
+		return []NodeOrderedSet{}
+	}
+	guideLayers = append(guideLayers, currentLayer)
+
+	done := false
+
+	for !done {
+		lastLayer := currentLayer
+		currentLayer = NodeOrderedSet{}
+
+		if util.Odd(len(guideLayers)) {
+			for _, leftNode := range lastLayer {
+				for _, rightNode := range bg.Right {
+					if used[rightNode] {
+						continue
+					}
+
+					edge, found := bg.Edges.FindByNodes(leftNode, rightNode)
+					if !found || matching.Contains(edge) {
+						continue
+					}
+
+					currentLayer = append(currentLayer, rightNode)
+					used[rightNode] = true
+
+					if matching.Free(rightNode) {
+						done = true
+					}
+				}
+			}
+		} else {
+			for _, rightNode := range lastLayer {
+				for _, leftNode := range bg.Left {
+					if used[leftNode] {
+						continue
+					}
+
+					edge, found := bg.Edges.FindByNodes(leftNode, rightNode)
+					if !found || !matching.Contains(edge) {
+						continue
+					}
+
+					currentLayer = append(currentLayer, leftNode)
+					used[leftNode] = true
+				}
+			}
+
+		}
+
+		if len(currentLayer) == 0 {
+			return []NodeOrderedSet{}
+		}
+		guideLayers = append(guideLayers, currentLayer)
+	}
+
+	return
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go
new file mode 100644
index 0000000..4fd15cc
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/edge/edge.go
@@ -0,0 +1,61 @@
+package edge
+
+import . "github.com/onsi/gomega/matchers/support/goraph/node"
+
+type Edge struct {
+	Node1 Node
+	Node2 Node
+}
+
+type EdgeSet []Edge
+
+func (ec EdgeSet) Free(node Node) bool {
+	for _, e := range ec {
+		if e.Node1 == node || e.Node2 == node {
+			return false
+		}
+	}
+
+	return true
+}
+
+func (ec EdgeSet) Contains(edge Edge) bool {
+	for _, e := range ec {
+		if e == edge {
+			return true
+		}
+	}
+
+	return false
+}
+
+func (ec EdgeSet) FindByNodes(node1, node2 Node) (Edge, bool) {
+	for _, e := range ec {
+		if (e.Node1 == node1 && e.Node2 == node2) || (e.Node1 == node2 && e.Node2 == node1) {
+			return e, true
+		}
+	}
+
+	return Edge{}, false
+}
+
+func (ec EdgeSet) SymmetricDifference(ec2 EdgeSet) EdgeSet {
+	edgesToInclude := make(map[Edge]bool)
+
+	for _, e := range ec {
+		edgesToInclude[e] = true
+	}
+
+	for _, e := range ec2 {
+		edgesToInclude[e] = !edgesToInclude[e]
+	}
+
+	result := EdgeSet{}
+	for e, include := range edgesToInclude {
+		if include {
+			result = append(result, e)
+		}
+	}
+
+	return result
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go
new file mode 100644
index 0000000..800c2ea
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/node/node.go
@@ -0,0 +1,7 @@
+package node
+
+type Node struct {
+	Id int
+}
+
+type NodeOrderedSet []Node
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/util/util.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/util/util.go
new file mode 100644
index 0000000..d76a1ee
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/support/goraph/util/util.go
@@ -0,0 +1,7 @@
+package util
+
+import "math"
+
+func Odd(n int) bool {
+	return math.Mod(float64(n), 2.0) == 1.0
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/type_support.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/type_support.go
new file mode 100644
index 0000000..b05a5e7
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/type_support.go
@@ -0,0 +1,173 @@
+/*
+Gomega matchers
+
+This package implements the Gomega matchers and does not typically need to be imported.
+See the docs for Gomega for documentation on the matchers
+
+http://onsi.github.io/gomega/
+*/
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+)
+
+type omegaMatcher interface {
+	Match(actual interface{}) (success bool, err error)
+	FailureMessage(actual interface{}) (message string)
+	NegatedFailureMessage(actual interface{}) (message string)
+}
+
+func isBool(a interface{}) bool {
+	return reflect.TypeOf(a).Kind() == reflect.Bool
+}
+
+func isNumber(a interface{}) bool {
+	if a == nil {
+		return false
+	}
+	kind := reflect.TypeOf(a).Kind()
+	return reflect.Int <= kind && kind <= reflect.Float64
+}
+
+func isInteger(a interface{}) bool {
+	kind := reflect.TypeOf(a).Kind()
+	return reflect.Int <= kind && kind <= reflect.Int64
+}
+
+func isUnsignedInteger(a interface{}) bool {
+	kind := reflect.TypeOf(a).Kind()
+	return reflect.Uint <= kind && kind <= reflect.Uint64
+}
+
+func isFloat(a interface{}) bool {
+	kind := reflect.TypeOf(a).Kind()
+	return reflect.Float32 <= kind && kind <= reflect.Float64
+}
+
+func toInteger(a interface{}) int64 {
+	if isInteger(a) {
+		return reflect.ValueOf(a).Int()
+	} else if isUnsignedInteger(a) {
+		return int64(reflect.ValueOf(a).Uint())
+	} else if isFloat(a) {
+		return int64(reflect.ValueOf(a).Float())
+	}
+	panic(fmt.Sprintf("Expected a number!  Got <%T> %#v", a, a))
+}
+
+func toUnsignedInteger(a interface{}) uint64 {
+	if isInteger(a) {
+		return uint64(reflect.ValueOf(a).Int())
+	} else if isUnsignedInteger(a) {
+		return reflect.ValueOf(a).Uint()
+	} else if isFloat(a) {
+		return uint64(reflect.ValueOf(a).Float())
+	}
+	panic(fmt.Sprintf("Expected a number!  Got <%T> %#v", a, a))
+}
+
+func toFloat(a interface{}) float64 {
+	if isInteger(a) {
+		return float64(reflect.ValueOf(a).Int())
+	} else if isUnsignedInteger(a) {
+		return float64(reflect.ValueOf(a).Uint())
+	} else if isFloat(a) {
+		return reflect.ValueOf(a).Float()
+	}
+	panic(fmt.Sprintf("Expected a number!  Got <%T> %#v", a, a))
+}
+
+func isError(a interface{}) bool {
+	_, ok := a.(error)
+	return ok
+}
+
+func isChan(a interface{}) bool {
+	if isNil(a) {
+		return false
+	}
+	return reflect.TypeOf(a).Kind() == reflect.Chan
+}
+
+func isMap(a interface{}) bool {
+	if a == nil {
+		return false
+	}
+	return reflect.TypeOf(a).Kind() == reflect.Map
+}
+
+func isArrayOrSlice(a interface{}) bool {
+	if a == nil {
+		return false
+	}
+	switch reflect.TypeOf(a).Kind() {
+	case reflect.Array, reflect.Slice:
+		return true
+	default:
+		return false
+	}
+}
+
+func isString(a interface{}) bool {
+	if a == nil {
+		return false
+	}
+	return reflect.TypeOf(a).Kind() == reflect.String
+}
+
+func toString(a interface{}) (string, bool) {
+	aString, isString := a.(string)
+	if isString {
+		return aString, true
+	}
+
+	aBytes, isBytes := a.([]byte)
+	if isBytes {
+		return string(aBytes), true
+	}
+
+	aStringer, isStringer := a.(fmt.Stringer)
+	if isStringer {
+		return aStringer.String(), true
+	}
+
+	return "", false
+}
+
+func lengthOf(a interface{}) (int, bool) {
+	if a == nil {
+		return 0, false
+	}
+	switch reflect.TypeOf(a).Kind() {
+	case reflect.Map, reflect.Array, reflect.String, reflect.Chan, reflect.Slice:
+		return reflect.ValueOf(a).Len(), true
+	default:
+		return 0, false
+	}
+}
+func capOf(a interface{}) (int, bool) {
+	if a == nil {
+		return 0, false
+	}
+	switch reflect.TypeOf(a).Kind() {
+	case reflect.Array, reflect.Chan, reflect.Slice:
+		return reflect.ValueOf(a).Cap(), true
+	default:
+		return 0, false
+	}
+}
+
+func isNil(a interface{}) bool {
+	if a == nil {
+		return true
+	}
+
+	switch reflect.TypeOf(a).Kind() {
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+		return reflect.ValueOf(a).IsNil()
+	}
+
+	return false
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/matchers/with_transform.go b/metrics-server/vendor/github.com/onsi/gomega/matchers/with_transform.go
new file mode 100644
index 0000000..8e58d8a
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/matchers/with_transform.go
@@ -0,0 +1,72 @@
+package matchers
+
+import (
+	"fmt"
+	"reflect"
+
+	"github.com/onsi/gomega/internal/oraclematcher"
+	"github.com/onsi/gomega/types"
+)
+
+type WithTransformMatcher struct {
+	// input
+	Transform interface{} // must be a function of one parameter that returns one value
+	Matcher   types.GomegaMatcher
+
+	// cached value
+	transformArgType reflect.Type
+
+	// state
+	transformedValue interface{}
+}
+
+func NewWithTransformMatcher(transform interface{}, matcher types.GomegaMatcher) *WithTransformMatcher {
+	if transform == nil {
+		panic("transform function cannot be nil")
+	}
+	txType := reflect.TypeOf(transform)
+	if txType.NumIn() != 1 {
+		panic("transform function must have 1 argument")
+	}
+	if txType.NumOut() != 1 {
+		panic("transform function must have 1 return value")
+	}
+
+	return &WithTransformMatcher{
+		Transform:        transform,
+		Matcher:          matcher,
+		transformArgType: reflect.TypeOf(transform).In(0),
+	}
+}
+
+func (m *WithTransformMatcher) Match(actual interface{}) (bool, error) {
+	// return error if actual's type is incompatible with Transform function's argument type
+	actualType := reflect.TypeOf(actual)
+	if !actualType.AssignableTo(m.transformArgType) {
+		return false, fmt.Errorf("Transform function expects '%s' but we have '%s'", m.transformArgType, actualType)
+	}
+
+	// call the Transform function with `actual`
+	fn := reflect.ValueOf(m.Transform)
+	result := fn.Call([]reflect.Value{reflect.ValueOf(actual)})
+	m.transformedValue = result[0].Interface() // expect exactly one value
+
+	return m.Matcher.Match(m.transformedValue)
+}
+
+func (m *WithTransformMatcher) FailureMessage(_ interface{}) (message string) {
+	return m.Matcher.FailureMessage(m.transformedValue)
+}
+
+func (m *WithTransformMatcher) NegatedFailureMessage(_ interface{}) (message string) {
+	return m.Matcher.NegatedFailureMessage(m.transformedValue)
+}
+
+func (m *WithTransformMatcher) MatchMayChangeInTheFuture(_ interface{}) bool {
+	// TODO: Maybe this should always just return true? (Only an issue for non-deterministic transformers.)
+	//
+	// Querying the next matcher is fine if the transformer always will return the same value.
+	// But if the transformer is non-deterministic and returns a different value each time, then there
+	// is no point in querying the next matcher, since it can only comment on the last transformed value.
+	return oraclematcher.MatchMayChangeInTheFuture(m.Matcher, m.transformedValue)
+}
diff --git a/metrics-server/vendor/github.com/onsi/gomega/types/types.go b/metrics-server/vendor/github.com/onsi/gomega/types/types.go
new file mode 100644
index 0000000..51256ed
--- /dev/null
+++ b/metrics-server/vendor/github.com/onsi/gomega/types/types.go
@@ -0,0 +1,17 @@
+package types
+
+type GomegaFailHandler func(message string, callerSkip ...int)
+
+//A simple *testing.T interface wrapper
+type GomegaTestingT interface {
+	Fatalf(format string, args ...interface{})
+}
+
+//All Gomega matchers must implement the GomegaMatcher interface
+//
+//For details on writing custom matchers, check out: http://onsi.github.io/gomega/#adding-your-own-matchers
+type GomegaMatcher interface {
+	Match(actual interface{}) (success bool, err error)
+	FailureMessage(actual interface{}) (message string)
+	NegatedFailureMessage(actual interface{}) (message string)
+}