Import of https://github.com/ciena/voltctl at commit 40d61fbf3f910ed4017cf67c9c79e8e1f82a33a5

Change-Id: I8464c59e60d76cb8612891db3303878975b5416c
diff --git a/vendor/k8s.io/apimachinery/pkg/api/meta/priority.go b/vendor/k8s.io/apimachinery/pkg/api/meta/priority.go
new file mode 100644
index 0000000..fa11c58
--- /dev/null
+++ b/vendor/k8s.io/apimachinery/pkg/api/meta/priority.go
@@ -0,0 +1,222 @@
+/*
+Copyright 2016 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package meta
+
+import (
+	"fmt"
+
+	"k8s.io/apimachinery/pkg/runtime/schema"
+)
+
+const (
+	AnyGroup    = "*"
+	AnyVersion  = "*"
+	AnyResource = "*"
+	AnyKind     = "*"
+)
+
+// PriorityRESTMapper is a wrapper for automatically choosing a particular Resource or Kind
+// when multiple matches are possible
+type PriorityRESTMapper struct {
+	// Delegate is the RESTMapper to use to locate all the Kind and Resource matches
+	Delegate RESTMapper
+
+	// ResourcePriority is a list of priority patterns to apply to matching resources.
+	// The list of all matching resources is narrowed based on the patterns until only one remains.
+	// A pattern with no matches is skipped.  A pattern with more than one match uses its
+	// matches as the list to continue matching against.
+	ResourcePriority []schema.GroupVersionResource
+
+	// KindPriority is a list of priority patterns to apply to matching kinds.
+	// The list of all matching kinds is narrowed based on the patterns until only one remains.
+	// A pattern with no matches is skipped.  A pattern with more than one match uses its
+	// matches as the list to continue matching against.
+	KindPriority []schema.GroupVersionKind
+}
+
+func (m PriorityRESTMapper) String() string {
+	return fmt.Sprintf("PriorityRESTMapper{\n\t%v\n\t%v\n\t%v\n}", m.ResourcePriority, m.KindPriority, m.Delegate)
+}
+
+// ResourceFor finds all resources, then passes them through the ResourcePriority patterns to find a single matching hit.
+func (m PriorityRESTMapper) ResourceFor(partiallySpecifiedResource schema.GroupVersionResource) (schema.GroupVersionResource, error) {
+	originalGVRs, originalErr := m.Delegate.ResourcesFor(partiallySpecifiedResource)
+	if originalErr != nil && len(originalGVRs) == 0 {
+		return schema.GroupVersionResource{}, originalErr
+	}
+	if len(originalGVRs) == 1 {
+		return originalGVRs[0], originalErr
+	}
+
+	remainingGVRs := append([]schema.GroupVersionResource{}, originalGVRs...)
+	for _, pattern := range m.ResourcePriority {
+		matchedGVRs := []schema.GroupVersionResource{}
+		for _, gvr := range remainingGVRs {
+			if resourceMatches(pattern, gvr) {
+				matchedGVRs = append(matchedGVRs, gvr)
+			}
+		}
+
+		switch len(matchedGVRs) {
+		case 0:
+			// if you have no matches, then nothing matched this pattern just move to the next
+			continue
+		case 1:
+			// one match, return
+			return matchedGVRs[0], originalErr
+		default:
+			// more than one match, use the matched hits as the list moving to the next pattern.
+			// this way you can have a series of selection criteria
+			remainingGVRs = matchedGVRs
+		}
+	}
+
+	return schema.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: partiallySpecifiedResource, MatchingResources: originalGVRs}
+}
+
+// KindFor finds all kinds, then passes them through the KindPriority patterns to find a single matching hit.
+func (m PriorityRESTMapper) KindFor(partiallySpecifiedResource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
+	originalGVKs, originalErr := m.Delegate.KindsFor(partiallySpecifiedResource)
+	if originalErr != nil && len(originalGVKs) == 0 {
+		return schema.GroupVersionKind{}, originalErr
+	}
+	if len(originalGVKs) == 1 {
+		return originalGVKs[0], originalErr
+	}
+
+	remainingGVKs := append([]schema.GroupVersionKind{}, originalGVKs...)
+	for _, pattern := range m.KindPriority {
+		matchedGVKs := []schema.GroupVersionKind{}
+		for _, gvr := range remainingGVKs {
+			if kindMatches(pattern, gvr) {
+				matchedGVKs = append(matchedGVKs, gvr)
+			}
+		}
+
+		switch len(matchedGVKs) {
+		case 0:
+			// if you have no matches, then nothing matched this pattern just move to the next
+			continue
+		case 1:
+			// one match, return
+			return matchedGVKs[0], originalErr
+		default:
+			// more than one match, use the matched hits as the list moving to the next pattern.
+			// this way you can have a series of selection criteria
+			remainingGVKs = matchedGVKs
+		}
+	}
+
+	return schema.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: partiallySpecifiedResource, MatchingKinds: originalGVKs}
+}
+
+func resourceMatches(pattern schema.GroupVersionResource, resource schema.GroupVersionResource) bool {
+	if pattern.Group != AnyGroup && pattern.Group != resource.Group {
+		return false
+	}
+	if pattern.Version != AnyVersion && pattern.Version != resource.Version {
+		return false
+	}
+	if pattern.Resource != AnyResource && pattern.Resource != resource.Resource {
+		return false
+	}
+
+	return true
+}
+
+func kindMatches(pattern schema.GroupVersionKind, kind schema.GroupVersionKind) bool {
+	if pattern.Group != AnyGroup && pattern.Group != kind.Group {
+		return false
+	}
+	if pattern.Version != AnyVersion && pattern.Version != kind.Version {
+		return false
+	}
+	if pattern.Kind != AnyKind && pattern.Kind != kind.Kind {
+		return false
+	}
+
+	return true
+}
+
+func (m PriorityRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (mapping *RESTMapping, err error) {
+	mappings, originalErr := m.Delegate.RESTMappings(gk, versions...)
+	if originalErr != nil && len(mappings) == 0 {
+		return nil, originalErr
+	}
+
+	// any versions the user provides take priority
+	priorities := m.KindPriority
+	if len(versions) > 0 {
+		priorities = make([]schema.GroupVersionKind, 0, len(m.KindPriority)+len(versions))
+		for _, version := range versions {
+			gv := schema.GroupVersion{
+				Version: version,
+				Group:   gk.Group,
+			}
+			priorities = append(priorities, gv.WithKind(AnyKind))
+		}
+		priorities = append(priorities, m.KindPriority...)
+	}
+
+	remaining := append([]*RESTMapping{}, mappings...)
+	for _, pattern := range priorities {
+		var matching []*RESTMapping
+		for _, m := range remaining {
+			if kindMatches(pattern, m.GroupVersionKind) {
+				matching = append(matching, m)
+			}
+		}
+
+		switch len(matching) {
+		case 0:
+			// if you have no matches, then nothing matched this pattern just move to the next
+			continue
+		case 1:
+			// one match, return
+			return matching[0], originalErr
+		default:
+			// more than one match, use the matched hits as the list moving to the next pattern.
+			// this way you can have a series of selection criteria
+			remaining = matching
+		}
+	}
+	if len(remaining) == 1 {
+		return remaining[0], originalErr
+	}
+
+	var kinds []schema.GroupVersionKind
+	for _, m := range mappings {
+		kinds = append(kinds, m.GroupVersionKind)
+	}
+	return nil, &AmbiguousKindError{PartialKind: gk.WithVersion(""), MatchingKinds: kinds}
+}
+
+func (m PriorityRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) {
+	return m.Delegate.RESTMappings(gk, versions...)
+}
+
+func (m PriorityRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
+	return m.Delegate.ResourceSingularizer(resource)
+}
+
+func (m PriorityRESTMapper) ResourcesFor(partiallySpecifiedResource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) {
+	return m.Delegate.ResourcesFor(partiallySpecifiedResource)
+}
+
+func (m PriorityRESTMapper) KindsFor(partiallySpecifiedResource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) {
+	return m.Delegate.KindsFor(partiallySpecifiedResource)
+}