mirror of
https://github.com/kubernetes-sigs/prometheus-adapter.git
synced 2026-04-07 02:07:58 +00:00
Check in the vendor directory
Travis seems to be having issues pulling deps, so we'll have to check in the vendor directory and prevent the makefile from trying to regenerate it normally.
This commit is contained in:
parent
98e16bc315
commit
a293b2bf94
2526 changed files with 930931 additions and 4 deletions
25
vendor/k8s.io/apimachinery/pkg/api/meta/OWNERS
generated
vendored
Executable file
25
vendor/k8s.io/apimachinery/pkg/api/meta/OWNERS
generated
vendored
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
reviewers:
|
||||
- thockin
|
||||
- smarterclayton
|
||||
- wojtek-t
|
||||
- deads2k
|
||||
- brendandburns
|
||||
- derekwaynecarr
|
||||
- caesarxuchao
|
||||
- mikedanese
|
||||
- liggitt
|
||||
- nikhiljindal
|
||||
- gmarek
|
||||
- janetkuo
|
||||
- ncdc
|
||||
- eparis
|
||||
- dims
|
||||
- krousey
|
||||
- markturansky
|
||||
- fabioy
|
||||
- resouer
|
||||
- david-mcmahon
|
||||
- mfojtik
|
||||
- jianhuiz
|
||||
- feihujiang
|
||||
- ghodss
|
||||
19
vendor/k8s.io/apimachinery/pkg/api/meta/doc.go
generated
vendored
Normal file
19
vendor/k8s.io/apimachinery/pkg/api/meta/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
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 meta provides functions for retrieving API metadata from objects
|
||||
// belonging to the Kubernetes API
|
||||
package meta // import "k8s.io/apimachinery/pkg/api/meta"
|
||||
121
vendor/k8s.io/apimachinery/pkg/api/meta/errors.go
generated
vendored
Normal file
121
vendor/k8s.io/apimachinery/pkg/api/meta/errors.go
generated
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
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 meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
)
|
||||
|
||||
// AmbiguousResourceError is returned if the RESTMapper finds multiple matches for a resource
|
||||
type AmbiguousResourceError struct {
|
||||
PartialResource schema.GroupVersionResource
|
||||
|
||||
MatchingResources []schema.GroupVersionResource
|
||||
MatchingKinds []schema.GroupVersionKind
|
||||
}
|
||||
|
||||
func (e *AmbiguousResourceError) Error() string {
|
||||
switch {
|
||||
case len(e.MatchingKinds) > 0 && len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v and kinds %v", e.PartialResource, e.MatchingResources, e.MatchingKinds)
|
||||
case len(e.MatchingKinds) > 0:
|
||||
return fmt.Sprintf("%v matches multiple kinds %v", e.PartialResource, e.MatchingKinds)
|
||||
case len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v", e.PartialResource, e.MatchingResources)
|
||||
}
|
||||
return fmt.Sprintf("%v matches multiple resources or kinds", e.PartialResource)
|
||||
}
|
||||
|
||||
// AmbiguousKindError is returned if the RESTMapper finds multiple matches for a kind
|
||||
type AmbiguousKindError struct {
|
||||
PartialKind schema.GroupVersionKind
|
||||
|
||||
MatchingResources []schema.GroupVersionResource
|
||||
MatchingKinds []schema.GroupVersionKind
|
||||
}
|
||||
|
||||
func (e *AmbiguousKindError) Error() string {
|
||||
switch {
|
||||
case len(e.MatchingKinds) > 0 && len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v and kinds %v", e.PartialKind, e.MatchingResources, e.MatchingKinds)
|
||||
case len(e.MatchingKinds) > 0:
|
||||
return fmt.Sprintf("%v matches multiple kinds %v", e.PartialKind, e.MatchingKinds)
|
||||
case len(e.MatchingResources) > 0:
|
||||
return fmt.Sprintf("%v matches multiple resources %v", e.PartialKind, e.MatchingResources)
|
||||
}
|
||||
return fmt.Sprintf("%v matches multiple resources or kinds", e.PartialKind)
|
||||
}
|
||||
|
||||
func IsAmbiguousError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
switch err.(type) {
|
||||
case *AmbiguousResourceError, *AmbiguousKindError:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// NoResourceMatchError is returned if the RESTMapper can't find any match for a resource
|
||||
type NoResourceMatchError struct {
|
||||
PartialResource schema.GroupVersionResource
|
||||
}
|
||||
|
||||
func (e *NoResourceMatchError) Error() string {
|
||||
return fmt.Sprintf("no matches for %v", e.PartialResource)
|
||||
}
|
||||
|
||||
// NoKindMatchError is returned if the RESTMapper can't find any match for a kind
|
||||
type NoKindMatchError struct {
|
||||
// GroupKind is the API group and kind that was searched
|
||||
GroupKind schema.GroupKind
|
||||
// SearchedVersions is the optional list of versions the search was restricted to
|
||||
SearchedVersions []string
|
||||
}
|
||||
|
||||
func (e *NoKindMatchError) Error() string {
|
||||
searchedVersions := sets.NewString()
|
||||
for _, v := range e.SearchedVersions {
|
||||
searchedVersions.Insert(schema.GroupVersion{Group: e.GroupKind.Group, Version: v}.String())
|
||||
}
|
||||
|
||||
switch len(searchedVersions) {
|
||||
case 0:
|
||||
return fmt.Sprintf("no matches for kind %q in group %q", e.GroupKind.Kind, e.GroupKind.Group)
|
||||
case 1:
|
||||
return fmt.Sprintf("no matches for kind %q in version %q", e.GroupKind.Kind, searchedVersions.List()[0])
|
||||
default:
|
||||
return fmt.Sprintf("no matches for kind %q in versions %q", e.GroupKind.Kind, searchedVersions.List())
|
||||
}
|
||||
}
|
||||
|
||||
func IsNoMatchError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
switch err.(type) {
|
||||
case *NoResourceMatchError, *NoKindMatchError:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
97
vendor/k8s.io/apimachinery/pkg/api/meta/firsthit_restmapper.go
generated
vendored
Normal file
97
vendor/k8s.io/apimachinery/pkg/api/meta/firsthit_restmapper.go
generated
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
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 meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
)
|
||||
|
||||
// FirstHitRESTMapper is a wrapper for multiple RESTMappers which returns the
|
||||
// first successful result for the singular requests
|
||||
type FirstHitRESTMapper struct {
|
||||
MultiRESTMapper
|
||||
}
|
||||
|
||||
func (m FirstHitRESTMapper) String() string {
|
||||
return fmt.Sprintf("FirstHitRESTMapper{\n\t%v\n}", m.MultiRESTMapper)
|
||||
}
|
||||
|
||||
func (m FirstHitRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) {
|
||||
errors := []error{}
|
||||
for _, t := range m.MultiRESTMapper {
|
||||
ret, err := t.ResourceFor(resource)
|
||||
if err == nil {
|
||||
return ret, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
||||
return schema.GroupVersionResource{}, collapseAggregateErrors(errors)
|
||||
}
|
||||
|
||||
func (m FirstHitRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||
errors := []error{}
|
||||
for _, t := range m.MultiRESTMapper {
|
||||
ret, err := t.KindFor(resource)
|
||||
if err == nil {
|
||||
return ret, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
||||
return schema.GroupVersionKind{}, collapseAggregateErrors(errors)
|
||||
}
|
||||
|
||||
// RESTMapping provides the REST mapping for the resource based on the
|
||||
// kind and version. This implementation supports multiple REST schemas and
|
||||
// return the first match.
|
||||
func (m FirstHitRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error) {
|
||||
errors := []error{}
|
||||
for _, t := range m.MultiRESTMapper {
|
||||
ret, err := t.RESTMapping(gk, versions...)
|
||||
if err == nil {
|
||||
return ret, nil
|
||||
}
|
||||
errors = append(errors, err)
|
||||
}
|
||||
|
||||
return nil, collapseAggregateErrors(errors)
|
||||
}
|
||||
|
||||
// collapseAggregateErrors returns the minimal errors. it handles empty as nil, handles one item in a list
|
||||
// by returning the item, and collapses all NoMatchErrors to a single one (since they should all be the same)
|
||||
func collapseAggregateErrors(errors []error) error {
|
||||
if len(errors) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(errors) == 1 {
|
||||
return errors[0]
|
||||
}
|
||||
|
||||
allNoMatchErrors := true
|
||||
for _, err := range errors {
|
||||
allNoMatchErrors = allNoMatchErrors && IsNoMatchError(err)
|
||||
}
|
||||
if allNoMatchErrors {
|
||||
return errors[0]
|
||||
}
|
||||
|
||||
return utilerrors.NewAggregate(errors)
|
||||
}
|
||||
205
vendor/k8s.io/apimachinery/pkg/api/meta/help.go
generated
vendored
Normal file
205
vendor/k8s.io/apimachinery/pkg/api/meta/help.go
generated
vendored
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// IsListType returns true if the provided Object has a slice called Items
|
||||
func IsListType(obj runtime.Object) bool {
|
||||
// if we're a runtime.Unstructured, check whether this is a list.
|
||||
// TODO: refactor GetItemsPtr to use an interface that returns []runtime.Object
|
||||
if unstructured, ok := obj.(runtime.Unstructured); ok {
|
||||
return unstructured.IsList()
|
||||
}
|
||||
|
||||
_, err := GetItemsPtr(obj)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// GetItemsPtr returns a pointer to the list object's Items member.
|
||||
// If 'list' doesn't have an Items member, it's not really a list type
|
||||
// and an error will be returned.
|
||||
// This function will either return a pointer to a slice, or an error, but not both.
|
||||
func GetItemsPtr(list runtime.Object) (interface{}, error) {
|
||||
v, err := conversion.EnforcePtr(list)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := v.FieldByName("Items")
|
||||
if !items.IsValid() {
|
||||
return nil, fmt.Errorf("no Items field in %#v", list)
|
||||
}
|
||||
switch items.Kind() {
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
target := reflect.TypeOf(items.Interface()).Elem()
|
||||
if target.Kind() != reflect.Slice {
|
||||
return nil, fmt.Errorf("items: Expected slice, got %s", target.Kind())
|
||||
}
|
||||
return items.Interface(), nil
|
||||
case reflect.Slice:
|
||||
return items.Addr().Interface(), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("items: Expected slice, got %s", items.Kind())
|
||||
}
|
||||
}
|
||||
|
||||
// EachListItem invokes fn on each runtime.Object in the list. Any error immediately terminates
|
||||
// the loop.
|
||||
func EachListItem(obj runtime.Object, fn func(runtime.Object) error) error {
|
||||
if unstructured, ok := obj.(runtime.Unstructured); ok {
|
||||
return unstructured.EachListItem(fn)
|
||||
}
|
||||
// TODO: Change to an interface call?
|
||||
itemsPtr, err := GetItemsPtr(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
items, err := conversion.EnforcePtr(itemsPtr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
len := items.Len()
|
||||
if len == 0 {
|
||||
return nil
|
||||
}
|
||||
takeAddr := false
|
||||
if elemType := items.Type().Elem(); elemType.Kind() != reflect.Ptr && elemType.Kind() != reflect.Interface {
|
||||
if !items.Index(0).CanAddr() {
|
||||
return fmt.Errorf("unable to take address of items in %T for EachListItem", obj)
|
||||
}
|
||||
takeAddr = true
|
||||
}
|
||||
|
||||
for i := 0; i < len; i++ {
|
||||
raw := items.Index(i)
|
||||
if takeAddr {
|
||||
raw = raw.Addr()
|
||||
}
|
||||
switch item := raw.Interface().(type) {
|
||||
case *runtime.RawExtension:
|
||||
if err := fn(item.Object); err != nil {
|
||||
return err
|
||||
}
|
||||
case runtime.Object:
|
||||
if err := fn(item); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
obj, ok := item.(runtime.Object)
|
||||
if !ok {
|
||||
return fmt.Errorf("%v: item[%v]: Expected object, got %#v(%s)", obj, i, raw.Interface(), raw.Kind())
|
||||
}
|
||||
if err := fn(obj); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExtractList returns obj's Items element as an array of runtime.Objects.
|
||||
// Returns an error if obj is not a List type (does not have an Items member).
|
||||
func ExtractList(obj runtime.Object) ([]runtime.Object, error) {
|
||||
itemsPtr, err := GetItemsPtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items, err := conversion.EnforcePtr(itemsPtr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list := make([]runtime.Object, items.Len())
|
||||
for i := range list {
|
||||
raw := items.Index(i)
|
||||
switch item := raw.Interface().(type) {
|
||||
case runtime.RawExtension:
|
||||
switch {
|
||||
case item.Object != nil:
|
||||
list[i] = item.Object
|
||||
case item.Raw != nil:
|
||||
// TODO: Set ContentEncoding and ContentType correctly.
|
||||
list[i] = &runtime.Unknown{Raw: item.Raw}
|
||||
default:
|
||||
list[i] = nil
|
||||
}
|
||||
case runtime.Object:
|
||||
list[i] = item
|
||||
default:
|
||||
var found bool
|
||||
if list[i], found = raw.Addr().Interface().(runtime.Object); !found {
|
||||
return nil, fmt.Errorf("%v: item[%v]: Expected object, got %#v(%s)", obj, i, raw.Interface(), raw.Kind())
|
||||
}
|
||||
}
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// objectSliceType is the type of a slice of Objects
|
||||
var objectSliceType = reflect.TypeOf([]runtime.Object{})
|
||||
|
||||
// SetList sets the given list object's Items member have the elements given in
|
||||
// objects.
|
||||
// Returns an error if list is not a List type (does not have an Items member),
|
||||
// or if any of the objects are not of the right type.
|
||||
func SetList(list runtime.Object, objects []runtime.Object) error {
|
||||
itemsPtr, err := GetItemsPtr(list)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
items, err := conversion.EnforcePtr(itemsPtr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if items.Type() == objectSliceType {
|
||||
items.Set(reflect.ValueOf(objects))
|
||||
return nil
|
||||
}
|
||||
slice := reflect.MakeSlice(items.Type(), len(objects), len(objects))
|
||||
for i := range objects {
|
||||
dest := slice.Index(i)
|
||||
if dest.Type() == reflect.TypeOf(runtime.RawExtension{}) {
|
||||
dest = dest.FieldByName("Object")
|
||||
}
|
||||
|
||||
// check to see if you're directly assignable
|
||||
if reflect.TypeOf(objects[i]).AssignableTo(dest.Type()) {
|
||||
dest.Set(reflect.ValueOf(objects[i]))
|
||||
continue
|
||||
}
|
||||
|
||||
src, err := conversion.EnforcePtr(objects[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if src.Type().AssignableTo(dest.Type()) {
|
||||
dest.Set(src)
|
||||
} else if src.Type().ConvertibleTo(dest.Type()) {
|
||||
dest.Set(src.Convert(dest.Type()))
|
||||
} else {
|
||||
return fmt.Errorf("item[%d]: can't assign or convert %v into %v", i, src.Type(), dest.Type())
|
||||
}
|
||||
}
|
||||
items.Set(slice)
|
||||
return nil
|
||||
}
|
||||
134
vendor/k8s.io/apimachinery/pkg/api/meta/interfaces.go
generated
vendored
Normal file
134
vendor/k8s.io/apimachinery/pkg/api/meta/interfaces.go
generated
vendored
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
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 meta
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
type ListMetaAccessor interface {
|
||||
GetListMeta() List
|
||||
}
|
||||
|
||||
// List lets you work with list metadata from any of the versioned or
|
||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||
// not support that field will be a no-op and return a default value.
|
||||
type List metav1.ListInterface
|
||||
|
||||
// Type exposes the type and APIVersion of versioned or internal API objects.
|
||||
type Type metav1.Type
|
||||
|
||||
// MetadataAccessor lets you work with object and list metadata from any of the versioned or
|
||||
// internal API objects. Attempting to set or retrieve a field on an object that does
|
||||
// not support that field (Name, UID, Namespace on lists) will be a no-op and return
|
||||
// a default value.
|
||||
//
|
||||
// MetadataAccessor exposes Interface in a way that can be used with multiple objects.
|
||||
type MetadataAccessor interface {
|
||||
APIVersion(obj runtime.Object) (string, error)
|
||||
SetAPIVersion(obj runtime.Object, version string) error
|
||||
|
||||
Kind(obj runtime.Object) (string, error)
|
||||
SetKind(obj runtime.Object, kind string) error
|
||||
|
||||
Namespace(obj runtime.Object) (string, error)
|
||||
SetNamespace(obj runtime.Object, namespace string) error
|
||||
|
||||
Name(obj runtime.Object) (string, error)
|
||||
SetName(obj runtime.Object, name string) error
|
||||
|
||||
GenerateName(obj runtime.Object) (string, error)
|
||||
SetGenerateName(obj runtime.Object, name string) error
|
||||
|
||||
UID(obj runtime.Object) (types.UID, error)
|
||||
SetUID(obj runtime.Object, uid types.UID) error
|
||||
|
||||
SelfLink(obj runtime.Object) (string, error)
|
||||
SetSelfLink(obj runtime.Object, selfLink string) error
|
||||
|
||||
Labels(obj runtime.Object) (map[string]string, error)
|
||||
SetLabels(obj runtime.Object, labels map[string]string) error
|
||||
|
||||
Annotations(obj runtime.Object) (map[string]string, error)
|
||||
SetAnnotations(obj runtime.Object, annotations map[string]string) error
|
||||
|
||||
Continue(obj runtime.Object) (string, error)
|
||||
SetContinue(obj runtime.Object, c string) error
|
||||
|
||||
runtime.ResourceVersioner
|
||||
}
|
||||
|
||||
type RESTScopeName string
|
||||
|
||||
const (
|
||||
RESTScopeNameNamespace RESTScopeName = "namespace"
|
||||
RESTScopeNameRoot RESTScopeName = "root"
|
||||
)
|
||||
|
||||
// RESTScope contains the information needed to deal with REST resources that are in a resource hierarchy
|
||||
type RESTScope interface {
|
||||
// Name of the scope
|
||||
Name() RESTScopeName
|
||||
}
|
||||
|
||||
// RESTMapping contains the information needed to deal with objects of a specific
|
||||
// resource and kind in a RESTful manner.
|
||||
type RESTMapping struct {
|
||||
// Resource is the GroupVersionResource (location) for this endpoint
|
||||
Resource schema.GroupVersionResource
|
||||
|
||||
// GroupVersionKind is the GroupVersionKind (data format) to submit to this endpoint
|
||||
GroupVersionKind schema.GroupVersionKind
|
||||
|
||||
// Scope contains the information needed to deal with REST Resources that are in a resource hierarchy
|
||||
Scope RESTScope
|
||||
}
|
||||
|
||||
// RESTMapper allows clients to map resources to kind, and map kind and version
|
||||
// to interfaces for manipulating those objects. It is primarily intended for
|
||||
// consumers of Kubernetes compatible REST APIs as defined in docs/devel/api-conventions.md.
|
||||
//
|
||||
// The Kubernetes API provides versioned resources and object kinds which are scoped
|
||||
// to API groups. In other words, kinds and resources should not be assumed to be
|
||||
// unique across groups.
|
||||
//
|
||||
// TODO: split into sub-interfaces
|
||||
type RESTMapper interface {
|
||||
// KindFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
|
||||
KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error)
|
||||
|
||||
// KindsFor takes a partial resource and returns the list of potential kinds in priority order
|
||||
KindsFor(resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error)
|
||||
|
||||
// ResourceFor takes a partial resource and returns the single match. Returns an error if there are multiple matches
|
||||
ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error)
|
||||
|
||||
// ResourcesFor takes a partial resource and returns the list of potential resource in priority order
|
||||
ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error)
|
||||
|
||||
// RESTMapping identifies a preferred resource mapping for the provided group kind.
|
||||
RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error)
|
||||
// RESTMappings returns all resource mappings for the provided group kind if no
|
||||
// version search is provided. Otherwise identifies a preferred resource mapping for
|
||||
// the provided version(s).
|
||||
RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error)
|
||||
|
||||
ResourceSingularizer(resource string) (singular string, err error)
|
||||
}
|
||||
104
vendor/k8s.io/apimachinery/pkg/api/meta/lazy.go
generated
vendored
Normal file
104
vendor/k8s.io/apimachinery/pkg/api/meta/lazy.go
generated
vendored
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package meta
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// lazyObject defers loading the mapper and typer until necessary.
|
||||
type lazyObject struct {
|
||||
loader func() (RESTMapper, error)
|
||||
|
||||
lock sync.Mutex
|
||||
loaded bool
|
||||
err error
|
||||
mapper RESTMapper
|
||||
}
|
||||
|
||||
// NewLazyObjectLoader handles unrecoverable errors when creating a RESTMapper / ObjectTyper by
|
||||
// returning those initialization errors when the interface methods are invoked. This defers the
|
||||
// initialization and any server calls until a client actually needs to perform the action.
|
||||
func NewLazyRESTMapperLoader(fn func() (RESTMapper, error)) RESTMapper {
|
||||
obj := &lazyObject{loader: fn}
|
||||
return obj
|
||||
}
|
||||
|
||||
// init lazily loads the mapper and typer, returning an error if initialization has failed.
|
||||
func (o *lazyObject) init() error {
|
||||
o.lock.Lock()
|
||||
defer o.lock.Unlock()
|
||||
if o.loaded {
|
||||
return o.err
|
||||
}
|
||||
o.mapper, o.err = o.loader()
|
||||
o.loaded = true
|
||||
return o.err
|
||||
}
|
||||
|
||||
var _ RESTMapper = &lazyObject{}
|
||||
|
||||
func (o *lazyObject) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||
if err := o.init(); err != nil {
|
||||
return schema.GroupVersionKind{}, err
|
||||
}
|
||||
return o.mapper.KindFor(resource)
|
||||
}
|
||||
|
||||
func (o *lazyObject) KindsFor(resource schema.GroupVersionResource) ([]schema.GroupVersionKind, error) {
|
||||
if err := o.init(); err != nil {
|
||||
return []schema.GroupVersionKind{}, err
|
||||
}
|
||||
return o.mapper.KindsFor(resource)
|
||||
}
|
||||
|
||||
func (o *lazyObject) ResourceFor(input schema.GroupVersionResource) (schema.GroupVersionResource, error) {
|
||||
if err := o.init(); err != nil {
|
||||
return schema.GroupVersionResource{}, err
|
||||
}
|
||||
return o.mapper.ResourceFor(input)
|
||||
}
|
||||
|
||||
func (o *lazyObject) ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) {
|
||||
if err := o.init(); err != nil {
|
||||
return []schema.GroupVersionResource{}, err
|
||||
}
|
||||
return o.mapper.ResourcesFor(input)
|
||||
}
|
||||
|
||||
func (o *lazyObject) RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error) {
|
||||
if err := o.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return o.mapper.RESTMapping(gk, versions...)
|
||||
}
|
||||
|
||||
func (o *lazyObject) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) {
|
||||
if err := o.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return o.mapper.RESTMappings(gk, versions...)
|
||||
}
|
||||
|
||||
func (o *lazyObject) ResourceSingularizer(resource string) (singular string, err error) {
|
||||
if err := o.init(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return o.mapper.ResourceSingularizer(resource)
|
||||
}
|
||||
650
vendor/k8s.io/apimachinery/pkg/api/meta/meta.go
generated
vendored
Normal file
650
vendor/k8s.io/apimachinery/pkg/api/meta/meta.go
generated
vendored
Normal file
|
|
@ -0,0 +1,650 @@
|
|||
/*
|
||||
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 meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/conversion"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
// errNotList is returned when an object implements the Object style interfaces but not the List style
|
||||
// interfaces.
|
||||
var errNotList = fmt.Errorf("object does not implement the List interfaces")
|
||||
|
||||
var errNotCommon = fmt.Errorf("object does not implement the common interface for accessing the SelfLink")
|
||||
|
||||
// CommonAccessor returns a Common interface for the provided object or an error if the object does
|
||||
// not provide List.
|
||||
func CommonAccessor(obj interface{}) (metav1.Common, error) {
|
||||
switch t := obj.(type) {
|
||||
case List:
|
||||
return t, nil
|
||||
case metav1.ListInterface:
|
||||
return t, nil
|
||||
case ListMetaAccessor:
|
||||
if m := t.GetListMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotCommon
|
||||
case metav1.ListMetaAccessor:
|
||||
if m := t.GetListMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotCommon
|
||||
case metav1.Object:
|
||||
return t, nil
|
||||
case metav1.ObjectMetaAccessor:
|
||||
if m := t.GetObjectMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotCommon
|
||||
default:
|
||||
return nil, errNotCommon
|
||||
}
|
||||
}
|
||||
|
||||
// ListAccessor returns a List interface for the provided object or an error if the object does
|
||||
// not provide List.
|
||||
// IMPORTANT: Objects are NOT a superset of lists. Do not use this check to determine whether an
|
||||
// object *is* a List.
|
||||
func ListAccessor(obj interface{}) (List, error) {
|
||||
switch t := obj.(type) {
|
||||
case List:
|
||||
return t, nil
|
||||
case metav1.ListInterface:
|
||||
return t, nil
|
||||
case ListMetaAccessor:
|
||||
if m := t.GetListMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotList
|
||||
case metav1.ListMetaAccessor:
|
||||
if m := t.GetListMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotList
|
||||
default:
|
||||
return nil, errNotList
|
||||
}
|
||||
}
|
||||
|
||||
// errNotObject is returned when an object implements the List style interfaces but not the Object style
|
||||
// interfaces.
|
||||
var errNotObject = fmt.Errorf("object does not implement the Object interfaces")
|
||||
|
||||
// Accessor takes an arbitrary object pointer and returns meta.Interface.
|
||||
// obj must be a pointer to an API type. An error is returned if the minimum
|
||||
// required fields are missing. Fields that are not required return the default
|
||||
// value and are a no-op if set.
|
||||
func Accessor(obj interface{}) (metav1.Object, error) {
|
||||
switch t := obj.(type) {
|
||||
case metav1.Object:
|
||||
return t, nil
|
||||
case metav1.ObjectMetaAccessor:
|
||||
if m := t.GetObjectMeta(); m != nil {
|
||||
return m, nil
|
||||
}
|
||||
return nil, errNotObject
|
||||
default:
|
||||
return nil, errNotObject
|
||||
}
|
||||
}
|
||||
|
||||
// AsPartialObjectMetadata takes the metav1 interface and returns a partial object.
|
||||
// TODO: consider making this solely a conversion action.
|
||||
func AsPartialObjectMetadata(m metav1.Object) *metav1beta1.PartialObjectMetadata {
|
||||
switch t := m.(type) {
|
||||
case *metav1.ObjectMeta:
|
||||
return &metav1beta1.PartialObjectMetadata{ObjectMeta: *t}
|
||||
default:
|
||||
return &metav1beta1.PartialObjectMetadata{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: m.GetName(),
|
||||
GenerateName: m.GetGenerateName(),
|
||||
Namespace: m.GetNamespace(),
|
||||
SelfLink: m.GetSelfLink(),
|
||||
UID: m.GetUID(),
|
||||
ResourceVersion: m.GetResourceVersion(),
|
||||
Generation: m.GetGeneration(),
|
||||
CreationTimestamp: m.GetCreationTimestamp(),
|
||||
DeletionTimestamp: m.GetDeletionTimestamp(),
|
||||
DeletionGracePeriodSeconds: m.GetDeletionGracePeriodSeconds(),
|
||||
Labels: m.GetLabels(),
|
||||
Annotations: m.GetAnnotations(),
|
||||
OwnerReferences: m.GetOwnerReferences(),
|
||||
Finalizers: m.GetFinalizers(),
|
||||
ClusterName: m.GetClusterName(),
|
||||
Initializers: m.GetInitializers(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TypeAccessor returns an interface that allows retrieving and modifying the APIVersion
|
||||
// and Kind of an in-memory internal object.
|
||||
// TODO: this interface is used to test code that does not have ObjectMeta or ListMeta
|
||||
// in round tripping (objects which can use apiVersion/kind, but do not fit the Kube
|
||||
// api conventions).
|
||||
func TypeAccessor(obj interface{}) (Type, error) {
|
||||
if typed, ok := obj.(runtime.Object); ok {
|
||||
return objectAccessor{typed}, nil
|
||||
}
|
||||
v, err := conversion.EnforcePtr(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t := v.Type()
|
||||
if v.Kind() != reflect.Struct {
|
||||
return nil, fmt.Errorf("expected struct, but got %v: %v (%#v)", v.Kind(), t, v.Interface())
|
||||
}
|
||||
|
||||
typeMeta := v.FieldByName("TypeMeta")
|
||||
if !typeMeta.IsValid() {
|
||||
return nil, fmt.Errorf("struct %v lacks embedded TypeMeta type", t)
|
||||
}
|
||||
a := &genericAccessor{}
|
||||
if err := extractFromTypeMeta(typeMeta, a); err != nil {
|
||||
return nil, fmt.Errorf("unable to find type fields on %#v: %v", typeMeta, err)
|
||||
}
|
||||
return a, nil
|
||||
}
|
||||
|
||||
type objectAccessor struct {
|
||||
runtime.Object
|
||||
}
|
||||
|
||||
func (obj objectAccessor) GetKind() string {
|
||||
return obj.GetObjectKind().GroupVersionKind().Kind
|
||||
}
|
||||
|
||||
func (obj objectAccessor) SetKind(kind string) {
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
gvk.Kind = kind
|
||||
obj.GetObjectKind().SetGroupVersionKind(gvk)
|
||||
}
|
||||
|
||||
func (obj objectAccessor) GetAPIVersion() string {
|
||||
return obj.GetObjectKind().GroupVersionKind().GroupVersion().String()
|
||||
}
|
||||
|
||||
func (obj objectAccessor) SetAPIVersion(version string) {
|
||||
gvk := obj.GetObjectKind().GroupVersionKind()
|
||||
gv, err := schema.ParseGroupVersion(version)
|
||||
if err != nil {
|
||||
gv = schema.GroupVersion{Version: version}
|
||||
}
|
||||
gvk.Group, gvk.Version = gv.Group, gv.Version
|
||||
obj.GetObjectKind().SetGroupVersionKind(gvk)
|
||||
}
|
||||
|
||||
// NewAccessor returns a MetadataAccessor that can retrieve
|
||||
// or manipulate resource version on objects derived from core API
|
||||
// metadata concepts.
|
||||
func NewAccessor() MetadataAccessor {
|
||||
return resourceAccessor{}
|
||||
}
|
||||
|
||||
// resourceAccessor implements ResourceVersioner and SelfLinker.
|
||||
type resourceAccessor struct{}
|
||||
|
||||
func (resourceAccessor) Kind(obj runtime.Object) (string, error) {
|
||||
return objectAccessor{obj}.GetKind(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetKind(obj runtime.Object, kind string) error {
|
||||
objectAccessor{obj}.SetKind(kind)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) APIVersion(obj runtime.Object) (string, error) {
|
||||
return objectAccessor{obj}.GetAPIVersion(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetAPIVersion(obj runtime.Object, version string) error {
|
||||
objectAccessor{obj}.SetAPIVersion(version)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Namespace(obj runtime.Object) (string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetNamespace(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetNamespace(obj runtime.Object, namespace string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetNamespace(namespace)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Name(obj runtime.Object) (string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetName(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetName(obj runtime.Object, name string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetName(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) GenerateName(obj runtime.Object) (string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetGenerateName(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetGenerateName(obj runtime.Object, name string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetGenerateName(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) UID(obj runtime.Object) (types.UID, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetUID(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetUID(obj runtime.Object, uid types.UID) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetUID(uid)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SelfLink(obj runtime.Object) (string, error) {
|
||||
accessor, err := CommonAccessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetSelfLink(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetSelfLink(obj runtime.Object, selfLink string) error {
|
||||
accessor, err := CommonAccessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetSelfLink(selfLink)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Labels(obj runtime.Object) (map[string]string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return accessor.GetLabels(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetLabels(obj runtime.Object, labels map[string]string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetLabels(labels)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Annotations(obj runtime.Object) (map[string]string, error) {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return accessor.GetAnnotations(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetAnnotations(obj runtime.Object, annotations map[string]string) error {
|
||||
accessor, err := Accessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetAnnotations(annotations)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) ResourceVersion(obj runtime.Object) (string, error) {
|
||||
accessor, err := CommonAccessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetResourceVersion(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetResourceVersion(obj runtime.Object, version string) error {
|
||||
accessor, err := CommonAccessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetResourceVersion(version)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) Continue(obj runtime.Object) (string, error) {
|
||||
accessor, err := ListAccessor(obj)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return accessor.GetContinue(), nil
|
||||
}
|
||||
|
||||
func (resourceAccessor) SetContinue(obj runtime.Object, version string) error {
|
||||
accessor, err := ListAccessor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
accessor.SetContinue(version)
|
||||
return nil
|
||||
}
|
||||
|
||||
// extractFromOwnerReference extracts v to o. v is the OwnerReferences field of an object.
|
||||
func extractFromOwnerReference(v reflect.Value, o *metav1.OwnerReference) error {
|
||||
if err := runtime.Field(v, "APIVersion", &o.APIVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.Field(v, "Kind", &o.Kind); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.Field(v, "Name", &o.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.Field(v, "UID", &o.UID); err != nil {
|
||||
return err
|
||||
}
|
||||
var controllerPtr *bool
|
||||
if err := runtime.Field(v, "Controller", &controllerPtr); err != nil {
|
||||
return err
|
||||
}
|
||||
if controllerPtr != nil {
|
||||
controller := *controllerPtr
|
||||
o.Controller = &controller
|
||||
}
|
||||
var blockOwnerDeletionPtr *bool
|
||||
if err := runtime.Field(v, "BlockOwnerDeletion", &blockOwnerDeletionPtr); err != nil {
|
||||
return err
|
||||
}
|
||||
if blockOwnerDeletionPtr != nil {
|
||||
block := *blockOwnerDeletionPtr
|
||||
o.BlockOwnerDeletion = &block
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// setOwnerReference sets v to o. v is the OwnerReferences field of an object.
|
||||
func setOwnerReference(v reflect.Value, o *metav1.OwnerReference) error {
|
||||
if err := runtime.SetField(o.APIVersion, v, "APIVersion"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.SetField(o.Kind, v, "Kind"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.SetField(o.Name, v, "Name"); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.SetField(o.UID, v, "UID"); err != nil {
|
||||
return err
|
||||
}
|
||||
if o.Controller != nil {
|
||||
controller := *(o.Controller)
|
||||
if err := runtime.SetField(&controller, v, "Controller"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if o.BlockOwnerDeletion != nil {
|
||||
block := *(o.BlockOwnerDeletion)
|
||||
if err := runtime.SetField(&block, v, "BlockOwnerDeletion"); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// genericAccessor contains pointers to strings that can modify an arbitrary
|
||||
// struct and implements the Accessor interface.
|
||||
type genericAccessor struct {
|
||||
namespace *string
|
||||
name *string
|
||||
generateName *string
|
||||
uid *types.UID
|
||||
apiVersion *string
|
||||
kind *string
|
||||
resourceVersion *string
|
||||
selfLink *string
|
||||
creationTimestamp *metav1.Time
|
||||
deletionTimestamp **metav1.Time
|
||||
labels *map[string]string
|
||||
annotations *map[string]string
|
||||
ownerReferences reflect.Value
|
||||
finalizers *[]string
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetNamespace() string {
|
||||
if a.namespace == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.namespace
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetNamespace(namespace string) {
|
||||
if a.namespace == nil {
|
||||
return
|
||||
}
|
||||
*a.namespace = namespace
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetName() string {
|
||||
if a.name == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.name
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetName(name string) {
|
||||
if a.name == nil {
|
||||
return
|
||||
}
|
||||
*a.name = name
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetGenerateName() string {
|
||||
if a.generateName == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.generateName
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetGenerateName(generateName string) {
|
||||
if a.generateName == nil {
|
||||
return
|
||||
}
|
||||
*a.generateName = generateName
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetUID() types.UID {
|
||||
if a.uid == nil {
|
||||
return ""
|
||||
}
|
||||
return *a.uid
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetUID(uid types.UID) {
|
||||
if a.uid == nil {
|
||||
return
|
||||
}
|
||||
*a.uid = uid
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetAPIVersion() string {
|
||||
return *a.apiVersion
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetAPIVersion(version string) {
|
||||
*a.apiVersion = version
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetKind() string {
|
||||
return *a.kind
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetKind(kind string) {
|
||||
*a.kind = kind
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetResourceVersion() string {
|
||||
return *a.resourceVersion
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetResourceVersion(version string) {
|
||||
*a.resourceVersion = version
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetSelfLink() string {
|
||||
return *a.selfLink
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetSelfLink(selfLink string) {
|
||||
*a.selfLink = selfLink
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetCreationTimestamp() metav1.Time {
|
||||
return *a.creationTimestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetCreationTimestamp(timestamp metav1.Time) {
|
||||
*a.creationTimestamp = timestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetDeletionTimestamp() *metav1.Time {
|
||||
return *a.deletionTimestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetDeletionTimestamp(timestamp *metav1.Time) {
|
||||
*a.deletionTimestamp = timestamp
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetLabels() map[string]string {
|
||||
if a.labels == nil {
|
||||
return nil
|
||||
}
|
||||
return *a.labels
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetLabels(labels map[string]string) {
|
||||
*a.labels = labels
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetAnnotations() map[string]string {
|
||||
if a.annotations == nil {
|
||||
return nil
|
||||
}
|
||||
return *a.annotations
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetAnnotations(annotations map[string]string) {
|
||||
if a.annotations == nil {
|
||||
emptyAnnotations := make(map[string]string)
|
||||
a.annotations = &emptyAnnotations
|
||||
}
|
||||
*a.annotations = annotations
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetFinalizers() []string {
|
||||
if a.finalizers == nil {
|
||||
return nil
|
||||
}
|
||||
return *a.finalizers
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetFinalizers(finalizers []string) {
|
||||
*a.finalizers = finalizers
|
||||
}
|
||||
|
||||
func (a genericAccessor) GetOwnerReferences() []metav1.OwnerReference {
|
||||
var ret []metav1.OwnerReference
|
||||
s := a.ownerReferences
|
||||
if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice {
|
||||
glog.Errorf("expect %v to be a pointer to slice", s)
|
||||
return ret
|
||||
}
|
||||
s = s.Elem()
|
||||
// Set the capacity to one element greater to avoid copy if the caller later append an element.
|
||||
ret = make([]metav1.OwnerReference, s.Len(), s.Len()+1)
|
||||
for i := 0; i < s.Len(); i++ {
|
||||
if err := extractFromOwnerReference(s.Index(i), &ret[i]); err != nil {
|
||||
glog.Errorf("extractFromOwnerReference failed: %v", err)
|
||||
return ret
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (a genericAccessor) SetOwnerReferences(references []metav1.OwnerReference) {
|
||||
s := a.ownerReferences
|
||||
if s.Kind() != reflect.Ptr || s.Elem().Kind() != reflect.Slice {
|
||||
glog.Errorf("expect %v to be a pointer to slice", s)
|
||||
}
|
||||
s = s.Elem()
|
||||
newReferences := reflect.MakeSlice(s.Type(), len(references), len(references))
|
||||
for i := 0; i < len(references); i++ {
|
||||
if err := setOwnerReference(newReferences.Index(i), &references[i]); err != nil {
|
||||
glog.Errorf("setOwnerReference failed: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
s.Set(newReferences)
|
||||
}
|
||||
|
||||
// extractFromTypeMeta extracts pointers to version and kind fields from an object
|
||||
func extractFromTypeMeta(v reflect.Value, a *genericAccessor) error {
|
||||
if err := runtime.FieldPtr(v, "APIVersion", &a.apiVersion); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := runtime.FieldPtr(v, "Kind", &a.kind); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
210
vendor/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go
generated
vendored
Normal file
210
vendor/k8s.io/apimachinery/pkg/api/meta/multirestmapper.go
generated
vendored
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
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 meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
)
|
||||
|
||||
// MultiRESTMapper is a wrapper for multiple RESTMappers.
|
||||
type MultiRESTMapper []RESTMapper
|
||||
|
||||
func (m MultiRESTMapper) String() string {
|
||||
nested := []string{}
|
||||
for _, t := range m {
|
||||
currString := fmt.Sprintf("%v", t)
|
||||
splitStrings := strings.Split(currString, "\n")
|
||||
nested = append(nested, strings.Join(splitStrings, "\n\t"))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("MultiRESTMapper{\n\t%s\n}", strings.Join(nested, "\n\t"))
|
||||
}
|
||||
|
||||
// ResourceSingularizer converts a REST resource name from plural to singular (e.g., from pods to pod)
|
||||
// This implementation supports multiple REST schemas and return the first match.
|
||||
func (m MultiRESTMapper) ResourceSingularizer(resource string) (singular string, err error) {
|
||||
for _, t := range m {
|
||||
singular, err = t.ResourceSingularizer(resource)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) ResourcesFor(resource schema.GroupVersionResource) ([]schema.GroupVersionResource, error) {
|
||||
allGVRs := []schema.GroupVersionResource{}
|
||||
for _, t := range m {
|
||||
gvrs, err := t.ResourcesFor(resource)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// walk the existing values to de-dup
|
||||
for _, curr := range gvrs {
|
||||
found := false
|
||||
for _, existing := range allGVRs {
|
||||
if curr == existing {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
allGVRs = append(allGVRs, curr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(allGVRs) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: resource}
|
||||
}
|
||||
|
||||
return allGVRs, nil
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) KindsFor(resource schema.GroupVersionResource) (gvk []schema.GroupVersionKind, err error) {
|
||||
allGVKs := []schema.GroupVersionKind{}
|
||||
for _, t := range m {
|
||||
gvks, err := t.KindsFor(resource)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// walk the existing values to de-dup
|
||||
for _, curr := range gvks {
|
||||
found := false
|
||||
for _, existing := range allGVKs {
|
||||
if curr == existing {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
allGVKs = append(allGVKs, curr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(allGVKs) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: resource}
|
||||
}
|
||||
|
||||
return allGVKs, nil
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) {
|
||||
resources, err := m.ResourcesFor(resource)
|
||||
if err != nil {
|
||||
return schema.GroupVersionResource{}, err
|
||||
}
|
||||
if len(resources) == 1 {
|
||||
return resources[0], nil
|
||||
}
|
||||
|
||||
return schema.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: resource, MatchingResources: resources}
|
||||
}
|
||||
|
||||
func (m MultiRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||
kinds, err := m.KindsFor(resource)
|
||||
if err != nil {
|
||||
return schema.GroupVersionKind{}, err
|
||||
}
|
||||
if len(kinds) == 1 {
|
||||
return kinds[0], nil
|
||||
}
|
||||
|
||||
return schema.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: resource, MatchingKinds: kinds}
|
||||
}
|
||||
|
||||
// RESTMapping provides the REST mapping for the resource based on the
|
||||
// kind and version. This implementation supports multiple REST schemas and
|
||||
// return the first match.
|
||||
func (m MultiRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error) {
|
||||
allMappings := []*RESTMapping{}
|
||||
errors := []error{}
|
||||
|
||||
for _, t := range m {
|
||||
currMapping, err := t.RESTMapping(gk, versions...)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
continue
|
||||
}
|
||||
|
||||
allMappings = append(allMappings, currMapping)
|
||||
}
|
||||
|
||||
// if we got exactly one mapping, then use it even if other requested failed
|
||||
if len(allMappings) == 1 {
|
||||
return allMappings[0], nil
|
||||
}
|
||||
if len(allMappings) > 1 {
|
||||
var kinds []schema.GroupVersionKind
|
||||
for _, m := range allMappings {
|
||||
kinds = append(kinds, m.GroupVersionKind)
|
||||
}
|
||||
return nil, &AmbiguousKindError{PartialKind: gk.WithVersion(""), MatchingKinds: kinds}
|
||||
}
|
||||
if len(errors) > 0 {
|
||||
return nil, utilerrors.NewAggregate(errors)
|
||||
}
|
||||
return nil, &NoKindMatchError{GroupKind: gk, SearchedVersions: versions}
|
||||
}
|
||||
|
||||
// RESTMappings returns all possible RESTMappings for the provided group kind, or an error
|
||||
// if the type is not recognized.
|
||||
func (m MultiRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) {
|
||||
var allMappings []*RESTMapping
|
||||
var errors []error
|
||||
|
||||
for _, t := range m {
|
||||
currMappings, err := t.RESTMappings(gk, versions...)
|
||||
// ignore "no match" errors, but any other error percolates back up
|
||||
if IsNoMatchError(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
errors = append(errors, err)
|
||||
continue
|
||||
}
|
||||
allMappings = append(allMappings, currMappings...)
|
||||
}
|
||||
if len(errors) > 0 {
|
||||
return nil, utilerrors.NewAggregate(errors)
|
||||
}
|
||||
if len(allMappings) == 0 {
|
||||
return nil, &NoKindMatchError{GroupKind: gk, SearchedVersions: versions}
|
||||
}
|
||||
return allMappings, nil
|
||||
}
|
||||
222
vendor/k8s.io/apimachinery/pkg/api/meta/priority.go
generated
vendored
Normal file
222
vendor/k8s.io/apimachinery/pkg/api/meta/priority.go
generated
vendored
Normal file
|
|
@ -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)
|
||||
}
|
||||
518
vendor/k8s.io/apimachinery/pkg/api/meta/restmapper.go
generated
vendored
Normal file
518
vendor/k8s.io/apimachinery/pkg/api/meta/restmapper.go
generated
vendored
Normal file
|
|
@ -0,0 +1,518 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
// TODO: move everything in this file to pkg/api/rest
|
||||
package meta
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// Implements RESTScope interface
|
||||
type restScope struct {
|
||||
name RESTScopeName
|
||||
}
|
||||
|
||||
func (r *restScope) Name() RESTScopeName {
|
||||
return r.name
|
||||
}
|
||||
|
||||
var RESTScopeNamespace = &restScope{
|
||||
name: RESTScopeNameNamespace,
|
||||
}
|
||||
|
||||
var RESTScopeRoot = &restScope{
|
||||
name: RESTScopeNameRoot,
|
||||
}
|
||||
|
||||
// DefaultRESTMapper exposes mappings between the types defined in a
|
||||
// runtime.Scheme. It assumes that all types defined the provided scheme
|
||||
// can be mapped with the provided MetadataAccessor and Codec interfaces.
|
||||
//
|
||||
// The resource name of a Kind is defined as the lowercase,
|
||||
// English-plural version of the Kind string.
|
||||
// When converting from resource to Kind, the singular version of the
|
||||
// resource name is also accepted for convenience.
|
||||
//
|
||||
// TODO: Only accept plural for some operations for increased control?
|
||||
// (`get pod bar` vs `get pods bar`)
|
||||
type DefaultRESTMapper struct {
|
||||
defaultGroupVersions []schema.GroupVersion
|
||||
|
||||
resourceToKind map[schema.GroupVersionResource]schema.GroupVersionKind
|
||||
kindToPluralResource map[schema.GroupVersionKind]schema.GroupVersionResource
|
||||
kindToScope map[schema.GroupVersionKind]RESTScope
|
||||
singularToPlural map[schema.GroupVersionResource]schema.GroupVersionResource
|
||||
pluralToSingular map[schema.GroupVersionResource]schema.GroupVersionResource
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) String() string {
|
||||
return fmt.Sprintf("DefaultRESTMapper{kindToPluralResource=%v}", m.kindToPluralResource)
|
||||
}
|
||||
|
||||
var _ RESTMapper = &DefaultRESTMapper{}
|
||||
|
||||
// NewDefaultRESTMapper initializes a mapping between Kind and APIVersion
|
||||
// to a resource name and back based on the objects in a runtime.Scheme
|
||||
// and the Kubernetes API conventions. Takes a group name, a priority list of the versions
|
||||
// to search when an object has no default version (set empty to return an error),
|
||||
// and a function that retrieves the correct metadata for a given version.
|
||||
func NewDefaultRESTMapper(defaultGroupVersions []schema.GroupVersion) *DefaultRESTMapper {
|
||||
resourceToKind := make(map[schema.GroupVersionResource]schema.GroupVersionKind)
|
||||
kindToPluralResource := make(map[schema.GroupVersionKind]schema.GroupVersionResource)
|
||||
kindToScope := make(map[schema.GroupVersionKind]RESTScope)
|
||||
singularToPlural := make(map[schema.GroupVersionResource]schema.GroupVersionResource)
|
||||
pluralToSingular := make(map[schema.GroupVersionResource]schema.GroupVersionResource)
|
||||
// TODO: verify name mappings work correctly when versions differ
|
||||
|
||||
return &DefaultRESTMapper{
|
||||
resourceToKind: resourceToKind,
|
||||
kindToPluralResource: kindToPluralResource,
|
||||
kindToScope: kindToScope,
|
||||
defaultGroupVersions: defaultGroupVersions,
|
||||
singularToPlural: singularToPlural,
|
||||
pluralToSingular: pluralToSingular,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) Add(kind schema.GroupVersionKind, scope RESTScope) {
|
||||
plural, singular := UnsafeGuessKindToResource(kind)
|
||||
m.AddSpecific(kind, plural, singular, scope)
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) AddSpecific(kind schema.GroupVersionKind, plural, singular schema.GroupVersionResource, scope RESTScope) {
|
||||
m.singularToPlural[singular] = plural
|
||||
m.pluralToSingular[plural] = singular
|
||||
|
||||
m.resourceToKind[singular] = kind
|
||||
m.resourceToKind[plural] = kind
|
||||
|
||||
m.kindToPluralResource[kind] = plural
|
||||
m.kindToScope[kind] = scope
|
||||
}
|
||||
|
||||
// unpluralizedSuffixes is a list of resource suffixes that are the same plural and singular
|
||||
// This is only is only necessary because some bits of code are lazy and don't actually use the RESTMapper like they should.
|
||||
// TODO eliminate this so that different callers can correctly map to resources. This probably means updating all
|
||||
// callers to use the RESTMapper they mean.
|
||||
var unpluralizedSuffixes = []string{
|
||||
"endpoints",
|
||||
}
|
||||
|
||||
// UnsafeGuessKindToResource converts Kind to a resource name.
|
||||
// Broken. This method only "sort of" works when used outside of this package. It assumes that Kinds and Resources match
|
||||
// and they aren't guaranteed to do so.
|
||||
func UnsafeGuessKindToResource(kind schema.GroupVersionKind) ( /*plural*/ schema.GroupVersionResource /*singular*/, schema.GroupVersionResource) {
|
||||
kindName := kind.Kind
|
||||
if len(kindName) == 0 {
|
||||
return schema.GroupVersionResource{}, schema.GroupVersionResource{}
|
||||
}
|
||||
singularName := strings.ToLower(kindName)
|
||||
singular := kind.GroupVersion().WithResource(singularName)
|
||||
|
||||
for _, skip := range unpluralizedSuffixes {
|
||||
if strings.HasSuffix(singularName, skip) {
|
||||
return singular, singular
|
||||
}
|
||||
}
|
||||
|
||||
switch string(singularName[len(singularName)-1]) {
|
||||
case "s":
|
||||
return kind.GroupVersion().WithResource(singularName + "es"), singular
|
||||
case "y":
|
||||
return kind.GroupVersion().WithResource(strings.TrimSuffix(singularName, "y") + "ies"), singular
|
||||
}
|
||||
|
||||
return kind.GroupVersion().WithResource(singularName + "s"), singular
|
||||
}
|
||||
|
||||
// ResourceSingularizer implements RESTMapper
|
||||
// It converts a resource name from plural to singular (e.g., from pods to pod)
|
||||
func (m *DefaultRESTMapper) ResourceSingularizer(resourceType string) (string, error) {
|
||||
partialResource := schema.GroupVersionResource{Resource: resourceType}
|
||||
resources, err := m.ResourcesFor(partialResource)
|
||||
if err != nil {
|
||||
return resourceType, err
|
||||
}
|
||||
|
||||
singular := schema.GroupVersionResource{}
|
||||
for _, curr := range resources {
|
||||
currSingular, ok := m.pluralToSingular[curr]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if singular.Empty() {
|
||||
singular = currSingular
|
||||
continue
|
||||
}
|
||||
|
||||
if currSingular.Resource != singular.Resource {
|
||||
return resourceType, fmt.Errorf("multiple possible singular resources (%v) found for %v", resources, resourceType)
|
||||
}
|
||||
}
|
||||
|
||||
if singular.Empty() {
|
||||
return resourceType, fmt.Errorf("no singular of resource %v has been defined", resourceType)
|
||||
}
|
||||
|
||||
return singular.Resource, nil
|
||||
}
|
||||
|
||||
// coerceResourceForMatching makes the resource lower case and converts internal versions to unspecified (legacy behavior)
|
||||
func coerceResourceForMatching(resource schema.GroupVersionResource) schema.GroupVersionResource {
|
||||
resource.Resource = strings.ToLower(resource.Resource)
|
||||
if resource.Version == runtime.APIVersionInternal {
|
||||
resource.Version = ""
|
||||
}
|
||||
|
||||
return resource
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) ResourcesFor(input schema.GroupVersionResource) ([]schema.GroupVersionResource, error) {
|
||||
resource := coerceResourceForMatching(input)
|
||||
|
||||
hasResource := len(resource.Resource) > 0
|
||||
hasGroup := len(resource.Group) > 0
|
||||
hasVersion := len(resource.Version) > 0
|
||||
|
||||
if !hasResource {
|
||||
return nil, fmt.Errorf("a resource must be present, got: %v", resource)
|
||||
}
|
||||
|
||||
ret := []schema.GroupVersionResource{}
|
||||
switch {
|
||||
case hasGroup && hasVersion:
|
||||
// fully qualified. Find the exact match
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular == resource {
|
||||
ret = append(ret, plural)
|
||||
break
|
||||
}
|
||||
if plural == resource {
|
||||
ret = append(ret, plural)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case hasGroup:
|
||||
// given a group, prefer an exact match. If you don't find one, resort to a prefix match on group
|
||||
foundExactMatch := false
|
||||
requestedGroupResource := resource.GroupResource()
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular.GroupResource() == requestedGroupResource {
|
||||
foundExactMatch = true
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.GroupResource() == requestedGroupResource {
|
||||
foundExactMatch = true
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
|
||||
// if you didn't find an exact match, match on group prefixing. This allows storageclass.storage to match
|
||||
// storageclass.storage.k8s.io
|
||||
if !foundExactMatch {
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if !strings.HasPrefix(plural.Group, requestedGroupResource.Group) {
|
||||
continue
|
||||
}
|
||||
if singular.Resource == requestedGroupResource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.Resource == requestedGroupResource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case hasVersion:
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular.Version == resource.Version && singular.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.Version == resource.Version && plural.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
for plural, singular := range m.pluralToSingular {
|
||||
if singular.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
if plural.Resource == resource.Resource {
|
||||
ret = append(ret, plural)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(ret) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: resource}
|
||||
}
|
||||
|
||||
sort.Sort(resourceByPreferredGroupVersion{ret, m.defaultGroupVersions})
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) ResourceFor(resource schema.GroupVersionResource) (schema.GroupVersionResource, error) {
|
||||
resources, err := m.ResourcesFor(resource)
|
||||
if err != nil {
|
||||
return schema.GroupVersionResource{}, err
|
||||
}
|
||||
if len(resources) == 1 {
|
||||
return resources[0], nil
|
||||
}
|
||||
|
||||
return schema.GroupVersionResource{}, &AmbiguousResourceError{PartialResource: resource, MatchingResources: resources}
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) KindsFor(input schema.GroupVersionResource) ([]schema.GroupVersionKind, error) {
|
||||
resource := coerceResourceForMatching(input)
|
||||
|
||||
hasResource := len(resource.Resource) > 0
|
||||
hasGroup := len(resource.Group) > 0
|
||||
hasVersion := len(resource.Version) > 0
|
||||
|
||||
if !hasResource {
|
||||
return nil, fmt.Errorf("a resource must be present, got: %v", resource)
|
||||
}
|
||||
|
||||
ret := []schema.GroupVersionKind{}
|
||||
switch {
|
||||
// fully qualified. Find the exact match
|
||||
case hasGroup && hasVersion:
|
||||
kind, exists := m.resourceToKind[resource]
|
||||
if exists {
|
||||
ret = append(ret, kind)
|
||||
}
|
||||
|
||||
case hasGroup:
|
||||
foundExactMatch := false
|
||||
requestedGroupResource := resource.GroupResource()
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if currResource.GroupResource() == requestedGroupResource {
|
||||
foundExactMatch = true
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
|
||||
// if you didn't find an exact match, match on group prefixing. This allows storageclass.storage to match
|
||||
// storageclass.storage.k8s.io
|
||||
if !foundExactMatch {
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if !strings.HasPrefix(currResource.Group, requestedGroupResource.Group) {
|
||||
continue
|
||||
}
|
||||
if currResource.Resource == requestedGroupResource.Resource {
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
case hasVersion:
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if currResource.Version == resource.Version && currResource.Resource == resource.Resource {
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
for currResource, currKind := range m.resourceToKind {
|
||||
if currResource.Resource == resource.Resource {
|
||||
ret = append(ret, currKind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(ret) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: input}
|
||||
}
|
||||
|
||||
sort.Sort(kindByPreferredGroupVersion{ret, m.defaultGroupVersions})
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (m *DefaultRESTMapper) KindFor(resource schema.GroupVersionResource) (schema.GroupVersionKind, error) {
|
||||
kinds, err := m.KindsFor(resource)
|
||||
if err != nil {
|
||||
return schema.GroupVersionKind{}, err
|
||||
}
|
||||
if len(kinds) == 1 {
|
||||
return kinds[0], nil
|
||||
}
|
||||
|
||||
return schema.GroupVersionKind{}, &AmbiguousResourceError{PartialResource: resource, MatchingKinds: kinds}
|
||||
}
|
||||
|
||||
type kindByPreferredGroupVersion struct {
|
||||
list []schema.GroupVersionKind
|
||||
sortOrder []schema.GroupVersion
|
||||
}
|
||||
|
||||
func (o kindByPreferredGroupVersion) Len() int { return len(o.list) }
|
||||
func (o kindByPreferredGroupVersion) Swap(i, j int) { o.list[i], o.list[j] = o.list[j], o.list[i] }
|
||||
func (o kindByPreferredGroupVersion) Less(i, j int) bool {
|
||||
lhs := o.list[i]
|
||||
rhs := o.list[j]
|
||||
if lhs == rhs {
|
||||
return false
|
||||
}
|
||||
|
||||
if lhs.GroupVersion() == rhs.GroupVersion() {
|
||||
return lhs.Kind < rhs.Kind
|
||||
}
|
||||
|
||||
// otherwise, the difference is in the GroupVersion, so we need to sort with respect to the preferred order
|
||||
lhsIndex := -1
|
||||
rhsIndex := -1
|
||||
|
||||
for i := range o.sortOrder {
|
||||
if o.sortOrder[i] == lhs.GroupVersion() {
|
||||
lhsIndex = i
|
||||
}
|
||||
if o.sortOrder[i] == rhs.GroupVersion() {
|
||||
rhsIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
if rhsIndex == -1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return lhsIndex < rhsIndex
|
||||
}
|
||||
|
||||
type resourceByPreferredGroupVersion struct {
|
||||
list []schema.GroupVersionResource
|
||||
sortOrder []schema.GroupVersion
|
||||
}
|
||||
|
||||
func (o resourceByPreferredGroupVersion) Len() int { return len(o.list) }
|
||||
func (o resourceByPreferredGroupVersion) Swap(i, j int) { o.list[i], o.list[j] = o.list[j], o.list[i] }
|
||||
func (o resourceByPreferredGroupVersion) Less(i, j int) bool {
|
||||
lhs := o.list[i]
|
||||
rhs := o.list[j]
|
||||
if lhs == rhs {
|
||||
return false
|
||||
}
|
||||
|
||||
if lhs.GroupVersion() == rhs.GroupVersion() {
|
||||
return lhs.Resource < rhs.Resource
|
||||
}
|
||||
|
||||
// otherwise, the difference is in the GroupVersion, so we need to sort with respect to the preferred order
|
||||
lhsIndex := -1
|
||||
rhsIndex := -1
|
||||
|
||||
for i := range o.sortOrder {
|
||||
if o.sortOrder[i] == lhs.GroupVersion() {
|
||||
lhsIndex = i
|
||||
}
|
||||
if o.sortOrder[i] == rhs.GroupVersion() {
|
||||
rhsIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
if rhsIndex == -1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return lhsIndex < rhsIndex
|
||||
}
|
||||
|
||||
// RESTMapping returns a struct representing the resource path and conversion interfaces a
|
||||
// RESTClient should use to operate on the provided group/kind in order of versions. If a version search
|
||||
// order is not provided, the search order provided to DefaultRESTMapper will be used to resolve which
|
||||
// version should be used to access the named group/kind.
|
||||
func (m *DefaultRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (*RESTMapping, error) {
|
||||
mappings, err := m.RESTMappings(gk, versions...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(mappings) == 0 {
|
||||
return nil, &NoKindMatchError{GroupKind: gk, SearchedVersions: versions}
|
||||
}
|
||||
// since we rely on RESTMappings method
|
||||
// take the first match and return to the caller
|
||||
// as this was the existing behavior.
|
||||
return mappings[0], nil
|
||||
}
|
||||
|
||||
// RESTMappings returns the RESTMappings for the provided group kind. If a version search order
|
||||
// is not provided, the search order provided to DefaultRESTMapper will be used.
|
||||
func (m *DefaultRESTMapper) RESTMappings(gk schema.GroupKind, versions ...string) ([]*RESTMapping, error) {
|
||||
mappings := make([]*RESTMapping, 0)
|
||||
potentialGVK := make([]schema.GroupVersionKind, 0)
|
||||
hadVersion := false
|
||||
|
||||
// Pick an appropriate version
|
||||
for _, version := range versions {
|
||||
if len(version) == 0 || version == runtime.APIVersionInternal {
|
||||
continue
|
||||
}
|
||||
currGVK := gk.WithVersion(version)
|
||||
hadVersion = true
|
||||
if _, ok := m.kindToPluralResource[currGVK]; ok {
|
||||
potentialGVK = append(potentialGVK, currGVK)
|
||||
break
|
||||
}
|
||||
}
|
||||
// Use the default preferred versions
|
||||
if !hadVersion && len(potentialGVK) == 0 {
|
||||
for _, gv := range m.defaultGroupVersions {
|
||||
if gv.Group != gk.Group {
|
||||
continue
|
||||
}
|
||||
potentialGVK = append(potentialGVK, gk.WithVersion(gv.Version))
|
||||
}
|
||||
}
|
||||
|
||||
if len(potentialGVK) == 0 {
|
||||
return nil, &NoKindMatchError{GroupKind: gk, SearchedVersions: versions}
|
||||
}
|
||||
|
||||
for _, gvk := range potentialGVK {
|
||||
//Ensure we have a REST mapping
|
||||
res, ok := m.kindToPluralResource[gvk]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
// Ensure we have a REST scope
|
||||
scope, ok := m.kindToScope[gvk]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("the provided version %q and kind %q cannot be mapped to a supported scope", gvk.GroupVersion(), gvk.Kind)
|
||||
}
|
||||
|
||||
mappings = append(mappings, &RESTMapping{
|
||||
Resource: res,
|
||||
GroupVersionKind: gvk,
|
||||
Scope: scope,
|
||||
})
|
||||
}
|
||||
|
||||
if len(mappings) == 0 {
|
||||
return nil, &NoResourceMatchError{PartialResource: schema.GroupVersionResource{Group: gk.Group, Resource: gk.Kind}}
|
||||
}
|
||||
return mappings, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue