Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
41b78ad2
Commit
41b78ad2
authored
Dec 07, 2015
by
deads2k
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
find partial resource matches
parent
3415f1df
Show whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
698 additions
and
134 deletions
+698
-134
install_test.go
pkg/api/install/install_test.go
+1
-1
interfaces.go
pkg/api/meta/interfaces.go
+14
-3
restmapper.go
pkg/api/meta/restmapper.go
+306
-45
restmapper_test.go
pkg/api/meta/restmapper_test.go
+247
-18
group_version.go
pkg/api/unversioned/group_version.go
+4
-0
install_test.go
pkg/apis/componentconfig/install/install_test.go
+1
-1
install_test.go
pkg/apis/extensions/install/install_test.go
+1
-1
scale.go
pkg/client/unversioned/scale.go
+13
-4
fixture.go
pkg/client/unversioned/testclient/fixture.go
+7
-7
explain.go
pkg/kubectl/cmd/explain.go
+1
-1
rollingupdate.go
pkg/kubectl/cmd/rollingupdate.go
+3
-3
factory.go
pkg/kubectl/cmd/util/factory.go
+1
-5
explain.go
pkg/kubectl/explain.go
+1
-1
kubectl.go
pkg/kubectl/kubectl.go
+21
-20
builder.go
pkg/kubectl/resource/builder.go
+3
-2
resource_printer.go
pkg/kubectl/resource_printer.go
+19
-6
codec.go
pkg/registry/thirdpartyresourcedata/codec.go
+47
-7
codec_test.go
pkg/registry/thirdpartyresourcedata/codec_test.go
+2
-2
admission.go
plugin/pkg/admission/namespace/autoprovision/admission.go
+2
-2
admission.go
plugin/pkg/admission/namespace/exists/admission.go
+2
-2
admission.go
plugin/pkg/admission/namespace/lifecycle/admission.go
+2
-3
No files found.
pkg/api/install/install_test.go
View file @
41b78ad2
...
...
@@ -78,7 +78,7 @@ func TestRESTMapper(t *testing.T) {
rcGVK
:=
gv
.
WithKind
(
"ReplicationController"
)
podTemplateGVK
:=
gv
.
WithKind
(
"PodTemplate"
)
if
gvk
,
err
:=
latest
.
GroupOrDie
(
internal
.
GroupName
)
.
RESTMapper
.
KindFor
(
"replicationcontrollers"
);
err
!=
nil
||
gvk
!=
rcGVK
{
if
gvk
,
err
:=
latest
.
GroupOrDie
(
internal
.
GroupName
)
.
RESTMapper
.
KindFor
(
internal
.
SchemeGroupVersion
.
WithResource
(
"replicationcontrollers"
)
);
err
!=
nil
||
gvk
!=
rcGVK
{
t
.
Errorf
(
"unexpected version mapping: %v %v"
,
gvk
,
err
)
}
...
...
pkg/api/meta/interfaces.go
View file @
41b78ad2
...
...
@@ -158,12 +158,23 @@ type RESTMapping struct {
// TODO(caesarxuchao): Add proper multi-group support so that kinds & resources are
// scoped to groups. See http://issues.k8s.io/12413 and http://issues.k8s.io/10009.
type
RESTMapper
interface
{
// KindFor takes a resource and returns back the unambiguous Kind (GroupVersionKind)
KindFor
(
resource
string
)
(
unversioned
.
GroupVersionKind
,
error
)
// KindFor takes a partial resource and returns back the single match. Returns an error if there are multiple matches
KindFor
(
resource
unversioned
.
GroupVersionResource
)
(
unversioned
.
GroupVersionKind
,
error
)
// KindsFor takes a partial resource and returns back the list of potential kinds in priority order
KindsFor
(
resource
unversioned
.
GroupVersionResource
)
([]
unversioned
.
GroupVersionKind
,
error
)
// ResourceFor takes a partial resource and returns back the single match. Returns an error if there are multiple matches
ResourceFor
(
input
unversioned
.
GroupVersionResource
)
(
unversioned
.
GroupVersionResource
,
error
)
// ResourcesFor takes a partial resource and returns back the list of potential resource in priority order
ResourcesFor
(
input
unversioned
.
GroupVersionResource
)
([]
unversioned
.
GroupVersionResource
,
error
)
RESTMapping
(
gk
unversioned
.
GroupKind
,
versions
...
string
)
(
*
RESTMapping
,
error
)
AliasesForResource
(
resource
string
)
([]
string
,
bool
)
ResourceSingularizer
(
resource
string
)
(
singular
string
,
err
error
)
ResourceIsValid
(
resource
string
)
bool
// ResourceIsValid takes a partial resource and returns back whether or not the resource matches at least one kind
ResourceIsValid
(
resource
unversioned
.
GroupVersionResource
)
bool
}
pkg/api/meta/restmapper.go
View file @
41b78ad2
...
...
@@ -19,9 +19,11 @@ package meta
import
(
"fmt"
"sort"
"strings"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/util/sets"
)
// Implements RESTScope interface
...
...
@@ -71,11 +73,11 @@ var RESTScopeRoot = &restScope{
type
DefaultRESTMapper
struct
{
defaultGroupVersions
[]
unversioned
.
GroupVersion
resourceToKind
map
[
string
]
unversioned
.
GroupVersionKind
kindToPluralResource
map
[
unversioned
.
GroupVersionKind
]
string
resourceToKind
map
[
unversioned
.
GroupVersionResource
]
unversioned
.
GroupVersionKind
kindToPluralResource
map
[
unversioned
.
GroupVersionKind
]
unversioned
.
GroupVersionResource
kindToScope
map
[
unversioned
.
GroupVersionKind
]
RESTScope
singularToPlural
map
[
string
]
string
pluralToSingular
map
[
string
]
string
singularToPlural
map
[
unversioned
.
GroupVersionResource
]
unversioned
.
GroupVersionResource
pluralToSingular
map
[
unversioned
.
GroupVersionResource
]
unversioned
.
GroupVersionResource
interfacesFunc
VersionInterfacesFunc
}
...
...
@@ -92,11 +94,11 @@ type VersionInterfacesFunc func(version unversioned.GroupVersion) (*VersionInter
// to search when an object has no default version (set empty to return an error),
// and a function that retrieves the correct codec and metadata for a given version.
func
NewDefaultRESTMapper
(
defaultGroupVersions
[]
unversioned
.
GroupVersion
,
f
VersionInterfacesFunc
)
*
DefaultRESTMapper
{
resourceToKind
:=
make
(
map
[
string
]
unversioned
.
GroupVersionKind
)
kindToPluralResource
:=
make
(
map
[
unversioned
.
GroupVersionKind
]
string
)
resourceToKind
:=
make
(
map
[
unversioned
.
GroupVersionResource
]
unversioned
.
GroupVersionKind
)
kindToPluralResource
:=
make
(
map
[
unversioned
.
GroupVersionKind
]
unversioned
.
GroupVersionResource
)
kindToScope
:=
make
(
map
[
unversioned
.
GroupVersionKind
]
RESTScope
)
singularToPlural
:=
make
(
map
[
string
]
string
)
pluralToSingular
:=
make
(
map
[
string
]
string
)
singularToPlural
:=
make
(
map
[
unversioned
.
GroupVersionResource
]
unversioned
.
GroupVersionResource
)
pluralToSingular
:=
make
(
map
[
unversioned
.
GroupVersionResource
]
unversioned
.
GroupVersionResource
)
// TODO: verify name mappings work correctly when versions differ
return
&
DefaultRESTMapper
{
...
...
@@ -110,45 +112,54 @@ func NewDefaultRESTMapper(defaultGroupVersions []unversioned.GroupVersion, f Ver
}
}
func
(
m
*
DefaultRESTMapper
)
Add
(
gvk
unversioned
.
GroupVersionKind
,
scope
RESTScope
,
mixedCase
bool
)
{
plural
,
singular
:=
KindToResource
(
gvk
.
Kind
,
mixedCase
)
func
(
m
*
DefaultRESTMapper
)
Add
(
kind
unversioned
.
GroupVersionKind
,
scope
RESTScope
,
mixedCase
bool
)
{
plural
,
singular
:=
KindToResource
(
kind
,
mixedCase
)
lowerPlural
:=
plural
.
GroupVersion
()
.
WithResource
(
strings
.
ToLower
(
plural
.
Resource
))
lowerSingular
:=
singular
.
GroupVersion
()
.
WithResource
(
strings
.
ToLower
(
singular
.
Resource
))
m
.
singularToPlural
[
singular
]
=
plural
m
.
pluralToSingular
[
plural
]
=
singular
_
,
ok1
:=
m
.
resourceToKind
[
plural
]
_
,
ok2
:=
m
.
resourceToKind
[
strings
.
ToLower
(
plural
)]
if
!
ok1
&&
!
ok2
{
m
.
resourceToKind
[
plural
]
=
gvk
m
.
resourceToKind
[
singular
]
=
gvk
if
strings
.
ToLower
(
plural
)
!=
plural
{
m
.
resourceToKind
[
strings
.
ToLower
(
plural
)]
=
gvk
m
.
resourceToKind
[
strings
.
ToLower
(
singular
)]
=
gvk
m
.
singularToPlural
[
lowerSingular
]
=
lowerPlural
m
.
pluralToSingular
[
lowerPlural
]
=
lowerSingular
if
_
,
mixedCaseExists
:=
m
.
resourceToKind
[
plural
];
!
mixedCaseExists
{
m
.
resourceToKind
[
plural
]
=
kind
m
.
resourceToKind
[
singular
]
=
kind
}
if
_
,
lowerCaseExists
:=
m
.
resourceToKind
[
lowerPlural
];
!
lowerCaseExists
&&
(
lowerPlural
!=
plural
)
{
m
.
resourceToKind
[
lowerPlural
]
=
kind
m
.
resourceToKind
[
lowerSingular
]
=
kind
}
m
.
kindToPluralResource
[
gvk
]
=
plural
m
.
kindToScope
[
gvk
]
=
scope
m
.
kindToPluralResource
[
kind
]
=
plural
m
.
kindToScope
[
kind
]
=
scope
}
// KindToResource converts Kind to a resource name.
func
KindToResource
(
kind
string
,
mixedCase
bool
)
(
plural
,
singular
string
)
{
if
len
(
kind
)
==
0
{
func
KindToResource
(
kind
unversioned
.
GroupVersionKind
,
mixedCase
bool
)
(
plural
,
singular
unversioned
.
GroupVersionResource
)
{
kindName
:=
kind
.
Kind
if
len
(
kindName
)
==
0
{
return
}
if
mixedCase
{
// Legacy support for mixed case names
singular
=
strings
.
ToLower
(
kind
[
:
1
])
+
kind
[
1
:
]
singular
=
kind
.
GroupVersion
()
.
WithResource
(
strings
.
ToLower
(
kindName
[
:
1
])
+
kindName
[
1
:
])
}
else
{
singular
=
strings
.
ToLower
(
kind
)
singular
=
kind
.
GroupVersion
()
.
WithResource
(
strings
.
ToLower
(
kindName
)
)
}
if
strings
.
HasSuffix
(
singular
,
"endpoints"
)
{
singularName
:=
singular
.
Resource
if
strings
.
HasSuffix
(
singularName
,
"endpoints"
)
{
plural
=
singular
}
else
{
switch
string
(
singular
[
len
(
singular
)
-
1
])
{
switch
string
(
singular
Name
[
len
(
singularName
)
-
1
])
{
case
"s"
:
plural
=
singular
+
"es"
plural
=
kind
.
GroupVersion
()
.
WithResource
(
singularName
+
"es"
)
case
"y"
:
plural
=
strings
.
TrimSuffix
(
singular
,
"y"
)
+
"ies"
plural
=
kind
.
GroupVersion
()
.
WithResource
(
strings
.
TrimSuffix
(
singularName
,
"y"
)
+
"ies"
)
default
:
plural
=
singular
+
"s"
plural
=
kind
.
GroupVersion
()
.
WithResource
(
singularName
+
"s"
)
}
}
return
...
...
@@ -156,21 +167,240 @@ func KindToResource(kind string, mixedCase bool) (plural, singular string) {
// ResourceSingularizer implements RESTMapper
// It converts a resource name from plural to singular (e.g., from pods to pod)
func
(
m
*
DefaultRESTMapper
)
ResourceSingularizer
(
resource
string
)
(
singular
string
,
err
error
)
{
// It must have exactly one match and it must match case perfectly. This is congruent with old functionality
func
(
m
*
DefaultRESTMapper
)
ResourceSingularizer
(
resourceType
string
)
(
string
,
error
)
{
partialResource
:=
unversioned
.
GroupVersionResource
{
Resource
:
resourceType
}
resource
,
err
:=
m
.
ResourceFor
(
partialResource
)
if
err
!=
nil
{
return
resourceType
,
err
}
singular
,
ok
:=
m
.
pluralToSingular
[
resource
]
if
!
ok
{
return
resource
,
fmt
.
Errorf
(
"no singular of resource %q
has been defined"
,
resource
)
return
resource
Type
,
fmt
.
Errorf
(
"no singular of resource %v
has been defined"
,
resource
)
}
return
singular
,
nil
return
singular
.
Resource
,
nil
}
// VersionAndKindForResource implements RESTMapper
func
(
m
*
DefaultRESTMapper
)
KindFor
(
resource
string
)
(
unversioned
.
GroupVersionKind
,
error
)
{
gvk
,
ok
:=
m
.
resourceToKind
[
strings
.
ToLower
(
resource
)]
if
!
ok
{
return
gvk
,
fmt
.
Errorf
(
"in version and kind for resource, no resource %q has been defined"
,
resource
)
func
(
m
*
DefaultRESTMapper
)
ResourcesFor
(
resource
unversioned
.
GroupVersionResource
)
([]
unversioned
.
GroupVersionResource
,
error
)
{
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
:=
[]
unversioned
.
GroupVersionResource
{}
switch
{
// fully qualified. Find the exact match
case
hasGroup
&&
hasVersion
:
for
plural
,
singular
:=
range
m
.
pluralToSingular
{
if
singular
==
resource
{
ret
=
append
(
ret
,
plural
)
break
}
if
plural
==
resource
{
ret
=
append
(
ret
,
plural
)
break
}
}
case
hasGroup
:
requestedGroupResource
:=
resource
.
GroupResource
()
for
currResource
:=
range
m
.
pluralToSingular
{
if
currResource
.
GroupResource
()
==
requestedGroupResource
{
ret
=
append
(
ret
,
currResource
)
}
}
case
hasVersion
:
for
currResource
:=
range
m
.
pluralToSingular
{
if
currResource
.
Version
==
resource
.
Version
&&
currResource
.
Resource
==
resource
.
Resource
{
ret
=
append
(
ret
,
currResource
)
}
}
default
:
for
currResource
:=
range
m
.
pluralToSingular
{
if
currResource
.
Resource
==
resource
.
Resource
{
ret
=
append
(
ret
,
currResource
)
}
}
}
if
len
(
ret
)
==
0
{
return
nil
,
fmt
.
Errorf
(
"no resource %v has been defined; known resources: %v"
,
resource
,
m
.
pluralToSingular
)
}
sort
.
Sort
(
resourceByPreferredGroupVersion
{
ret
,
m
.
defaultGroupVersions
})
return
ret
,
nil
}
func
(
m
*
DefaultRESTMapper
)
ResourceFor
(
resource
unversioned
.
GroupVersionResource
)
(
unversioned
.
GroupVersionResource
,
error
)
{
resources
,
err
:=
m
.
ResourcesFor
(
resource
)
if
err
!=
nil
{
return
unversioned
.
GroupVersionResource
{},
err
}
if
len
(
resources
)
==
1
{
return
resources
[
0
],
nil
}
return
unversioned
.
GroupVersionResource
{},
fmt
.
Errorf
(
"%v is ambiguous, got: %v"
,
resource
,
resources
)
}
func
(
m
*
DefaultRESTMapper
)
KindsFor
(
input
unversioned
.
GroupVersionResource
)
([]
unversioned
.
GroupVersionKind
,
error
)
{
resource
:=
input
.
GroupVersion
()
.
WithResource
(
strings
.
ToLower
(
input
.
Resource
))
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
:=
[]
unversioned
.
GroupVersionKind
{}
switch
{
// fully qualified. Find the exact match
case
hasGroup
&&
hasVersion
:
kind
,
exists
:=
m
.
resourceToKind
[
resource
]
if
exists
{
ret
=
append
(
ret
,
kind
)
}
case
hasGroup
:
requestedGroupResource
:=
resource
.
GroupResource
()
for
currResource
,
currKind
:=
range
m
.
resourceToKind
{
if
currResource
.
GroupResource
()
==
requestedGroupResource
{
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
,
fmt
.
Errorf
(
"no kind %v has been defined; known resources: %v"
,
resource
,
m
.
pluralToSingular
)
}
sort
.
Sort
(
kindByPreferredGroupVersion
{
ret
,
m
.
defaultGroupVersions
})
return
ret
,
nil
}
func
(
m
*
DefaultRESTMapper
)
KindFor
(
resource
unversioned
.
GroupVersionResource
)
(
unversioned
.
GroupVersionKind
,
error
)
{
kinds
,
err
:=
m
.
KindsFor
(
resource
)
if
err
!=
nil
{
return
unversioned
.
GroupVersionKind
{},
err
}
// TODO for each group, choose the most preferred (first) version. This keeps us consistent with code today.
// eventually, we'll need a RESTMapper that is aware of what's available server-side and deconflicts that with
// user preferences
oneKindPerGroup
:=
[]
unversioned
.
GroupVersionKind
{}
groupsAdded
:=
sets
.
String
{}
for
_
,
kind
:=
range
kinds
{
if
groupsAdded
.
Has
(
kind
.
Group
)
{
continue
}
return
gvk
,
nil
oneKindPerGroup
=
append
(
oneKindPerGroup
,
kind
)
groupsAdded
.
Insert
(
kind
.
Group
)
}
if
len
(
oneKindPerGroup
)
==
1
{
return
oneKindPerGroup
[
0
],
nil
}
return
unversioned
.
GroupVersionKind
{},
fmt
.
Errorf
(
"%v is ambiguous, got: %v"
,
resource
,
kinds
)
}
type
kindByPreferredGroupVersion
struct
{
list
[]
unversioned
.
GroupVersionKind
sortOrder
[]
unversioned
.
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
[]
unversioned
.
GroupVersionResource
sortOrder
[]
unversioned
.
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
...
...
@@ -238,7 +468,7 @@ func (m *DefaultRESTMapper) RESTMapping(gk unversioned.GroupKind, versions ...st
}
retVal
:=
&
RESTMapping
{
Resource
:
resource
,
Resource
:
resource
.
Resource
,
GroupVersionKind
:
*
gvk
,
Scope
:
scope
,
...
...
@@ -269,8 +499,8 @@ func (m *DefaultRESTMapper) AliasesForResource(alias string) ([]string, bool) {
return
nil
,
false
}
// ResourceIsValid takes a
string (kind) and checks if it's a valid resource
func
(
m
*
DefaultRESTMapper
)
ResourceIsValid
(
resource
string
)
bool
{
// ResourceIsValid takes a
partial resource and checks if it's valid
func
(
m
*
DefaultRESTMapper
)
ResourceIsValid
(
resource
unversioned
.
GroupVersionResource
)
bool
{
_
,
err
:=
m
.
KindFor
(
resource
)
return
err
==
nil
}
...
...
@@ -290,10 +520,41 @@ func (m MultiRESTMapper) ResourceSingularizer(resource string) (singular string,
return
}
// VersionAndKindForResource provides the Version and Kind mappings for the
// REST resources. This implementation supports multiple REST schemas and return
func
(
m
MultiRESTMapper
)
ResourcesFor
(
resource
unversioned
.
GroupVersionResource
)
(
gvk
[]
unversioned
.
GroupVersionResource
,
err
error
)
{
for
_
,
t
:=
range
m
{
gvk
,
err
=
t
.
ResourcesFor
(
resource
)
if
err
==
nil
{
return
}
}
return
}
// KindsFor provides the Kind mappings for the REST resources. This implementation supports multiple REST schemas and returns
// the first match.
func
(
m
MultiRESTMapper
)
KindsFor
(
resource
unversioned
.
GroupVersionResource
)
(
gvk
[]
unversioned
.
GroupVersionKind
,
err
error
)
{
for
_
,
t
:=
range
m
{
gvk
,
err
=
t
.
KindsFor
(
resource
)
if
err
==
nil
{
return
}
}
return
}
func
(
m
MultiRESTMapper
)
ResourceFor
(
resource
unversioned
.
GroupVersionResource
)
(
gvk
unversioned
.
GroupVersionResource
,
err
error
)
{
for
_
,
t
:=
range
m
{
gvk
,
err
=
t
.
ResourceFor
(
resource
)
if
err
==
nil
{
return
}
}
return
}
// KindsFor provides the Kind mapping for the REST resources. This implementation supports multiple REST schemas and returns
// the first match.
func
(
m
MultiRESTMapper
)
KindFor
(
resource
string
)
(
gvk
unversioned
.
GroupVersionKind
,
err
error
)
{
func
(
m
MultiRESTMapper
)
KindFor
(
resource
unversioned
.
GroupVersionResource
)
(
gvk
unversioned
.
GroupVersionKind
,
err
error
)
{
for
_
,
t
:=
range
m
{
gvk
,
err
=
t
.
KindFor
(
resource
)
if
err
==
nil
{
...
...
@@ -327,7 +588,7 @@ func (m MultiRESTMapper) AliasesForResource(alias string) (aliases []string, ok
}
// ResourceIsValid takes a string (either group/kind or kind) and checks if it's a valid resource
func
(
m
MultiRESTMapper
)
ResourceIsValid
(
resource
string
)
bool
{
func
(
m
MultiRESTMapper
)
ResourceIsValid
(
resource
unversioned
.
GroupVersionResource
)
bool
{
for
_
,
t
:=
range
m
{
if
t
.
ResourceIsValid
(
resource
)
{
return
true
...
...
pkg/api/meta/restmapper_test.go
View file @
41b78ad2
...
...
@@ -20,6 +20,8 @@ import (
"errors"
"io"
"net/url"
"reflect"
"strings"
"testing"
"k8s.io/kubernetes/pkg/api/unversioned"
...
...
@@ -92,23 +94,23 @@ func TestRESTMapperVersionAndKindForResource(t *testing.T) {
testGroupVersion
:=
unversioned
.
GroupVersion
{
Group
:
testGroup
,
Version
:
testVersion
}
testCases
:=
[]
struct
{
Resource
string
Resource
unversioned
.
GroupVersionResource
GroupVersionToRegister
unversioned
.
GroupVersion
ExpectedGVK
unversioned
.
GroupVersionKind
MixedCase
bool
Err
bool
}{
{
Resource
:
"internalobjec"
,
Err
:
true
},
{
Resource
:
"internalObjec"
,
Err
:
true
},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"internalobjec"
}
,
Err
:
true
},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"internalObjec"
}
,
Err
:
true
},
{
Resource
:
"internalobject"
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
"internalobjects"
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"internalobject"
}
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"internalobjects"
}
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
"internalobject"
,
MixedCase
:
true
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
"internalobjects"
,
MixedCase
:
true
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"internalobject"
}
,
MixedCase
:
true
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"internalobjects"
}
,
MixedCase
:
true
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
"internalObject"
,
MixedCase
:
true
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
"internalObjects"
,
MixedCase
:
true
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"internalObject"
}
,
MixedCase
:
true
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"internalObjects"
}
,
MixedCase
:
true
,
ExpectedGVK
:
testGroupVersion
.
WithKind
(
"InternalObject"
)},
}
for
i
,
testCase
:=
range
testCases
{
mapper
:=
NewDefaultRESTMapper
([]
unversioned
.
GroupVersion
{
testGroupVersion
},
fakeInterfaces
)
...
...
@@ -134,18 +136,19 @@ func TestRESTMapperVersionAndKindForResource(t *testing.T) {
func
TestRESTMapperGroupForResource
(
t
*
testing
.
T
)
{
testCases
:=
[]
struct
{
Resource
string
Resource
unversioned
.
GroupVersionResource
GroupVersionKind
unversioned
.
GroupVersionKind
Err
bool
}{
{
Resource
:
"myObject"
,
GroupVersionKind
:
unversioned
.
GroupVersionKind
{
Group
:
"testapi"
,
Version
:
"test"
,
Kind
:
"MyObject"
}},
{
Resource
:
"myobject"
,
GroupVersionKind
:
unversioned
.
GroupVersionKind
{
Group
:
"testapi2"
,
Version
:
"test"
,
Kind
:
"MyObject"
}},
{
Resource
:
"myObje"
,
Err
:
true
,
GroupVersionKind
:
unversioned
.
GroupVersionKind
{
Group
:
"testapi"
,
Version
:
"test"
,
Kind
:
"MyObject"
}},
{
Resource
:
"myobje"
,
Err
:
true
,
GroupVersionKind
:
unversioned
.
GroupVersionKind
{
Group
:
"testapi"
,
Version
:
"test"
,
Kind
:
"MyObject"
}},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"myObject"
}
,
GroupVersionKind
:
unversioned
.
GroupVersionKind
{
Group
:
"testapi"
,
Version
:
"test"
,
Kind
:
"MyObject"
}},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"myobject"
}
,
GroupVersionKind
:
unversioned
.
GroupVersionKind
{
Group
:
"testapi2"
,
Version
:
"test"
,
Kind
:
"MyObject"
}},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"myObje"
}
,
Err
:
true
,
GroupVersionKind
:
unversioned
.
GroupVersionKind
{
Group
:
"testapi"
,
Version
:
"test"
,
Kind
:
"MyObject"
}},
{
Resource
:
unversioned
.
GroupVersionResource
{
Resource
:
"myobje"
}
,
Err
:
true
,
GroupVersionKind
:
unversioned
.
GroupVersionKind
{
Group
:
"testapi"
,
Version
:
"test"
,
Kind
:
"MyObject"
}},
}
for
i
,
testCase
:=
range
testCases
{
mapper
:=
NewDefaultRESTMapper
([]
unversioned
.
GroupVersion
{
testCase
.
GroupVersionKind
.
GroupVersion
()},
fakeInterfaces
)
mapper
.
Add
(
testCase
.
GroupVersionKind
,
RESTScopeNamespace
,
false
)
actualGVK
,
err
:=
mapper
.
KindFor
(
testCase
.
Resource
)
if
testCase
.
Err
{
if
err
==
nil
{
...
...
@@ -159,6 +162,230 @@ func TestRESTMapperGroupForResource(t *testing.T) {
}
}
func
TestRESTMapperKindsFor
(
t
*
testing
.
T
)
{
testCases
:=
[]
struct
{
Name
string
PreferredOrder
[]
unversioned
.
GroupVersion
KindsToRegister
[]
unversioned
.
GroupVersionKind
PartialResourceToRequest
unversioned
.
GroupVersionResource
ExpectedKinds
[]
unversioned
.
GroupVersionKind
ExpectedKindErr
string
}{
{
Name
:
"ambiguous groups, with preference order"
,
PreferredOrder
:
[]
unversioned
.
GroupVersion
{
{
Group
:
"second-group"
,
Version
:
"first-version"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
},
},
KindsToRegister
:
[]
unversioned
.
GroupVersionKind
{
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
},
PartialResourceToRequest
:
unversioned
.
GroupVersionResource
{
Resource
:
"my-kinds"
},
ExpectedKinds
:
[]
unversioned
.
GroupVersionKind
{
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
},
ExpectedKindErr
:
"is ambiguous"
,
},
{
Name
:
"ambiguous groups, with explicit group match"
,
PreferredOrder
:
[]
unversioned
.
GroupVersion
{
{
Group
:
"second-group"
,
Version
:
"first-version"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
},
},
KindsToRegister
:
[]
unversioned
.
GroupVersionKind
{
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
},
PartialResourceToRequest
:
unversioned
.
GroupVersionResource
{
Group
:
"first-group"
,
Resource
:
"my-kinds"
},
ExpectedKinds
:
[]
unversioned
.
GroupVersionKind
{
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
},
},
{
Name
:
"ambiguous groups, with ambiguous version match"
,
PreferredOrder
:
[]
unversioned
.
GroupVersion
{
{
Group
:
"first-group"
,
Version
:
"first-version"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
},
},
KindsToRegister
:
[]
unversioned
.
GroupVersionKind
{
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
},
PartialResourceToRequest
:
unversioned
.
GroupVersionResource
{
Version
:
"first-version"
,
Resource
:
"my-kinds"
},
ExpectedKinds
:
[]
unversioned
.
GroupVersionKind
{
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
},
ExpectedKindErr
:
"is ambiguous"
,
},
}
for
_
,
testCase
:=
range
testCases
{
tcName
:=
testCase
.
Name
mapper
:=
NewDefaultRESTMapper
(
testCase
.
PreferredOrder
,
fakeInterfaces
)
for
_
,
kind
:=
range
testCase
.
KindsToRegister
{
mapper
.
Add
(
kind
,
RESTScopeNamespace
,
false
)
}
actualKinds
,
err
:=
mapper
.
KindsFor
(
testCase
.
PartialResourceToRequest
)
if
err
!=
nil
{
t
.
Errorf
(
"%s: unexpected error: %v"
,
tcName
,
err
)
continue
}
if
!
reflect
.
DeepEqual
(
testCase
.
ExpectedKinds
,
actualKinds
)
{
t
.
Errorf
(
"%s: expected %v, got %v"
,
tcName
,
testCase
.
ExpectedKinds
,
actualKinds
)
}
singleKind
,
err
:=
mapper
.
KindFor
(
testCase
.
PartialResourceToRequest
)
if
err
==
nil
&&
len
(
testCase
.
ExpectedKindErr
)
!=
0
{
t
.
Errorf
(
"%s: expected error: %v"
,
tcName
,
testCase
.
ExpectedKindErr
)
continue
}
if
err
!=
nil
{
if
len
(
testCase
.
ExpectedKindErr
)
==
0
{
t
.
Errorf
(
"%s: unexpected error: %v"
,
tcName
,
err
)
continue
}
else
{
if
!
strings
.
Contains
(
err
.
Error
(),
testCase
.
ExpectedKindErr
)
{
t
.
Errorf
(
"%s: expected %v, got %v"
,
tcName
,
testCase
.
ExpectedKindErr
,
err
)
continue
}
}
}
else
{
if
testCase
.
ExpectedKinds
[
0
]
!=
singleKind
{
t
.
Errorf
(
"%s: expected %v, got %v"
,
tcName
,
testCase
.
ExpectedKinds
[
0
],
singleKind
)
}
}
}
}
func
TestRESTMapperResourcesFor
(
t
*
testing
.
T
)
{
testCases
:=
[]
struct
{
Name
string
PreferredOrder
[]
unversioned
.
GroupVersion
KindsToRegister
[]
unversioned
.
GroupVersionKind
PartialResourceToRequest
unversioned
.
GroupVersionResource
ExpectedResources
[]
unversioned
.
GroupVersionResource
ExpectedResourceErr
string
}{
{
Name
:
"ambiguous groups, with preference order"
,
PreferredOrder
:
[]
unversioned
.
GroupVersion
{
{
Group
:
"second-group"
,
Version
:
"first-version"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
},
},
KindsToRegister
:
[]
unversioned
.
GroupVersionKind
{
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
},
PartialResourceToRequest
:
unversioned
.
GroupVersionResource
{
Resource
:
"my-kinds"
},
ExpectedResources
:
[]
unversioned
.
GroupVersionResource
{
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Resource
:
"my-kinds"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Resource
:
"my-kinds"
},
},
ExpectedResourceErr
:
"is ambiguous"
,
},
{
Name
:
"ambiguous groups, with explicit group match"
,
PreferredOrder
:
[]
unversioned
.
GroupVersion
{
{
Group
:
"second-group"
,
Version
:
"first-version"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
},
},
KindsToRegister
:
[]
unversioned
.
GroupVersionKind
{
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
},
PartialResourceToRequest
:
unversioned
.
GroupVersionResource
{
Group
:
"first-group"
,
Resource
:
"my-kinds"
},
ExpectedResources
:
[]
unversioned
.
GroupVersionResource
{
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Resource
:
"my-kinds"
},
},
},
{
Name
:
"ambiguous groups, with ambiguous version match"
,
PreferredOrder
:
[]
unversioned
.
GroupVersion
{
{
Group
:
"first-group"
,
Version
:
"first-version"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
},
},
KindsToRegister
:
[]
unversioned
.
GroupVersionKind
{
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"my-kind"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Kind
:
"your-kind"
},
},
PartialResourceToRequest
:
unversioned
.
GroupVersionResource
{
Version
:
"first-version"
,
Resource
:
"my-kinds"
},
ExpectedResources
:
[]
unversioned
.
GroupVersionResource
{
{
Group
:
"first-group"
,
Version
:
"first-version"
,
Resource
:
"my-kinds"
},
{
Group
:
"second-group"
,
Version
:
"first-version"
,
Resource
:
"my-kinds"
},
},
ExpectedResourceErr
:
"is ambiguous"
,
},
}
for
_
,
testCase
:=
range
testCases
{
tcName
:=
testCase
.
Name
mapper
:=
NewDefaultRESTMapper
(
testCase
.
PreferredOrder
,
fakeInterfaces
)
for
_
,
kind
:=
range
testCase
.
KindsToRegister
{
mapper
.
Add
(
kind
,
RESTScopeNamespace
,
false
)
}
actualResources
,
err
:=
mapper
.
ResourcesFor
(
testCase
.
PartialResourceToRequest
)
if
err
!=
nil
{
t
.
Errorf
(
"%s: unexpected error: %v"
,
tcName
,
err
)
continue
}
if
!
reflect
.
DeepEqual
(
testCase
.
ExpectedResources
,
actualResources
)
{
t
.
Errorf
(
"%s: expected %v, got %v"
,
tcName
,
testCase
.
ExpectedResources
,
actualResources
)
}
singleResource
,
err
:=
mapper
.
ResourceFor
(
testCase
.
PartialResourceToRequest
)
if
err
==
nil
&&
len
(
testCase
.
ExpectedResourceErr
)
!=
0
{
t
.
Errorf
(
"%s: expected error: %v"
,
tcName
,
testCase
.
ExpectedResourceErr
)
continue
}
if
err
!=
nil
{
if
len
(
testCase
.
ExpectedResourceErr
)
==
0
{
t
.
Errorf
(
"%s: unexpected error: %v"
,
tcName
,
err
)
continue
}
else
{
if
!
strings
.
Contains
(
err
.
Error
(),
testCase
.
ExpectedResourceErr
)
{
t
.
Errorf
(
"%s: expected %v, got %v"
,
tcName
,
testCase
.
ExpectedResourceErr
,
err
)
continue
}
}
}
else
{
if
testCase
.
ExpectedResources
[
0
]
!=
singleResource
{
t
.
Errorf
(
"%s: expected %v, got %v"
,
tcName
,
testCase
.
ExpectedResources
[
0
],
singleResource
)
}
}
}
}
func
TestKindToResource
(
t
*
testing
.
T
)
{
testCases
:=
[]
struct
{
Kind
string
...
...
@@ -181,9 +408,11 @@ func TestKindToResource(t *testing.T) {
{
Kind
:
"lowercase"
,
MixedCase
:
false
,
Plural
:
"lowercases"
,
Singular
:
"lowercase"
},
}
for
i
,
testCase
:=
range
testCases
{
plural
,
singular
:=
KindToResource
(
testCase
.
Kind
,
testCase
.
MixedCase
)
if
singular
!=
testCase
.
Singular
||
plural
!=
testCase
.
Plural
{
t
.
Errorf
(
"%d: unexpected plural and singular: %s %s"
,
i
,
plural
,
singular
)
version
:=
unversioned
.
GroupVersion
{}
plural
,
singular
:=
KindToResource
(
version
.
WithKind
(
testCase
.
Kind
),
testCase
.
MixedCase
)
if
singular
!=
version
.
WithResource
(
testCase
.
Singular
)
||
plural
!=
version
.
WithResource
(
testCase
.
Plural
)
{
t
.
Errorf
(
"%d: unexpected plural and singular: %v %v"
,
i
,
plural
,
singular
)
}
}
}
...
...
@@ -224,7 +453,7 @@ func TestRESTMapperResourceSingularizer(t *testing.T) {
t
.
Errorf
(
"%d: unexpected error: %v"
,
i
,
err
)
}
if
singular
!=
testCase
.
Singular
{
t
.
Errorf
(
"%d: mismatched singular:
%s, should be %s
"
,
i
,
singular
,
testCase
.
Singular
)
t
.
Errorf
(
"%d: mismatched singular:
got %v, expected %v
"
,
i
,
singular
,
testCase
.
Singular
)
}
}
}
...
...
pkg/api/unversioned/group_version.go
View file @
41b78ad2
...
...
@@ -29,6 +29,10 @@ type GroupResource struct {
Resource
string
}
func
(
gr
GroupResource
)
WithVersion
(
version
string
)
GroupVersionResource
{
return
GroupVersionResource
{
Group
:
gr
.
Group
,
Version
:
version
,
Resource
:
gr
.
Resource
}
}
func
(
gr
*
GroupResource
)
String
()
string
{
return
strings
.
Join
([]
string
{
gr
.
Group
,
", Resource="
,
gr
.
Resource
},
""
)
}
...
...
pkg/apis/componentconfig/install/install_test.go
View file @
41b78ad2
...
...
@@ -57,7 +57,7 @@ func TestRESTMapper(t *testing.T) {
gv
:=
unversioned
.
GroupVersion
{
Group
:
componentconfig
.
GroupName
,
Version
:
"v1alpha1"
}
proxyGVK
:=
gv
.
WithKind
(
"KubeProxyConfiguration"
)
if
gvk
,
err
:=
latest
.
GroupOrDie
(
componentconfig
.
GroupName
)
.
RESTMapper
.
KindFor
(
"kubeproxyconfiguration"
);
err
!=
nil
||
gvk
!=
proxyGVK
{
if
gvk
,
err
:=
latest
.
GroupOrDie
(
componentconfig
.
GroupName
)
.
RESTMapper
.
KindFor
(
gv
.
WithResource
(
"kubeproxyconfiguration"
)
);
err
!=
nil
||
gvk
!=
proxyGVK
{
t
.
Errorf
(
"unexpected version mapping: %v %v"
,
gvk
,
err
)
}
...
...
pkg/apis/extensions/install/install_test.go
View file @
41b78ad2
...
...
@@ -80,7 +80,7 @@ func TestRESTMapper(t *testing.T) {
hpaGVK
:=
gv
.
WithKind
(
"HorizontalPodAutoscaler"
)
daemonSetGVK
:=
gv
.
WithKind
(
"DaemonSet"
)
if
gvk
,
err
:=
latest
.
GroupOrDie
(
extensions
.
GroupName
)
.
RESTMapper
.
KindFor
(
"horizontalpodautoscalers"
);
err
!=
nil
||
gvk
!=
hpaGVK
{
if
gvk
,
err
:=
latest
.
GroupOrDie
(
extensions
.
GroupName
)
.
RESTMapper
.
KindFor
(
gv
.
WithResource
(
"horizontalpodautoscalers"
)
);
err
!=
nil
||
gvk
!=
hpaGVK
{
t
.
Errorf
(
"unexpected version mapping: %v %v"
,
gvk
,
err
)
}
...
...
pkg/client/unversioned/scale.go
View file @
41b78ad2
...
...
@@ -18,6 +18,7 @@ package unversioned
import
(
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
)
...
...
@@ -48,17 +49,25 @@ func newScales(c *ExtensionsClient, namespace string) *scales {
// Get takes the reference to scale subresource and returns the subresource or error, if one occurs.
func
(
c
*
scales
)
Get
(
kind
string
,
name
string
)
(
result
*
extensions
.
Scale
,
err
error
)
{
result
=
&
extensions
.
Scale
{}
resource
,
_
:=
meta
.
KindToResource
(
kind
,
false
)
err
=
c
.
client
.
Get
()
.
Namespace
(
c
.
ns
)
.
Resource
(
resource
)
.
Name
(
name
)
.
SubResource
(
"scale"
)
.
Do
()
.
Into
(
result
)
// TODO this method needs to take a proper unambiguous kind
fullyQualifiedKind
:=
unversioned
.
GroupVersionKind
{
Kind
:
kind
}
resource
,
_
:=
meta
.
KindToResource
(
fullyQualifiedKind
,
false
)
err
=
c
.
client
.
Get
()
.
Namespace
(
c
.
ns
)
.
Resource
(
resource
.
Resource
)
.
Name
(
name
)
.
SubResource
(
"scale"
)
.
Do
()
.
Into
(
result
)
return
}
func
(
c
*
scales
)
Update
(
kind
string
,
scale
*
extensions
.
Scale
)
(
result
*
extensions
.
Scale
,
err
error
)
{
result
=
&
extensions
.
Scale
{}
resource
,
_
:=
meta
.
KindToResource
(
kind
,
false
)
// TODO this method needs to take a proper unambiguous kind
fullyQualifiedKind
:=
unversioned
.
GroupVersionKind
{
Kind
:
kind
}
resource
,
_
:=
meta
.
KindToResource
(
fullyQualifiedKind
,
false
)
err
=
c
.
client
.
Put
()
.
Namespace
(
scale
.
Namespace
)
.
Resource
(
resource
)
.
Resource
(
resource
.
Resource
)
.
Name
(
scale
.
Name
)
.
SubResource
(
"scale"
)
.
Body
(
scale
)
.
...
...
pkg/client/unversioned/testclient/fixture.go
View file @
41b78ad2
...
...
@@ -59,7 +59,7 @@ type ObjectScheme interface {
func
ObjectReaction
(
o
ObjectRetriever
,
mapper
meta
.
RESTMapper
)
ReactionFunc
{
return
func
(
action
Action
)
(
bool
,
runtime
.
Object
,
error
)
{
gvk
,
err
:=
mapper
.
KindFor
(
action
.
GetResource
()
)
kind
,
err
:=
mapper
.
KindFor
(
unversioned
.
GroupVersionResource
{
Resource
:
action
.
GetResource
()}
)
if
err
!=
nil
{
return
false
,
nil
,
fmt
.
Errorf
(
"unrecognized action %s: %v"
,
action
.
GetResource
(),
err
)
}
...
...
@@ -67,16 +67,16 @@ func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
// TODO: have mapper return a Kind for a subresource?
switch
castAction
:=
action
.
(
type
)
{
case
ListAction
:
gvk
.
Kind
+=
"List"
resource
,
err
:=
o
.
Kind
(
gvk
,
""
)
kind
.
Kind
+=
"List"
resource
,
err
:=
o
.
Kind
(
kind
,
""
)
return
true
,
resource
,
err
case
GetAction
:
resource
,
err
:=
o
.
Kind
(
gvk
,
castAction
.
GetName
())
resource
,
err
:=
o
.
Kind
(
kind
,
castAction
.
GetName
())
return
true
,
resource
,
err
case
DeleteAction
:
resource
,
err
:=
o
.
Kind
(
gvk
,
castAction
.
GetName
())
resource
,
err
:=
o
.
Kind
(
kind
,
castAction
.
GetName
())
return
true
,
resource
,
err
case
CreateAction
:
...
...
@@ -84,7 +84,7 @@ func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
if
err
!=
nil
{
return
true
,
nil
,
err
}
resource
,
err
:=
o
.
Kind
(
gvk
,
meta
.
Name
)
resource
,
err
:=
o
.
Kind
(
kind
,
meta
.
Name
)
return
true
,
resource
,
err
case
UpdateAction
:
...
...
@@ -92,7 +92,7 @@ func ObjectReaction(o ObjectRetriever, mapper meta.RESTMapper) ReactionFunc {
if
err
!=
nil
{
return
true
,
nil
,
err
}
resource
,
err
:=
o
.
Kind
(
gvk
,
meta
.
Name
)
resource
,
err
:=
o
.
Kind
(
kind
,
meta
.
Name
)
return
true
,
resource
,
err
default
:
...
...
pkg/kubectl/cmd/explain.go
View file @
41b78ad2
...
...
@@ -84,7 +84,7 @@ func RunExplain(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st
}
// TODO: We should deduce the group for a resource by discovering the supported resources at server.
gvk
,
err
:=
mapper
.
KindFor
(
inModel
)
gvk
,
err
:=
mapper
.
KindFor
(
unversioned
.
GroupVersionResource
{
Resource
:
inModel
}
)
if
err
!=
nil
{
return
err
}
...
...
pkg/kubectl/cmd/rollingupdate.go
View file @
41b78ad2
...
...
@@ -360,12 +360,12 @@ func RunRollingUpdate(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, arg
if
outputFormat
!=
""
{
return
f
.
PrintObject
(
cmd
,
newRc
,
out
)
}
gvk
,
err
:=
api
.
Scheme
.
ObjectKind
(
newRc
)
kind
,
err
:=
api
.
Scheme
.
ObjectKind
(
newRc
)
if
err
!=
nil
{
return
err
}
_
,
res
:=
meta
.
KindToResource
(
gvk
.
K
ind
,
false
)
cmdutil
.
PrintSuccess
(
mapper
,
false
,
out
,
res
,
oldName
,
message
)
_
,
res
:=
meta
.
KindToResource
(
k
ind
,
false
)
cmdutil
.
PrintSuccess
(
mapper
,
false
,
out
,
res
.
Resource
,
oldName
,
message
)
return
nil
}
...
...
pkg/kubectl/cmd/util/factory.go
View file @
41b78ad2
...
...
@@ -154,16 +154,12 @@ func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
return
clients
.
ClientConfigForVersion
(
nil
)
},
RESTClient
:
func
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
{
gvk
,
err
:=
api
.
RESTMapper
.
KindFor
(
mapping
.
Resource
)
if
err
!=
nil
{
return
nil
,
err
}
mappingVersion
:=
mapping
.
GroupVersionKind
.
GroupVersion
()
client
,
err
:=
clients
.
ClientForVersion
(
&
mappingVersion
)
if
err
!=
nil
{
return
nil
,
err
}
switch
gvk
.
Group
{
switch
mapping
.
GroupVersionKind
.
Group
{
case
api
.
GroupName
:
return
client
.
RESTClient
,
nil
case
extensions
.
GroupName
:
...
...
pkg/kubectl/explain.go
View file @
41b78ad2
...
...
@@ -44,7 +44,7 @@ func GetSwaggerSchema(version unversioned.GroupVersion, kubeClient client.Interf
// SplitAndParseResourceRequest separates the users input into a model and fields
func
SplitAndParseResourceRequest
(
inResource
string
,
mapper
meta
.
RESTMapper
)
(
string
,
[]
string
,
error
)
{
inResource
,
fieldsPath
:=
splitDotNotation
(
inResource
)
inResource
,
_
=
mapper
.
ResourceSingularizer
(
expandResourceShortcut
(
inResource
)
)
inResource
,
_
=
mapper
.
ResourceSingularizer
(
expandResourceShortcut
(
unversioned
.
GroupVersionResource
{
Resource
:
inResource
})
.
Resource
)
return
inResource
,
fieldsPath
,
nil
}
...
...
pkg/kubectl/kubectl.go
View file @
41b78ad2
...
...
@@ -23,6 +23,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/apis/extensions"
)
const
kubectlAnnotationPrefix
=
"kubectl.kubernetes.io/"
...
...
@@ -80,40 +81,40 @@ var _ meta.RESTMapper = &ShortcutExpander{}
// KindFor implements meta.RESTMapper. It expands the resource first, then invokes the wrapped
// mapper.
func
(
e
ShortcutExpander
)
KindFor
(
resource
string
)
(
unversioned
.
GroupVersionKind
,
error
)
{
func
(
e
ShortcutExpander
)
KindFor
(
resource
unversioned
.
GroupVersionResource
)
(
unversioned
.
GroupVersionKind
,
error
)
{
resource
=
expandResourceShortcut
(
resource
)
return
e
.
RESTMapper
.
KindFor
(
resource
)
}
// ResourceIsValid takes a string (kind) and checks if it's a valid resource.
// It expands the resource first, then invokes the wrapped mapper.
func
(
e
ShortcutExpander
)
ResourceIsValid
(
resource
string
)
bool
{
func
(
e
ShortcutExpander
)
ResourceIsValid
(
resource
unversioned
.
GroupVersionResource
)
bool
{
return
e
.
RESTMapper
.
ResourceIsValid
(
expandResourceShortcut
(
resource
))
}
// expandResourceShortcut will return the expanded version of resource
// (something that a pkg/api/meta.RESTMapper can understand), if it is
// indeed a shortcut. Otherwise, will return resource unmodified.
func
expandResourceShortcut
(
resource
string
)
string
{
shortForms
:=
map
[
string
]
string
{
func
expandResourceShortcut
(
resource
unversioned
.
GroupVersionResource
)
unversioned
.
GroupVersionResource
{
shortForms
:=
map
[
string
]
unversioned
.
GroupVersionResource
{
// Please keep this alphabetized
"cs"
:
"componentstatuses"
,
"ds"
:
"daemonsets"
,
"ep"
:
"endpoints"
,
"ev"
:
"events"
,
"hpa"
:
"horizontalpodautoscalers"
,
"ing"
:
"ingresses"
,
"limits"
:
"limitranges"
,
"no"
:
"nodes"
,
"ns"
:
"namespaces"
,
"po"
:
"pods"
,
"pvc"
:
"persistentvolumeclaims"
,
"pv"
:
"persistentvolumes"
,
"quota"
:
"resourcequotas"
,
"rc"
:
"replicationcontrollers"
,
"svc"
:
"services"
,
"cs"
:
api
.
SchemeGroupVersion
.
WithResource
(
"componentstatuses"
)
,
"ds"
:
extensions
.
SchemeGroupVersion
.
WithResource
(
"daemonsets"
)
,
"ep"
:
api
.
SchemeGroupVersion
.
WithResource
(
"endpoints"
)
,
"ev"
:
api
.
SchemeGroupVersion
.
WithResource
(
"events"
)
,
"hpa"
:
extensions
.
SchemeGroupVersion
.
WithResource
(
"horizontalpodautoscalers"
)
,
"ing"
:
extensions
.
SchemeGroupVersion
.
WithResource
(
"ingresses"
)
,
"limits"
:
api
.
SchemeGroupVersion
.
WithResource
(
"limitranges"
)
,
"no"
:
api
.
SchemeGroupVersion
.
WithResource
(
"nodes"
)
,
"ns"
:
api
.
SchemeGroupVersion
.
WithResource
(
"namespaces"
)
,
"po"
:
api
.
SchemeGroupVersion
.
WithResource
(
"pods"
)
,
"pvc"
:
api
.
SchemeGroupVersion
.
WithResource
(
"persistentvolumeclaims"
)
,
"pv"
:
api
.
SchemeGroupVersion
.
WithResource
(
"persistentvolumes"
)
,
"quota"
:
api
.
SchemeGroupVersion
.
WithResource
(
"resourcequotas"
)
,
"rc"
:
api
.
SchemeGroupVersion
.
WithResource
(
"replicationcontrollers"
)
,
"svc"
:
api
.
SchemeGroupVersion
.
WithResource
(
"services"
)
,
}
if
expanded
,
ok
:=
shortForms
[
resource
];
ok
{
if
expanded
,
ok
:=
shortForms
[
resource
.
Resource
];
ok
{
return
expanded
}
return
resource
...
...
pkg/kubectl/resource/builder.go
View file @
41b78ad2
...
...
@@ -25,6 +25,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime"
...
...
@@ -426,7 +427,7 @@ func (b *Builder) resourceMappings() ([]*meta.RESTMapping, error) {
}
mappings
:=
[]
*
meta
.
RESTMapping
{}
for
_
,
r
:=
range
b
.
resources
{
gvk
,
err
:=
b
.
mapper
.
KindFor
(
r
)
gvk
,
err
:=
b
.
mapper
.
KindFor
(
unversioned
.
GroupVersionResource
{
Resource
:
r
}
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -446,7 +447,7 @@ func (b *Builder) resourceTupleMappings() (map[string]*meta.RESTMapping, error)
if
_
,
ok
:=
mappings
[
r
.
Resource
];
ok
{
continue
}
gvk
,
err
:=
b
.
mapper
.
KindFor
(
r
.
Resource
)
gvk
,
err
:=
b
.
mapper
.
KindFor
(
unversioned
.
GroupVersionResource
{
Resource
:
r
.
Resource
}
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
pkg/kubectl/resource_printer.go
View file @
41b78ad2
...
...
@@ -203,11 +203,24 @@ type NamePrinter struct {
// and print "resource/name" pair. If the object is a List, print all items in it.
func
(
p
*
NamePrinter
)
PrintObj
(
obj
runtime
.
Object
,
w
io
.
Writer
)
error
{
objvalue
:=
reflect
.
ValueOf
(
obj
)
.
Elem
()
kind
:=
objvalue
.
FieldByName
(
"Kind"
)
if
!
kind
.
IsValid
()
{
kind
=
reflect
.
ValueOf
(
"<unknown>"
)
kindString
:=
objvalue
.
FieldByName
(
"Kind"
)
groupVersionString
:=
objvalue
.
FieldByName
(
"APIVersion"
)
kind
:=
unversioned
.
GroupVersionKind
{}
if
!
kindString
.
IsValid
()
{
kindString
=
reflect
.
ValueOf
(
"<unknown>"
)
}
if
kind
.
String
()
==
"List"
{
kind
.
Kind
=
kindString
.
String
()
if
!
groupVersionString
.
IsValid
()
{
groupVersionString
=
reflect
.
ValueOf
(
"<unknown>/<unknown>"
)
}
gv
,
err
:=
unversioned
.
ParseGroupVersion
(
groupVersionString
.
String
())
if
err
!=
nil
{
kind
.
Group
=
gv
.
Group
kind
.
Version
=
gv
.
Version
}
if
kind
.
Kind
==
"List"
{
items
:=
objvalue
.
FieldByName
(
"Items"
)
if
items
.
Type
()
.
String
()
==
"[]runtime.RawExtension"
{
for
i
:=
0
;
i
<
items
.
Len
();
i
++
{
...
...
@@ -237,9 +250,9 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
if
!
name
.
IsValid
()
{
name
=
reflect
.
ValueOf
(
"<unknown>"
)
}
_
,
resource
:=
meta
.
KindToResource
(
kind
.
String
()
,
false
)
_
,
resource
:=
meta
.
KindToResource
(
kind
,
false
)
fmt
.
Fprintf
(
w
,
"%s/%s
\n
"
,
resource
,
name
)
fmt
.
Fprintf
(
w
,
"%s/%s
\n
"
,
resource
.
Resource
,
name
)
}
return
nil
...
...
pkg/registry/thirdpartyresourcedata/codec.go
View file @
41b78ad2
...
...
@@ -41,14 +41,55 @@ type thirdPartyResourceDataMapper struct {
var
_
meta
.
RESTMapper
=
&
thirdPartyResourceDataMapper
{}
func
(
t
*
thirdPartyResourceDataMapper
)
isThirdPartyResource
(
resource
string
)
bool
{
plural
,
_
:=
meta
.
KindToResource
(
t
.
kind
,
false
)
return
resource
==
plural
func
(
t
*
thirdPartyResourceDataMapper
)
getResource
()
unversioned
.
GroupVersionResource
{
plural
,
_
:=
meta
.
KindToResource
(
t
.
getKind
(),
false
)
return
plural
}
func
(
t
*
thirdPartyResourceDataMapper
)
getKind
()
unversioned
.
GroupVersionKind
{
return
unversioned
.
GroupVersionKind
{
Group
:
t
.
group
,
Version
:
t
.
version
,
Kind
:
t
.
kind
}
}
func
(
t
*
thirdPartyResourceDataMapper
)
isThirdPartyResource
(
partialResource
unversioned
.
GroupVersionResource
)
bool
{
actualResource
:=
t
.
getResource
()
if
strings
.
ToLower
(
partialResource
.
Resource
)
!=
strings
.
ToLower
(
actualResource
.
Resource
)
{
return
false
}
if
len
(
partialResource
.
Group
)
!=
0
&&
partialResource
.
Group
!=
actualResource
.
Group
{
return
false
}
if
len
(
partialResource
.
Version
)
!=
0
&&
partialResource
.
Version
!=
actualResource
.
Version
{
return
false
}
return
true
}
func
(
t
*
thirdPartyResourceDataMapper
)
ResourcesFor
(
resource
unversioned
.
GroupVersionResource
)
([]
unversioned
.
GroupVersionResource
,
error
)
{
if
t
.
isThirdPartyResource
(
resource
)
{
return
[]
unversioned
.
GroupVersionResource
{
t
.
getResource
()},
nil
}
return
t
.
mapper
.
ResourcesFor
(
resource
)
}
func
(
t
*
thirdPartyResourceDataMapper
)
KindsFor
(
resource
unversioned
.
GroupVersionResource
)
([]
unversioned
.
GroupVersionKind
,
error
)
{
if
t
.
isThirdPartyResource
(
resource
)
{
return
[]
unversioned
.
GroupVersionKind
{
t
.
getKind
()},
nil
}
return
t
.
mapper
.
KindsFor
(
resource
)
}
func
(
t
*
thirdPartyResourceDataMapper
)
ResourceFor
(
resource
unversioned
.
GroupVersionResource
)
(
unversioned
.
GroupVersionResource
,
error
)
{
if
t
.
isThirdPartyResource
(
resource
)
{
return
t
.
getResource
(),
nil
}
return
t
.
mapper
.
ResourceFor
(
resource
)
}
func
(
t
*
thirdPartyResourceDataMapper
)
KindFor
(
resource
string
)
(
unversioned
.
GroupVersionKind
,
error
)
{
func
(
t
*
thirdPartyResourceDataMapper
)
KindFor
(
resource
unversioned
.
GroupVersionResource
)
(
unversioned
.
GroupVersionKind
,
error
)
{
if
t
.
isThirdPartyResource
(
resource
)
{
return
unversioned
.
GroupVersionKind
{
Group
:
t
.
group
,
Version
:
t
.
version
,
Kind
:
t
.
kind
}
,
nil
return
t
.
getKind
()
,
nil
}
return
t
.
mapper
.
KindFor
(
resource
)
}
...
...
@@ -86,8 +127,7 @@ func (t *thirdPartyResourceDataMapper) ResourceSingularizer(resource string) (si
return
t
.
mapper
.
ResourceSingularizer
(
resource
)
}
// ResourceIsValid takes a string (kind) and checks if it's a valid resource
func
(
t
*
thirdPartyResourceDataMapper
)
ResourceIsValid
(
resource
string
)
bool
{
func
(
t
*
thirdPartyResourceDataMapper
)
ResourceIsValid
(
resource
unversioned
.
GroupVersionResource
)
bool
{
return
t
.
isThirdPartyResource
(
resource
)
||
t
.
mapper
.
ResourceIsValid
(
resource
)
}
...
...
pkg/registry/thirdpartyresourcedata/codec_test.go
View file @
41b78ad2
...
...
@@ -212,9 +212,9 @@ func TestResourceIsValid(t *testing.T) {
for
_
,
test
:=
range
tests
{
mapper
:=
&
thirdPartyResourceDataMapper
{
kind
:
test
.
kind
}
mapper
.
mapper
=
api
.
RESTMapper
valid
:=
mapper
.
ResourceIsValid
(
test
.
resource
)
valid
:=
mapper
.
ResourceIsValid
(
unversioned
.
GroupVersionResource
{
Resource
:
test
.
resource
}
)
if
valid
!=
test
.
valid
{
t
.
Errorf
(
"
expected: %v, saw: %v for %s"
,
test
.
valid
,
valid
,
test
.
name
)
t
.
Errorf
(
"
%s: expected: %v, actual: %v"
,
test
.
name
,
test
.
valid
,
valid
)
}
}
}
plugin/pkg/admission/namespace/autoprovision/admission.go
View file @
41b78ad2
...
...
@@ -45,11 +45,11 @@ type provision struct {
}
func
(
p
*
provision
)
Admit
(
a
admission
.
Attributes
)
(
err
error
)
{
gvk
,
err
:=
api
.
RESTMapper
.
KindFor
(
a
.
GetResource
()
.
Resource
)
kind
,
err
:=
api
.
RESTMapper
.
KindFor
(
a
.
GetResource
()
.
WithVersion
(
""
)
)
if
err
!=
nil
{
return
admission
.
NewForbidden
(
a
,
err
)
}
mapping
,
err
:=
api
.
RESTMapper
.
RESTMapping
(
gvk
.
GroupKind
(),
gvk
.
Version
)
mapping
,
err
:=
api
.
RESTMapper
.
RESTMapping
(
kind
.
GroupKind
(),
kind
.
Version
)
if
err
!=
nil
{
return
admission
.
NewForbidden
(
a
,
err
)
}
...
...
plugin/pkg/admission/namespace/exists/admission.go
View file @
41b78ad2
...
...
@@ -46,11 +46,11 @@ type exists struct {
}
func
(
e
*
exists
)
Admit
(
a
admission
.
Attributes
)
(
err
error
)
{
gvk
,
err
:=
api
.
RESTMapper
.
KindFor
(
a
.
GetResource
()
.
Resource
)
kind
,
err
:=
api
.
RESTMapper
.
KindFor
(
a
.
GetResource
()
.
WithVersion
(
""
)
)
if
err
!=
nil
{
return
errors
.
NewInternalError
(
err
)
}
mapping
,
err
:=
api
.
RESTMapper
.
RESTMapping
(
gvk
.
GroupKind
(),
gvk
.
Version
)
mapping
,
err
:=
api
.
RESTMapper
.
RESTMapping
(
kind
.
GroupKind
(),
kind
.
Version
)
if
err
!=
nil
{
return
errors
.
NewInternalError
(
err
)
}
...
...
plugin/pkg/admission/namespace/lifecycle/admission.go
View file @
41b78ad2
...
...
@@ -48,17 +48,16 @@ type lifecycle struct {
}
func
(
l
*
lifecycle
)
Admit
(
a
admission
.
Attributes
)
(
err
error
)
{
// prevent deletion of immortal namespaces
if
a
.
GetOperation
()
==
admission
.
Delete
&&
a
.
GetKind
()
==
api
.
Kind
(
"Namespace"
)
&&
l
.
immortalNamespaces
.
Has
(
a
.
GetName
())
{
return
errors
.
NewForbidden
(
a
.
GetKind
()
.
Kind
,
a
.
GetName
(),
fmt
.
Errorf
(
"this namespace may not be deleted"
))
}
gvk
,
err
:=
api
.
RESTMapper
.
KindFor
(
a
.
GetResource
()
.
Resource
)
kind
,
err
:=
api
.
RESTMapper
.
KindFor
(
a
.
GetResource
()
.
WithVersion
(
""
)
)
if
err
!=
nil
{
return
errors
.
NewInternalError
(
err
)
}
mapping
,
err
:=
api
.
RESTMapper
.
RESTMapping
(
gvk
.
GroupKind
(),
gvk
.
Version
)
mapping
,
err
:=
api
.
RESTMapper
.
RESTMapping
(
kind
.
GroupKind
(),
kind
.
Version
)
if
err
!=
nil
{
return
errors
.
NewInternalError
(
err
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment