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
06c12f67
Unverified
Commit
06c12f67
authored
Jan 22, 2017
by
Jordan Liggitt
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
describe: use unstructured objects
parent
b6d4f371
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
112 additions
and
18 deletions
+112
-18
describe.go
pkg/kubectl/cmd/describe.go
+11
-3
describe_test.go
pkg/kubectl/cmd/describe_test.go
+40
-15
fake.go
pkg/kubectl/cmd/testing/fake.go
+61
-0
No files found.
pkg/kubectl/cmd/describe.go
View file @
06c12f67
...
...
@@ -25,6 +25,7 @@ import (
apierrors
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
utilerrors
"k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/sets"
...
...
@@ -111,8 +112,11 @@ func RunDescribe(f cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, a
return
cmdutil
.
UsageError
(
cmd
,
"Required resource not specified."
)
}
mapper
,
typer
:=
f
.
Object
()
r
:=
resource
.
NewBuilder
(
mapper
,
typer
,
resource
.
ClientMapperFunc
(
f
.
ClientForMapping
),
f
.
Decoder
(
true
))
.
mapper
,
typer
,
err
:=
f
.
UnstructuredObject
()
if
err
!=
nil
{
return
err
}
r
:=
resource
.
NewBuilder
(
mapper
,
typer
,
resource
.
ClientMapperFunc
(
f
.
UnstructuredClientForMapping
),
unstructured
.
UnstructuredJSONScheme
)
.
ContinueOnError
()
.
NamespaceParam
(
cmdNamespace
)
.
DefaultNamespace
()
.
AllNamespaces
(
allNamespaces
)
.
FilenameParam
(
enforceNamespace
,
options
)
.
...
...
@@ -168,7 +172,11 @@ func RunDescribe(f cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, a
}
func
DescribeMatchingResources
(
mapper
meta
.
RESTMapper
,
typer
runtime
.
ObjectTyper
,
f
cmdutil
.
Factory
,
namespace
,
rsrc
,
prefix
string
,
describerSettings
*
kubectl
.
DescriberSettings
,
out
io
.
Writer
,
originalError
error
)
error
{
r
:=
resource
.
NewBuilder
(
mapper
,
typer
,
resource
.
ClientMapperFunc
(
f
.
ClientForMapping
),
f
.
Decoder
(
true
))
.
mapper
,
typer
,
err
:=
f
.
UnstructuredObject
()
if
err
!=
nil
{
return
err
}
r
:=
resource
.
NewBuilder
(
mapper
,
typer
,
resource
.
ClientMapperFunc
(
f
.
UnstructuredClientForMapping
),
unstructured
.
UnstructuredJSONScheme
)
.
NamespaceParam
(
namespace
)
.
DefaultNamespace
()
.
ResourceTypeOrNameArgs
(
true
,
rsrc
)
.
SingleResourceType
()
.
...
...
pkg/kubectl/cmd/describe_test.go
View file @
06c12f67
...
...
@@ -30,11 +30,11 @@ import (
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func
TestDescribeUnknownSchemaObject
(
t
*
testing
.
T
)
{
d
:=
&
testDescriber
{
Output
:
"test output"
}
f
,
tf
,
codec
,
ns
:=
cmdtesting
.
NewTestFactory
()
f
,
tf
,
codec
,
_
:=
cmdtesting
.
NewTestFactory
()
tf
.
Describer
=
d
tf
.
Client
=
&
fake
.
RESTClient
{
tf
.
Unstructured
Client
=
&
fake
.
RESTClient
{
APIRegistry
:
api
.
Registry
,
NegotiatedSerializer
:
ns
,
NegotiatedSerializer
:
unstructuredSerializer
,
Resp
:
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
cmdtesting
.
NewInternalType
(
""
,
""
,
"foo"
))},
}
tf
.
Namespace
=
"non-default"
...
...
@@ -43,6 +43,31 @@ func TestDescribeUnknownSchemaObject(t *testing.T) {
cmd
:=
NewCmdDescribe
(
f
,
buf
,
buferr
)
cmd
.
Run
(
cmd
,
[]
string
{
"type"
,
"foo"
})
if
d
.
Name
!=
"foo"
||
d
.
Namespace
!=
""
{
t
.
Errorf
(
"unexpected describer: %#v"
,
d
)
}
if
buf
.
String
()
!=
fmt
.
Sprintf
(
"%s"
,
d
.
Output
)
{
t
.
Errorf
(
"unexpected output: %s"
,
buf
.
String
())
}
}
// Verifies that schemas that are not in the master tree of Kubernetes can be retrieved via Get.
func
TestDescribeUnknownNamespacedSchemaObject
(
t
*
testing
.
T
)
{
d
:=
&
testDescriber
{
Output
:
"test output"
}
f
,
tf
,
codec
,
_
:=
cmdtesting
.
NewTestFactory
()
tf
.
Describer
=
d
tf
.
UnstructuredClient
=
&
fake
.
RESTClient
{
APIRegistry
:
api
.
Registry
,
NegotiatedSerializer
:
unstructuredSerializer
,
Resp
:
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
cmdtesting
.
NewInternalNamespacedType
(
""
,
""
,
"foo"
,
"non-default"
))},
}
tf
.
Namespace
=
"non-default"
buf
:=
bytes
.
NewBuffer
([]
byte
{})
buferr
:=
bytes
.
NewBuffer
([]
byte
{})
cmd
:=
NewCmdDescribe
(
f
,
buf
,
buferr
)
cmd
.
Run
(
cmd
,
[]
string
{
"namespacedtype"
,
"foo"
})
if
d
.
Name
!=
"foo"
||
d
.
Namespace
!=
"non-default"
{
t
.
Errorf
(
"unexpected describer: %#v"
,
d
)
}
...
...
@@ -54,12 +79,12 @@ func TestDescribeUnknownSchemaObject(t *testing.T) {
func
TestDescribeObject
(
t
*
testing
.
T
)
{
_
,
_
,
rc
:=
testData
()
f
,
tf
,
codec
,
ns
:=
cmdtesting
.
NewAPIFactory
()
f
,
tf
,
codec
,
_
:=
cmdtesting
.
NewAPIFactory
()
d
:=
&
testDescriber
{
Output
:
"test output"
}
tf
.
Describer
=
d
tf
.
Client
=
&
fake
.
RESTClient
{
tf
.
Unstructured
Client
=
&
fake
.
RESTClient
{
APIRegistry
:
api
.
Registry
,
NegotiatedSerializer
:
ns
,
NegotiatedSerializer
:
unstructuredSerializer
,
Client
:
fake
.
CreateHTTPClient
(
func
(
req
*
http
.
Request
)
(
*
http
.
Response
,
error
)
{
switch
p
,
m
:=
req
.
URL
.
Path
,
req
.
Method
;
{
case
p
==
"/namespaces/test/replicationcontrollers/redis-master"
&&
m
==
"GET"
:
...
...
@@ -88,12 +113,12 @@ func TestDescribeObject(t *testing.T) {
func
TestDescribeListObjects
(
t
*
testing
.
T
)
{
pods
,
_
,
_
:=
testData
()
f
,
tf
,
codec
,
ns
:=
cmdtesting
.
NewAPIFactory
()
f
,
tf
,
codec
,
_
:=
cmdtesting
.
NewAPIFactory
()
d
:=
&
testDescriber
{
Output
:
"test output"
}
tf
.
Describer
=
d
tf
.
Client
=
&
fake
.
RESTClient
{
tf
.
Unstructured
Client
=
&
fake
.
RESTClient
{
APIRegistry
:
api
.
Registry
,
NegotiatedSerializer
:
ns
,
NegotiatedSerializer
:
unstructuredSerializer
,
Resp
:
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
pods
)},
}
...
...
@@ -109,12 +134,12 @@ func TestDescribeListObjects(t *testing.T) {
func
TestDescribeObjectShowEvents
(
t
*
testing
.
T
)
{
pods
,
_
,
_
:=
testData
()
f
,
tf
,
codec
,
ns
:=
cmdtesting
.
NewAPIFactory
()
f
,
tf
,
codec
,
_
:=
cmdtesting
.
NewAPIFactory
()
d
:=
&
testDescriber
{
Output
:
"test output"
}
tf
.
Describer
=
d
tf
.
Client
=
&
fake
.
RESTClient
{
tf
.
Unstructured
Client
=
&
fake
.
RESTClient
{
APIRegistry
:
api
.
Registry
,
NegotiatedSerializer
:
ns
,
NegotiatedSerializer
:
unstructuredSerializer
,
Resp
:
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
pods
)},
}
...
...
@@ -131,12 +156,12 @@ func TestDescribeObjectShowEvents(t *testing.T) {
func
TestDescribeObjectSkipEvents
(
t
*
testing
.
T
)
{
pods
,
_
,
_
:=
testData
()
f
,
tf
,
codec
,
ns
:=
cmdtesting
.
NewAPIFactory
()
f
,
tf
,
codec
,
_
:=
cmdtesting
.
NewAPIFactory
()
d
:=
&
testDescriber
{
Output
:
"test output"
}
tf
.
Describer
=
d
tf
.
Client
=
&
fake
.
RESTClient
{
tf
.
Unstructured
Client
=
&
fake
.
RESTClient
{
APIRegistry
:
api
.
Registry
,
NegotiatedSerializer
:
ns
,
NegotiatedSerializer
:
unstructuredSerializer
,
Resp
:
&
http
.
Response
{
StatusCode
:
200
,
Header
:
defaultHeader
(),
Body
:
objBody
(
codec
,
pods
)},
}
...
...
pkg/kubectl/cmd/testing/fake.go
View file @
06c12f67
...
...
@@ -93,6 +93,60 @@ func NewInternalType(kind, apiversion, name string) *InternalType {
return
&
item
}
type
InternalNamespacedType
struct
{
Kind
string
APIVersion
string
Name
string
Namespace
string
}
type
ExternalNamespacedType
struct
{
Kind
string
`json:"kind"`
APIVersion
string
`json:"apiVersion"`
Name
string
`json:"name"`
Namespace
string
`json:"namespace"`
}
type
ExternalNamespacedType2
struct
{
Kind
string
`json:"kind"`
APIVersion
string
`json:"apiVersion"`
Name
string
`json:"name"`
Namespace
string
`json:"namespace"`
}
func
(
obj
*
InternalNamespacedType
)
GetObjectKind
()
schema
.
ObjectKind
{
return
obj
}
func
(
obj
*
InternalNamespacedType
)
SetGroupVersionKind
(
gvk
schema
.
GroupVersionKind
)
{
obj
.
APIVersion
,
obj
.
Kind
=
gvk
.
ToAPIVersionAndKind
()
}
func
(
obj
*
InternalNamespacedType
)
GroupVersionKind
()
schema
.
GroupVersionKind
{
return
schema
.
FromAPIVersionAndKind
(
obj
.
APIVersion
,
obj
.
Kind
)
}
func
(
obj
*
ExternalNamespacedType
)
GetObjectKind
()
schema
.
ObjectKind
{
return
obj
}
func
(
obj
*
ExternalNamespacedType
)
SetGroupVersionKind
(
gvk
schema
.
GroupVersionKind
)
{
obj
.
APIVersion
,
obj
.
Kind
=
gvk
.
ToAPIVersionAndKind
()
}
func
(
obj
*
ExternalNamespacedType
)
GroupVersionKind
()
schema
.
GroupVersionKind
{
return
schema
.
FromAPIVersionAndKind
(
obj
.
APIVersion
,
obj
.
Kind
)
}
func
(
obj
*
ExternalNamespacedType2
)
GetObjectKind
()
schema
.
ObjectKind
{
return
obj
}
func
(
obj
*
ExternalNamespacedType2
)
SetGroupVersionKind
(
gvk
schema
.
GroupVersionKind
)
{
obj
.
APIVersion
,
obj
.
Kind
=
gvk
.
ToAPIVersionAndKind
()
}
func
(
obj
*
ExternalNamespacedType2
)
GroupVersionKind
()
schema
.
GroupVersionKind
{
return
schema
.
FromAPIVersionAndKind
(
obj
.
APIVersion
,
obj
.
Kind
)
}
func
NewInternalNamespacedType
(
kind
,
apiversion
,
name
,
namespace
string
)
*
InternalNamespacedType
{
item
:=
InternalNamespacedType
{
Kind
:
kind
,
APIVersion
:
apiversion
,
Name
:
name
,
Namespace
:
namespace
}
return
&
item
}
var
versionErr
=
errors
.
New
(
"not a version"
)
func
versionErrIfFalse
(
b
bool
)
error
{
...
...
@@ -109,11 +163,17 @@ var ValidVersionGV = schema.GroupVersion{Group: "apitest", Version: ValidVersion
func
newExternalScheme
()
(
*
runtime
.
Scheme
,
meta
.
RESTMapper
,
runtime
.
Codec
)
{
scheme
:=
runtime
.
NewScheme
()
scheme
.
AddKnownTypeWithName
(
InternalGV
.
WithKind
(
"Type"
),
&
InternalType
{})
scheme
.
AddKnownTypeWithName
(
UnlikelyGV
.
WithKind
(
"Type"
),
&
ExternalType
{})
//This tests that kubectl will not confuse the external scheme with the internal scheme, even when they accidentally have versions of the same name.
scheme
.
AddKnownTypeWithName
(
ValidVersionGV
.
WithKind
(
"Type"
),
&
ExternalType2
{})
scheme
.
AddKnownTypeWithName
(
InternalGV
.
WithKind
(
"NamespacedType"
),
&
InternalNamespacedType
{})
scheme
.
AddKnownTypeWithName
(
UnlikelyGV
.
WithKind
(
"NamespacedType"
),
&
ExternalNamespacedType
{})
//This tests that kubectl will not confuse the external scheme with the internal scheme, even when they accidentally have versions of the same name.
scheme
.
AddKnownTypeWithName
(
ValidVersionGV
.
WithKind
(
"NamespacedType"
),
&
ExternalNamespacedType2
{})
codecs
:=
serializer
.
NewCodecFactory
(
scheme
)
codec
:=
codecs
.
LegacyCodec
(
UnlikelyGV
)
mapper
:=
meta
.
NewDefaultRESTMapper
([]
schema
.
GroupVersion
{
UnlikelyGV
,
ValidVersionGV
},
func
(
version
schema
.
GroupVersion
)
(
*
meta
.
VersionInterfaces
,
error
)
{
...
...
@@ -603,6 +663,7 @@ func testDynamicResources() []*discovery.APIGroupResources {
{
Name
:
"componentstatuses"
,
Namespaced
:
false
,
Kind
:
"ComponentStatus"
},
{
Name
:
"nodes"
,
Namespaced
:
false
,
Kind
:
"Node"
},
{
Name
:
"type"
,
Namespaced
:
false
,
Kind
:
"Type"
},
{
Name
:
"namespacedtype"
,
Namespaced
:
true
,
Kind
:
"NamespacedType"
},
},
},
},
...
...
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