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
37f6cb72
Commit
37f6cb72
authored
May 09, 2018
by
David Eads
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
move category expansion types to restmapper package
parent
23a9136d
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
206 additions
and
233 deletions
+206
-233
BUILD
pkg/kubectl/categories/BUILD
+2
-17
categories.go
pkg/kubectl/categories/categories.go
+2
-148
fake.go
pkg/kubectl/cmd/testing/fake.go
+4
-3
factory.go
pkg/kubectl/cmd/util/factory.go
+2
-2
factory_object_mapping.go
pkg/kubectl/cmd/util/factory_object_mapping.go
+4
-3
BUILD
pkg/kubectl/resource/BUILD
+1
-1
builder.go
pkg/kubectl/resource/builder.go
+4
-4
BUILD
staging/src/k8s.io/client-go/restmapper/BUILD
+2
-0
category_expansion.go
...ing/src/k8s.io/client-go/restmapper/category_expansion.go
+168
-0
category_expansion_test.go
...rc/k8s.io/client-go/restmapper/category_expansion_test.go
+17
-55
No files found.
pkg/kubectl/categories/BUILD
View file @
37f6cb72
load("@io_bazel_rules_go//go:def.bzl", "go_library"
, "go_test"
)
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
go_library(
name = "go_default_library",
name = "go_default_library",
...
@@ -7,22 +7,7 @@ go_library(
...
@@ -7,22 +7,7 @@ go_library(
visibility = ["//visibility:public"],
visibility = ["//visibility:public"],
deps = [
deps = [
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
"//vendor/k8s.io/client-go/restmapper:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["categories_test.go"],
embed = [":go_default_library"],
deps = [
"//vendor/github.com/googleapis/gnostic/OpenAPIv2:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/version:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest/fake:go_default_library",
],
],
)
)
...
...
pkg/kubectl/categories/categories.go
View file @
37f6cb72
...
@@ -18,155 +18,9 @@ package categories
...
@@ -18,155 +18,9 @@ package categories
import
(
import
(
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/
discovery
"
"k8s.io/client-go/
restmapper
"
)
)
// CategoryExpander maps category strings to GroupResouces.
// Categories are classification or 'tag' of a group of resources.
type
CategoryExpander
interface
{
Expand
(
category
string
)
([]
schema
.
GroupResource
,
bool
)
}
// SimpleCategoryExpander implements CategoryExpander interface
// using a static mapping of categories to GroupResource mapping.
type
SimpleCategoryExpander
struct
{
Expansions
map
[
string
][]
schema
.
GroupResource
}
func
(
e
SimpleCategoryExpander
)
Expand
(
category
string
)
([]
schema
.
GroupResource
,
bool
)
{
ret
,
ok
:=
e
.
Expansions
[
category
]
return
ret
,
ok
}
// discoveryCategoryExpander struct lets a REST Client wrapper (discoveryClient) to retrieve list of APIResourceList,
// and then convert to fallbackExpander
type
discoveryCategoryExpander
struct
{
fallbackExpander
CategoryExpander
discoveryClient
discovery
.
DiscoveryInterface
}
// NewDiscoveryCategoryExpander returns a category expander that makes use of the "categories" fields from
// the API, found through the discovery client. In case of any error or no category found (which likely
// means we're at a cluster prior to categories support, fallback to the expander provided.
func
NewDiscoveryCategoryExpander
(
fallbackExpander
CategoryExpander
,
client
discovery
.
DiscoveryInterface
)
(
discoveryCategoryExpander
,
error
)
{
if
client
==
nil
{
panic
(
"Please provide discovery client to shortcut expander"
)
}
return
discoveryCategoryExpander
{
fallbackExpander
:
fallbackExpander
,
discoveryClient
:
client
},
nil
}
func
(
e
discoveryCategoryExpander
)
Expand
(
category
string
)
([]
schema
.
GroupResource
,
bool
)
{
// Get all supported resources for groups and versions from server, if no resource found, fallback anyway.
apiResourceLists
,
_
:=
e
.
discoveryClient
.
ServerResources
()
if
len
(
apiResourceLists
)
==
0
{
return
e
.
fallbackExpander
.
Expand
(
category
)
}
discoveredExpansions
:=
map
[
string
][]
schema
.
GroupResource
{}
for
_
,
apiResourceList
:=
range
apiResourceLists
{
gv
,
err
:=
schema
.
ParseGroupVersion
(
apiResourceList
.
GroupVersion
)
if
err
!=
nil
{
return
e
.
fallbackExpander
.
Expand
(
category
)
}
// Collect GroupVersions by categories
for
_
,
apiResource
:=
range
apiResourceList
.
APIResources
{
if
categories
:=
apiResource
.
Categories
;
len
(
categories
)
>
0
{
for
_
,
category
:=
range
categories
{
groupResource
:=
schema
.
GroupResource
{
Group
:
gv
.
Group
,
Resource
:
apiResource
.
Name
,
}
discoveredExpansions
[
category
]
=
append
(
discoveredExpansions
[
category
],
groupResource
)
}
}
}
}
if
len
(
discoveredExpansions
)
==
0
{
// We don't know if the server really don't have any resource with categories,
// or we're on a cluster version prior to categories support. Anyways, fallback.
return
e
.
fallbackExpander
.
Expand
(
category
)
}
ret
,
ok
:=
discoveredExpansions
[
category
]
return
ret
,
ok
}
// discoveryFilteredExpander expands the given CategoryExpander (delegate) to filter group and resource returned from server
type
discoveryFilteredExpander
struct
{
delegate
CategoryExpander
discoveryClient
discovery
.
DiscoveryInterface
}
// NewDiscoveryFilteredExpander returns a category expander that filters the returned groupresources
// by what the server has available
func
NewDiscoveryFilteredExpander
(
delegate
CategoryExpander
,
client
discovery
.
DiscoveryInterface
)
(
discoveryFilteredExpander
,
error
)
{
if
client
==
nil
{
panic
(
"Please provide discovery client to shortcut expander"
)
}
return
discoveryFilteredExpander
{
delegate
:
delegate
,
discoveryClient
:
client
},
nil
}
func
(
e
discoveryFilteredExpander
)
Expand
(
category
string
)
([]
schema
.
GroupResource
,
bool
)
{
delegateExpansion
,
ok
:=
e
.
delegate
.
Expand
(
category
)
// Check if we have access to server resources
apiResources
,
err
:=
e
.
discoveryClient
.
ServerResources
()
if
err
!=
nil
{
return
delegateExpansion
,
ok
}
availableResources
,
err
:=
discovery
.
GroupVersionResources
(
apiResources
)
if
err
!=
nil
{
return
delegateExpansion
,
ok
}
available
:=
[]
schema
.
GroupResource
{}
for
_
,
requestedResource
:=
range
delegateExpansion
{
for
availableResource
:=
range
availableResources
{
if
requestedResource
.
Group
==
availableResource
.
Group
&&
requestedResource
.
Resource
==
availableResource
.
Resource
{
available
=
append
(
available
,
requestedResource
)
break
}
}
}
return
available
,
ok
}
// UnionCategoryExpander implements CategoryExpander interface.
// It maps given category string to union of expansions returned by all the CategoryExpanders in the list.
type
UnionCategoryExpander
[]
CategoryExpander
func
(
u
UnionCategoryExpander
)
Expand
(
category
string
)
([]
schema
.
GroupResource
,
bool
)
{
ret
:=
[]
schema
.
GroupResource
{}
ok
:=
false
// Expand the category for each CategoryExpander in the list and merge/combine the results.
for
_
,
expansion
:=
range
u
{
curr
,
currOk
:=
expansion
.
Expand
(
category
)
for
_
,
currGR
:=
range
curr
{
found
:=
false
for
_
,
existing
:=
range
ret
{
if
existing
==
currGR
{
found
=
true
break
}
}
if
!
found
{
ret
=
append
(
ret
,
currGR
)
}
}
ok
=
ok
||
currOk
}
return
ret
,
ok
}
// legacyUserResources are the resource names that apply to the primary, user facing resources used by
// legacyUserResources are the resource names that apply to the primary, user facing resources used by
// client tools. They are in deletion-first order - dependent resources should be last.
// client tools. They are in deletion-first order - dependent resources should be last.
// Should remain exported in order to expose a current list of resources to downstream
// Should remain exported in order to expose a current list of resources to downstream
...
@@ -185,7 +39,7 @@ var legacyUserResources = []schema.GroupResource{
...
@@ -185,7 +39,7 @@ var legacyUserResources = []schema.GroupResource{
}
}
// LegacyCategoryExpander is the old hardcoded expansion
// LegacyCategoryExpander is the old hardcoded expansion
var
LegacyCategoryExpander
CategoryExpander
=
SimpleCategoryExpander
{
var
LegacyCategoryExpander
restmapper
.
CategoryExpander
=
restmapper
.
SimpleCategoryExpander
{
Expansions
:
map
[
string
][]
schema
.
GroupResource
{
Expansions
:
map
[
string
][]
schema
.
GroupResource
{
"all"
:
legacyUserResources
,
"all"
:
legacyUserResources
,
},
},
...
...
pkg/kubectl/cmd/testing/fake.go
View file @
37f6cb72
...
@@ -287,7 +287,7 @@ func (f *TestFactory) Cleanup() {
...
@@ -287,7 +287,7 @@ func (f *TestFactory) Cleanup() {
os
.
Remove
(
f
.
tempConfigFile
.
Name
())
os
.
Remove
(
f
.
tempConfigFile
.
Name
())
}
}
func
(
f
*
TestFactory
)
CategoryExpander
()
categories
.
CategoryExpander
{
func
(
f
*
TestFactory
)
CategoryExpander
()
restmapper
.
CategoryExpander
{
return
categories
.
LegacyCategoryExpander
return
categories
.
LegacyCategoryExpander
}
}
...
@@ -335,6 +335,7 @@ func (f *TestFactory) Command(*cobra.Command, bool) string {
...
@@ -335,6 +335,7 @@ func (f *TestFactory) Command(*cobra.Command, bool) string {
func
(
f
*
TestFactory
)
NewBuilder
()
*
resource
.
Builder
{
func
(
f
*
TestFactory
)
NewBuilder
()
*
resource
.
Builder
{
mapper
,
err
:=
f
.
RESTMapper
()
mapper
,
err
:=
f
.
RESTMapper
()
categoryExpander
,
err2
:=
f
.
CategoryExpander
()
return
resource
.
NewFakeBuilder
(
return
resource
.
NewFakeBuilder
(
func
(
version
schema
.
GroupVersion
)
(
resource
.
RESTClient
,
error
)
{
func
(
version
schema
.
GroupVersion
)
(
resource
.
RESTClient
,
error
)
{
...
@@ -347,8 +348,8 @@ func (f *TestFactory) NewBuilder() *resource.Builder {
...
@@ -347,8 +348,8 @@ func (f *TestFactory) NewBuilder() *resource.Builder {
return
f
.
Client
,
nil
return
f
.
Client
,
nil
},
},
mapper
,
mapper
,
f
.
CategoryExpander
()
,
categoryExpander
,
)
.
AddError
(
err
)
)
.
AddError
(
err
)
.
AddError
(
err2
)
}
}
func
(
f
*
TestFactory
)
KubernetesClientSet
()
(
*
kubernetes
.
Clientset
,
error
)
{
func
(
f
*
TestFactory
)
KubernetesClientSet
()
(
*
kubernetes
.
Clientset
,
error
)
{
...
...
pkg/kubectl/cmd/util/factory.go
View file @
37f6cb72
...
@@ -36,13 +36,13 @@ import (
...
@@ -36,13 +36,13 @@ import (
"k8s.io/client-go/dynamic"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes"
restclient
"k8s.io/client-go/rest"
restclient
"k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
scaleclient
"k8s.io/client-go/scale"
scaleclient
"k8s.io/client-go/scale"
api
"k8s.io/kubernetes/pkg/apis/core"
api
"k8s.io/kubernetes/pkg/apis/core"
apiv1
"k8s.io/kubernetes/pkg/apis/core/v1"
apiv1
"k8s.io/kubernetes/pkg/apis/core/v1"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
coreclient
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
coreclient
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/categories"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kubernetes/pkg/kubectl/plugins"
"k8s.io/kubernetes/pkg/kubectl/plugins"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/resource"
...
@@ -169,7 +169,7 @@ type ClientAccessFactory interface {
...
@@ -169,7 +169,7 @@ type ClientAccessFactory interface {
// Generally they provide object typing and functions that build requests based on the negotiated clients.
// Generally they provide object typing and functions that build requests based on the negotiated clients.
type
ObjectMappingFactory
interface
{
type
ObjectMappingFactory
interface
{
// Returns interface for expanding categories like `all`.
// Returns interface for expanding categories like `all`.
CategoryExpander
()
categories
.
CategoryExpander
CategoryExpander
()
restmapper
.
CategoryExpander
// Returns a RESTClient for working with the specified RESTMapping or an error. This is intended
// Returns a RESTClient for working with the specified RESTMapping or an error. This is intended
// for working with arbitrary resources and is not guaranteed to point to a Kubernetes APIServer.
// for working with arbitrary resources and is not guaranteed to point to a Kubernetes APIServer.
ClientForMapping
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
ClientForMapping
(
mapping
*
meta
.
RESTMapping
)
(
resource
.
RESTClient
,
error
)
...
...
pkg/kubectl/cmd/util/factory_object_mapping.go
View file @
37f6cb72
...
@@ -40,6 +40,7 @@ import (
...
@@ -40,6 +40,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/dynamic"
restclient
"k8s.io/client-go/rest"
restclient
"k8s.io/client-go/rest"
"k8s.io/client-go/restmapper"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/batch"
api
"k8s.io/kubernetes/pkg/apis/core"
api
"k8s.io/kubernetes/pkg/apis/core"
...
@@ -75,17 +76,17 @@ func NewObjectMappingFactory(clientAccessFactory ClientAccessFactory) ObjectMapp
...
@@ -75,17 +76,17 @@ func NewObjectMappingFactory(clientAccessFactory ClientAccessFactory) ObjectMapp
return
f
return
f
}
}
func
(
f
*
ring1Factory
)
CategoryExpander
()
categories
.
CategoryExpander
{
func
(
f
*
ring1Factory
)
CategoryExpander
()
restmapper
.
CategoryExpander
{
legacyExpander
:=
categories
.
LegacyCategoryExpander
legacyExpander
:=
categories
.
LegacyCategoryExpander
discoveryClient
,
err
:=
f
.
clientAccessFactory
.
DiscoveryClient
()
discoveryClient
,
err
:=
f
.
clientAccessFactory
.
DiscoveryClient
()
if
err
==
nil
{
if
err
==
nil
{
// fallback is the legacy expander wrapped with discovery based filtering
// fallback is the legacy expander wrapped with discovery based filtering
fallbackExpander
,
err
:=
categories
.
NewDiscoveryFilteredExpander
(
legacyExpander
,
discoveryClient
)
fallbackExpander
,
err
:=
restmapper
.
NewDiscoveryFilteredExpander
(
legacyExpander
,
discoveryClient
)
CheckErr
(
err
)
CheckErr
(
err
)
// by default use the expander that discovers based on "categories" field from the API
// by default use the expander that discovers based on "categories" field from the API
discoveryCategoryExpander
,
err
:=
categories
.
NewDiscoveryCategoryExpander
(
fallbackExpander
,
discoveryClient
)
discoveryCategoryExpander
,
err
:=
restmapper
.
NewDiscoveryCategoryExpander
(
fallbackExpander
,
discoveryClient
)
CheckErr
(
err
)
CheckErr
(
err
)
return
discoveryCategoryExpander
return
discoveryCategoryExpander
...
...
pkg/kubectl/resource/BUILD
View file @
37f6cb72
...
@@ -22,7 +22,6 @@ go_library(
...
@@ -22,7 +22,6 @@ go_library(
"//build/visible_to:pkg_kubectl_resource_CONSUMERS",
"//build/visible_to:pkg_kubectl_resource_CONSUMERS",
],
],
deps = [
deps = [
"//pkg/kubectl/categories:go_default_library",
"//pkg/kubectl/validation:go_default_library",
"//pkg/kubectl/validation:go_default_library",
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
"//vendor/golang.org/x/text/transform:go_default_library",
"//vendor/golang.org/x/text/transform:go_default_library",
...
@@ -44,6 +43,7 @@ go_library(
...
@@ -44,6 +43,7 @@ go_library(
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/dynamic:go_default_library",
"//vendor/k8s.io/client-go/dynamic:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/restmapper:go_default_library",
],
],
)
)
...
...
pkg/kubectl/resource/builder.go
View file @
37f6cb72
...
@@ -34,7 +34,7 @@ import (
...
@@ -34,7 +34,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/serializer"
"k8s.io/apimachinery/pkg/runtime/serializer"
utilerrors
"k8s.io/apimachinery/pkg/util/errors"
utilerrors
"k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/
kubernetes/pkg/kubectl/categories
"
"k8s.io/
client-go/restmapper
"
"k8s.io/kubernetes/pkg/kubectl/validation"
"k8s.io/kubernetes/pkg/kubectl/validation"
)
)
...
@@ -47,7 +47,7 @@ const defaultHttpGetAttempts int = 3
...
@@ -47,7 +47,7 @@ const defaultHttpGetAttempts int = 3
// from the command line and converting them to a list of resources to iterate
// from the command line and converting them to a list of resources to iterate
// over using the Visitor interface.
// over using the Visitor interface.
type
Builder
struct
{
type
Builder
struct
{
categoryExpander
categories
.
CategoryExpander
categoryExpander
restmapper
.
CategoryExpander
// mapper is set explicitly by resource builders
// mapper is set explicitly by resource builders
mapper
*
mapper
mapper
*
mapper
...
@@ -143,7 +143,7 @@ type resourceTuple struct {
...
@@ -143,7 +143,7 @@ type resourceTuple struct {
type
FakeClientFunc
func
(
version
schema
.
GroupVersion
)
(
RESTClient
,
error
)
type
FakeClientFunc
func
(
version
schema
.
GroupVersion
)
(
RESTClient
,
error
)
func
NewFakeBuilder
(
fakeClientFn
FakeClientFunc
,
restMapper
meta
.
RESTMapper
,
categoryExpander
categories
.
CategoryExpander
)
*
Builder
{
func
NewFakeBuilder
(
fakeClientFn
FakeClientFunc
,
restMapper
meta
.
RESTMapper
,
categoryExpander
restmapper
.
CategoryExpander
)
*
Builder
{
ret
:=
NewBuilder
(
nil
,
restMapper
,
categoryExpander
)
ret
:=
NewBuilder
(
nil
,
restMapper
,
categoryExpander
)
ret
.
fakeClientFn
=
fakeClientFn
ret
.
fakeClientFn
=
fakeClientFn
return
ret
return
ret
...
@@ -153,7 +153,7 @@ func NewFakeBuilder(fakeClientFn FakeClientFunc, restMapper meta.RESTMapper, cat
...
@@ -153,7 +153,7 @@ func NewFakeBuilder(fakeClientFn FakeClientFunc, restMapper meta.RESTMapper, cat
// internal or unstructured must be specified.
// internal or unstructured must be specified.
// TODO: Add versioned client (although versioned is still lossy)
// TODO: Add versioned client (although versioned is still lossy)
// TODO remove internal and unstructured mapper and instead have them set the negotiated serializer for use in the client
// TODO remove internal and unstructured mapper and instead have them set the negotiated serializer for use in the client
func
NewBuilder
(
clientConfigFn
ClientConfigFunc
,
restMapper
meta
.
RESTMapper
,
categoryExpander
categories
.
CategoryExpander
)
*
Builder
{
func
NewBuilder
(
clientConfigFn
ClientConfigFunc
,
restMapper
meta
.
RESTMapper
,
categoryExpander
restmapper
.
CategoryExpander
)
*
Builder
{
return
&
Builder
{
return
&
Builder
{
clientConfigFn
:
clientConfigFn
,
clientConfigFn
:
clientConfigFn
,
restMapper
:
restMapper
,
restMapper
:
restMapper
,
...
...
staging/src/k8s.io/client-go/restmapper/BUILD
View file @
37f6cb72
...
@@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
...
@@ -3,6 +3,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
go_library(
name = "go_default_library",
name = "go_default_library",
srcs = [
srcs = [
"category_expansion.go",
"discovery.go",
"discovery.go",
"shortcut.go",
"shortcut.go",
],
],
...
@@ -20,6 +21,7 @@ go_library(
...
@@ -20,6 +21,7 @@ go_library(
go_test(
go_test(
name = "go_default_test",
name = "go_default_test",
srcs = [
srcs = [
"category_expansion_test.go",
"discovery_test.go",
"discovery_test.go",
"shortcut_test.go",
"shortcut_test.go",
],
],
...
...
staging/src/k8s.io/client-go/restmapper/category_expansion.go
0 → 100644
View file @
37f6cb72
/*
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
restmapper
import
(
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/discovery"
)
// CategoryExpander maps category strings to GroupResouces.
// Categories are classification or 'tag' of a group of resources.
type
CategoryExpander
interface
{
Expand
(
category
string
)
([]
schema
.
GroupResource
,
bool
)
}
// SimpleCategoryExpander implements CategoryExpander interface
// using a static mapping of categories to GroupResource mapping.
type
SimpleCategoryExpander
struct
{
Expansions
map
[
string
][]
schema
.
GroupResource
}
func
(
e
SimpleCategoryExpander
)
Expand
(
category
string
)
([]
schema
.
GroupResource
,
bool
)
{
ret
,
ok
:=
e
.
Expansions
[
category
]
return
ret
,
ok
}
// discoveryCategoryExpander struct lets a REST Client wrapper (discoveryClient) to retrieve list of APIResourceList,
// and then convert to fallbackExpander
type
discoveryCategoryExpander
struct
{
fallbackExpander
CategoryExpander
discoveryClient
discovery
.
DiscoveryInterface
}
// NewDiscoveryCategoryExpander returns a category expander that makes use of the "categories" fields from
// the API, found through the discovery client. In case of any error or no category found (which likely
// means we're at a cluster prior to categories support, fallback to the expander provided.
func
NewDiscoveryCategoryExpander
(
fallbackExpander
CategoryExpander
,
client
discovery
.
DiscoveryInterface
)
(
discoveryCategoryExpander
,
error
)
{
if
client
==
nil
{
panic
(
"Please provide discovery client to shortcut expander"
)
}
return
discoveryCategoryExpander
{
fallbackExpander
:
fallbackExpander
,
discoveryClient
:
client
},
nil
}
func
(
e
discoveryCategoryExpander
)
Expand
(
category
string
)
([]
schema
.
GroupResource
,
bool
)
{
// Get all supported resources for groups and versions from server, if no resource found, fallback anyway.
apiResourceLists
,
_
:=
e
.
discoveryClient
.
ServerResources
()
if
len
(
apiResourceLists
)
==
0
{
return
e
.
fallbackExpander
.
Expand
(
category
)
}
discoveredExpansions
:=
map
[
string
][]
schema
.
GroupResource
{}
for
_
,
apiResourceList
:=
range
apiResourceLists
{
gv
,
err
:=
schema
.
ParseGroupVersion
(
apiResourceList
.
GroupVersion
)
if
err
!=
nil
{
return
e
.
fallbackExpander
.
Expand
(
category
)
}
// Collect GroupVersions by categories
for
_
,
apiResource
:=
range
apiResourceList
.
APIResources
{
if
categories
:=
apiResource
.
Categories
;
len
(
categories
)
>
0
{
for
_
,
category
:=
range
categories
{
groupResource
:=
schema
.
GroupResource
{
Group
:
gv
.
Group
,
Resource
:
apiResource
.
Name
,
}
discoveredExpansions
[
category
]
=
append
(
discoveredExpansions
[
category
],
groupResource
)
}
}
}
}
if
len
(
discoveredExpansions
)
==
0
{
// We don't know if the server really don't have any resource with categories,
// or we're on a cluster version prior to categories support. Anyways, fallback.
return
e
.
fallbackExpander
.
Expand
(
category
)
}
ret
,
ok
:=
discoveredExpansions
[
category
]
return
ret
,
ok
}
// discoveryFilteredExpander expands the given CategoryExpander (delegate) to filter group and resource returned from server
type
discoveryFilteredExpander
struct
{
delegate
CategoryExpander
discoveryClient
discovery
.
DiscoveryInterface
}
// NewDiscoveryFilteredExpander returns a category expander that filters the returned groupresources
// by what the server has available
func
NewDiscoveryFilteredExpander
(
delegate
CategoryExpander
,
client
discovery
.
DiscoveryInterface
)
(
discoveryFilteredExpander
,
error
)
{
if
client
==
nil
{
panic
(
"Please provide discovery client to shortcut expander"
)
}
return
discoveryFilteredExpander
{
delegate
:
delegate
,
discoveryClient
:
client
},
nil
}
func
(
e
discoveryFilteredExpander
)
Expand
(
category
string
)
([]
schema
.
GroupResource
,
bool
)
{
delegateExpansion
,
ok
:=
e
.
delegate
.
Expand
(
category
)
// Check if we have access to server resources
apiResources
,
err
:=
e
.
discoveryClient
.
ServerResources
()
if
err
!=
nil
{
return
delegateExpansion
,
ok
}
availableResources
,
err
:=
discovery
.
GroupVersionResources
(
apiResources
)
if
err
!=
nil
{
return
delegateExpansion
,
ok
}
available
:=
[]
schema
.
GroupResource
{}
for
_
,
requestedResource
:=
range
delegateExpansion
{
for
availableResource
:=
range
availableResources
{
if
requestedResource
.
Group
==
availableResource
.
Group
&&
requestedResource
.
Resource
==
availableResource
.
Resource
{
available
=
append
(
available
,
requestedResource
)
break
}
}
}
return
available
,
ok
}
// UnionCategoryExpander implements CategoryExpander interface.
// It maps given category string to union of expansions returned by all the CategoryExpanders in the list.
type
UnionCategoryExpander
[]
CategoryExpander
func
(
u
UnionCategoryExpander
)
Expand
(
category
string
)
([]
schema
.
GroupResource
,
bool
)
{
ret
:=
[]
schema
.
GroupResource
{}
ok
:=
false
// Expand the category for each CategoryExpander in the list and merge/combine the results.
for
_
,
expansion
:=
range
u
{
curr
,
currOk
:=
expansion
.
Expand
(
category
)
for
_
,
currGR
:=
range
curr
{
found
:=
false
for
_
,
existing
:=
range
ret
{
if
existing
==
currGR
{
found
=
true
break
}
}
if
!
found
{
ret
=
append
(
ret
,
currGR
)
}
}
ok
=
ok
||
currOk
}
return
ret
,
ok
}
pkg/kubectl/categories/categories
_test.go
→
staging/src/k8s.io/client-go/restmapper/category_expansion
_test.go
View file @
37f6cb72
...
@@ -14,19 +14,14 @@ See the License for the specific language governing permissions and
...
@@ -14,19 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
limitations under the License.
*/
*/
package
categories
package
restmapper
import
(
import
(
"reflect"
"reflect"
"testing"
"testing"
"github.com/googleapis/gnostic/OpenAPIv2"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/discovery"
restclient
"k8s.io/client-go/rest"
"k8s.io/client-go/rest/fake"
)
)
func
TestCategoryExpansion
(
t
*
testing
.
T
)
{
func
TestCategoryExpansion
(
t
*
testing
.
T
)
{
...
@@ -46,23 +41,28 @@ func TestCategoryExpansion(t *testing.T) {
...
@@ -46,23 +41,28 @@ func TestCategoryExpansion(t *testing.T) {
name
:
"all-replacement"
,
name
:
"all-replacement"
,
arg
:
"all"
,
arg
:
"all"
,
expected
:
[]
schema
.
GroupResource
{
expected
:
[]
schema
.
GroupResource
{
{
Resource
:
"pods"
},
{
Resource
:
"one"
},
{
Resource
:
"replicationcontrollers"
},
{
Resource
:
"two"
},
{
Resource
:
"services"
},
{
Resource
:
"three"
,
Group
:
"alpha"
},
{
Resource
:
"statefulsets"
,
Group
:
"apps"
},
{
Resource
:
"four"
,
Group
:
"bravo"
},
{
Resource
:
"horizontalpodautoscalers"
,
Group
:
"autoscaling"
},
{
Resource
:
"jobs"
,
Group
:
"batch"
},
{
Resource
:
"cronjobs"
,
Group
:
"batch"
},
{
Resource
:
"daemonsets"
,
Group
:
"extensions"
},
{
Resource
:
"deployments"
,
Group
:
"extensions"
},
{
Resource
:
"replicasets"
,
Group
:
"extensions"
},
},
},
expectedOk
:
true
,
expectedOk
:
true
,
},
},
}
}
for
_
,
test
:=
range
tests
{
for
_
,
test
:=
range
tests
{
actual
,
actualOk
:=
LegacyCategoryExpander
.
Expand
(
test
.
arg
)
simpleCategoryExpander
:=
SimpleCategoryExpander
{
Expansions
:
map
[
string
][]
schema
.
GroupResource
{
"all"
:
{
{
Group
:
""
,
Resource
:
"one"
},
{
Group
:
""
,
Resource
:
"two"
},
{
Group
:
"alpha"
,
Resource
:
"three"
},
{
Group
:
"bravo"
,
Resource
:
"four"
},
},
},
}
actual
,
actualOk
:=
simpleCategoryExpander
.
Expand
(
test
.
arg
)
if
e
,
a
:=
test
.
expected
,
actual
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
if
e
,
a
:=
test
.
expected
,
actual
;
!
reflect
.
DeepEqual
(
e
,
a
)
{
t
.
Errorf
(
"%s: expected %s, got %s"
,
test
.
name
,
e
,
a
)
t
.
Errorf
(
"%s: expected %s, got %s"
,
test
.
name
,
e
,
a
)
}
}
...
@@ -146,41 +146,3 @@ func TestDiscoveryCategoryExpander(t *testing.T) {
...
@@ -146,41 +146,3 @@ func TestDiscoveryCategoryExpander(t *testing.T) {
}
}
}
}
type
fakeDiscoveryClient
struct
{
serverResourcesHandler
func
()
([]
*
metav1
.
APIResourceList
,
error
)
}
var
_
discovery
.
DiscoveryInterface
=
&
fakeDiscoveryClient
{}
func
(
c
*
fakeDiscoveryClient
)
RESTClient
()
restclient
.
Interface
{
return
&
fake
.
RESTClient
{}
}
func
(
c
*
fakeDiscoveryClient
)
ServerGroups
()
(
*
metav1
.
APIGroupList
,
error
)
{
return
nil
,
nil
}
func
(
c
*
fakeDiscoveryClient
)
ServerResourcesForGroupVersion
(
groupVersion
string
)
(
*
metav1
.
APIResourceList
,
error
)
{
return
&
metav1
.
APIResourceList
{},
nil
}
func
(
c
*
fakeDiscoveryClient
)
ServerResources
()
([]
*
metav1
.
APIResourceList
,
error
)
{
return
c
.
serverResourcesHandler
()
}
func
(
c
*
fakeDiscoveryClient
)
ServerPreferredResources
()
([]
*
metav1
.
APIResourceList
,
error
)
{
return
nil
,
nil
}
func
(
c
*
fakeDiscoveryClient
)
ServerPreferredNamespacedResources
()
([]
*
metav1
.
APIResourceList
,
error
)
{
return
nil
,
nil
}
func
(
c
*
fakeDiscoveryClient
)
ServerVersion
()
(
*
version
.
Info
,
error
)
{
return
&
version
.
Info
{},
nil
}
func
(
c
*
fakeDiscoveryClient
)
OpenAPISchema
()
(
*
openapi_v2
.
Document
,
error
)
{
return
&
openapi_v2
.
Document
{},
nil
}
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