git subrepo clone (merge) https://github.com/kubernetes-incubator/metrics-server.git metrics-server
subrepo:
subdir: "metrics-server"
merged: "92d8412"
upstream:
origin: "https://github.com/kubernetes-incubator/metrics-server.git"
branch: "master"
commit: "92d8412"
git-subrepo:
version: "0.4.0"
origin: "???"
commit: "???"
diff --git a/metrics-server/vendor/k8s.io/apiserver/pkg/storage/etcd/api_object_versioner.go b/metrics-server/vendor/k8s.io/apiserver/pkg/storage/etcd/api_object_versioner.go
new file mode 100644
index 0000000..5534f9f
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/apiserver/pkg/storage/etcd/api_object_versioner.go
@@ -0,0 +1,148 @@
+/*
+Copyright 2014 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package etcd
+
+import (
+ "strconv"
+
+ "k8s.io/apimachinery/pkg/api/meta"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/util/validation/field"
+ "k8s.io/apiserver/pkg/storage"
+)
+
+// APIObjectVersioner implements versioning and extracting etcd node information
+// for objects that have an embedded ObjectMeta or ListMeta field.
+type APIObjectVersioner struct{}
+
+// UpdateObject implements Versioner
+func (a APIObjectVersioner) UpdateObject(obj runtime.Object, resourceVersion uint64) error {
+ accessor, err := meta.Accessor(obj)
+ if err != nil {
+ return err
+ }
+ versionString := ""
+ if resourceVersion != 0 {
+ versionString = strconv.FormatUint(resourceVersion, 10)
+ }
+ accessor.SetResourceVersion(versionString)
+ return nil
+}
+
+// UpdateList implements Versioner
+func (a APIObjectVersioner) UpdateList(obj runtime.Object, resourceVersion uint64, nextKey string) error {
+ listAccessor, err := meta.ListAccessor(obj)
+ if err != nil || listAccessor == nil {
+ return err
+ }
+ versionString := ""
+ if resourceVersion != 0 {
+ versionString = strconv.FormatUint(resourceVersion, 10)
+ }
+ listAccessor.SetResourceVersion(versionString)
+ listAccessor.SetContinue(nextKey)
+ return nil
+}
+
+// PrepareObjectForStorage clears resource version and self link prior to writing to etcd.
+func (a APIObjectVersioner) PrepareObjectForStorage(obj runtime.Object) error {
+ accessor, err := meta.Accessor(obj)
+ if err != nil {
+ return err
+ }
+ accessor.SetResourceVersion("")
+ accessor.SetSelfLink("")
+ return nil
+}
+
+// ObjectResourceVersion implements Versioner
+func (a APIObjectVersioner) ObjectResourceVersion(obj runtime.Object) (uint64, error) {
+ accessor, err := meta.Accessor(obj)
+ if err != nil {
+ return 0, err
+ }
+ version := accessor.GetResourceVersion()
+ if len(version) == 0 {
+ return 0, nil
+ }
+ return strconv.ParseUint(version, 10, 64)
+}
+
+// ParseWatchResourceVersion takes a resource version argument and converts it to
+// the etcd version we should pass to helper.Watch(). Because resourceVersion is
+// an opaque value, the default watch behavior for non-zero watch is to watch
+// the next value (if you pass "1", you will see updates from "2" onwards).
+func (a APIObjectVersioner) ParseWatchResourceVersion(resourceVersion string) (uint64, error) {
+ if resourceVersion == "" || resourceVersion == "0" {
+ return 0, nil
+ }
+ version, err := strconv.ParseUint(resourceVersion, 10, 64)
+ if err != nil {
+ return 0, storage.NewInvalidError(field.ErrorList{
+ // Validation errors are supposed to return version-specific field
+ // paths, but this is probably close enough.
+ field.Invalid(field.NewPath("resourceVersion"), resourceVersion, err.Error()),
+ })
+ }
+ return version, nil
+}
+
+// ParseListResourceVersion takes a resource version argument and converts it to
+// the etcd version.
+// TODO: reevaluate whether it is really clearer to have both this and the
+// Watch version of this function, since they perform the same logic.
+func (a APIObjectVersioner) ParseListResourceVersion(resourceVersion string) (uint64, error) {
+ if resourceVersion == "" {
+ return 0, nil
+ }
+ version, err := strconv.ParseUint(resourceVersion, 10, 64)
+ if err != nil {
+ return 0, storage.NewInvalidError(field.ErrorList{
+ // Validation errors are supposed to return version-specific field
+ // paths, but this is probably close enough.
+ field.Invalid(field.NewPath("resourceVersion"), resourceVersion, err.Error()),
+ })
+ }
+ return version, nil
+}
+
+// APIObjectVersioner implements Versioner
+var Versioner storage.Versioner = APIObjectVersioner{}
+
+// CompareResourceVersion compares etcd resource versions. Outside this API they are all strings,
+// but etcd resource versions are special, they're actually ints, so we can easily compare them.
+func (a APIObjectVersioner) CompareResourceVersion(lhs, rhs runtime.Object) int {
+ lhsVersion, err := Versioner.ObjectResourceVersion(lhs)
+ if err != nil {
+ // coder error
+ panic(err)
+ }
+ rhsVersion, err := Versioner.ObjectResourceVersion(rhs)
+ if err != nil {
+ // coder error
+ panic(err)
+ }
+
+ if lhsVersion == rhsVersion {
+ return 0
+ }
+ if lhsVersion < rhsVersion {
+ return -1
+ }
+
+ return 1
+}