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
765f9ec6
Unverified
Commit
765f9ec6
authored
Feb 05, 2018
by
juanvallejo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update -o name format to kind.group/name
parent
76e6da25
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
179 additions
and
62 deletions
+179
-62
test-cmd-util.sh
hack/make-rules/test-cmd-util.sh
+52
-3
resource.yaml
hack/testdata/CRD/resource.yaml
+7
-0
label.go
pkg/kubectl/cmd/label.go
+1
-1
set_env_test.go
pkg/kubectl/cmd/set/set_env_test.go
+6
-6
set_image_test.go
pkg/kubectl/cmd/set/set_image_test.go
+6
-6
set_resources_test.go
pkg/kubectl/cmd/set/set_resources_test.go
+8
-8
set_selector_test.go
pkg/kubectl/cmd/set/set_selector_test.go
+3
-3
set_serviceaccount_test.go
pkg/kubectl/cmd/set/set_serviceaccount_test.go
+3
-3
factory_builder.go
pkg/kubectl/cmd/util/factory_builder.go
+2
-5
printing.go
pkg/kubectl/cmd/util/printing.go
+2
-3
builder.go
pkg/kubectl/resource/builder.go
+21
-4
BUILD
pkg/printers/BUILD
+1
-0
printers_test.go
pkg/printers/internalversion/printers_test.go
+8
-9
name.go
pkg/printers/name.go
+32
-8
printers.go
pkg/printers/printers.go
+1
-3
group_version.go
...c/k8s.io/apimachinery/pkg/runtime/schema/group_version.go
+24
-0
restmapper.go
staging/src/k8s.io/client-go/discovery/restmapper.go
+2
-0
No files found.
hack/make-rules/test-cmd-util.sh
View file @
765f9ec6
...
...
@@ -1460,7 +1460,7 @@ run_kubectl_get_tests() {
kube::test::if_has_string
"
${
output_message
}
"
'valid-pod'
# pod details
output_message
=
$(
kubectl get pods/valid-pod
-o
name
-w
--request-timeout
=
1
"
${
kube_flags
[@]
}
"
)
kube::test::if_has_not_string
"
${
output_message
}
"
'STATUS'
# no headers
kube::test::if_has_string
"
${
output_message
}
"
'pod
s
/valid-pod'
# resource name
kube::test::if_has_string
"
${
output_message
}
"
'pod/valid-pod'
# resource name
output_message
=
$(
kubectl get pods/valid-pod
-o
yaml
-w
--request-timeout
=
1
"
${
kube_flags
[@]
}
"
)
kube::test::if_has_not_string
"
${
output_message
}
"
'STATUS'
# no headers
kube::test::if_has_string
"
${
output_message
}
"
'name: valid-pod'
# yaml
...
...
@@ -1574,6 +1574,33 @@ __EOF__
# Post-Condition: assertion object exist
kube::test::get_object_assert customresourcedefinitions
"{{range.items}}{{
$id_field
}}:{{end}}"
'bars.company.com:foos.company.com:'
# This test ensures that the name printer is able to output a resource
# in the proper "kind.group/resource_name" format, and that the
# resource builder is able to resolve a GVK when a kind.group pair is given.
kubectl
"
${
kube_flags_with_token
[@]
}
"
create
-f
-
<<
__EOF__
{
"kind": "CustomResourceDefinition",
"apiVersion": "apiextensions.k8s.io/v1beta1",
"metadata": {
"name": "resources.mygroup.example.com"
},
"spec": {
"group": "mygroup.example.com",
"version": "v1alpha1",
"scope": "Namespaced",
"names": {
"plural": "resources",
"singular": "resource",
"kind": "Kind",
"listKind": "KindList"
}
}
}
__EOF__
# Post-Condition: assertion crd with non-matching kind and resource exists
kube::test::get_object_assert customresourcedefinitions
"{{range.items}}{{
$id_field
}}:{{end}}"
'bars.company.com:foos.company.com:resources.mygroup.example.com:'
run_non_native_resource_tests
# teardown
...
...
@@ -1621,6 +1648,28 @@ run_non_native_resource_tests() {
# Test that we can list this new CustomResource (bars)
kube::test::get_object_assert bars
"{{range.items}}{{
$id_field
}}:{{end}}"
''
# Test that we can list this new CustomResource (resources)
kube::test::get_object_assert resources
"{{range.items}}{{
$id_field
}}:{{end}}"
''
# Test that we can create a new resource of type Kind
kubectl
"
${
kube_flags
[@]
}
"
create
-f
hack/testdata/CRD/resource.yaml
"
${
kube_flags
[@]
}
"
# Test that -o name returns kind.group/resourcename
output_message
=
$(
kubectl
"
${
kube_flags
[@]
}
"
get resource/myobj
-o
name
)
kube::test::if_has_string
"
${
output_message
}
"
'kind.mygroup.example.com/myobj'
output_message
=
$(
kubectl
"
${
kube_flags
[@]
}
"
get resources/myobj
-o
name
)
kube::test::if_has_string
"
${
output_message
}
"
'kind.mygroup.example.com/myobj'
output_message
=
$(
kubectl
"
${
kube_flags
[@]
}
"
get kind.mygroup.example.com/myobj
-o
name
)
kube::test::if_has_string
"
${
output_message
}
"
'kind.mygroup.example.com/myobj'
# Delete the resource with cascade.
kubectl
"
${
kube_flags
[@]
}
"
delete resources myobj
--cascade
=
true
# Make sure it's gone
kube::test::get_object_assert resources
"{{range.items}}{{
$id_field
}}:{{end}}"
''
# Test that we can create a new resource of type Foo
kubectl
"
${
kube_flags
[@]
}
"
create
-f
hack/testdata/CRD/foo.yaml
"
${
kube_flags
[@]
}
"
...
...
@@ -1649,7 +1698,7 @@ run_non_native_resource_tests() {
kubectl
"
${
kube_flags
[@]
}
"
get foos
-o
"go-template={{range .items}}{{.someField}}{{end}}"
--allow-missing-template-keys
=
false
kubectl
"
${
kube_flags
[@]
}
"
get foos/test
-o
"go-template={{.someField}}"
--allow-missing-template-keys
=
false
output_message
=
$(
kubectl
"
${
kube_flags
[@]
}
"
get foos/test
-o
name
)
kube::test::if_has_string
"
${
output_message
}
"
'foo
s
/test'
kube::test::if_has_string
"
${
output_message
}
"
'foo
.company.com
/test'
# Test patching
kube::log::status
"Testing CustomResource patching"
...
...
@@ -1732,7 +1781,7 @@ run_non_native_resource_tests() {
# Stop the watcher and the patch loop.
kill
-9
${
watch_pid
}
kill
-9
${
patch_pid
}
kube::test::if_has_string
"
${
watch_output
}
"
'bar
s
/test'
kube::test::if_has_string
"
${
watch_output
}
"
'bar
.company.com
/test'
# Delete the resource without cascade.
kubectl
"
${
kube_flags
[@]
}
"
delete bars
test
--cascade
=
false
...
...
hack/testdata/CRD/resource.yaml
0 → 100644
View file @
765f9ec6
apiVersion
:
mygroup.example.com/v1alpha1
kind
:
Kind
metadata
:
name
:
myobj
spec
:
key
:
value
\ No newline at end of file
pkg/kubectl/cmd/label.go
View file @
765f9ec6
...
...
@@ -287,7 +287,7 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error {
return
nil
}
if
o
.
outputFormat
!=
""
{
if
len
(
o
.
outputFormat
)
>
0
{
return
f
.
PrintObject
(
cmd
,
o
.
local
,
r
.
Mapper
()
.
RESTMapper
,
outputObj
,
o
.
out
)
}
f
.
PrintSuccess
(
false
,
o
.
out
,
info
.
Mapping
.
Resource
,
info
.
Name
,
o
.
dryrun
,
dataChangeMsg
)
...
...
pkg/kubectl/cmd/set/set_env_test.go
View file @
765f9ec6
...
...
@@ -64,8 +64,8 @@ func TestSetEnvLocal(t *testing.T) {
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"output"
,
"name"
)
cmd
.
Flags
()
.
Set
(
"local"
,
"true"
)
mapper
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
,
Mapper
:
mapper
}
_
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
}
opts
:=
EnvOptions
{
FilenameOptions
:
resource
.
FilenameOptions
{
Filenames
:
[]
string
{
"../../../../examples/storage/cassandra/cassandra-controller.yaml"
}},
...
...
@@ -78,7 +78,7 @@ func TestSetEnvLocal(t *testing.T) {
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
if
!
strings
.
Contains
(
buf
.
String
(),
"replicationcontroller
s
/cassandra"
)
{
if
!
strings
.
Contains
(
buf
.
String
(),
"replicationcontroller/cassandra"
)
{
t
.
Errorf
(
"did not set env: %s"
,
buf
.
String
())
}
}
...
...
@@ -101,8 +101,8 @@ func TestSetMultiResourcesEnvLocal(t *testing.T) {
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"output"
,
"name"
)
cmd
.
Flags
()
.
Set
(
"local"
,
"true"
)
mapper
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
,
Mapper
:
mapper
}
_
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
}
opts
:=
EnvOptions
{
FilenameOptions
:
resource
.
FilenameOptions
{
Filenames
:
[]
string
{
"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"
}},
...
...
@@ -116,7 +116,7 @@ func TestSetMultiResourcesEnvLocal(t *testing.T) {
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
expectedOut
:=
"replicationcontroller
s/first-rc
\n
replicationcontrollers
/second-rc
\n
"
expectedOut
:=
"replicationcontroller
/first-rc
\n
replicationcontroller
/second-rc
\n
"
if
buf
.
String
()
!=
expectedOut
{
t
.
Errorf
(
"expected out:
\n
%s
\n
but got:
\n
%s"
,
expectedOut
,
buf
.
String
())
}
...
...
pkg/kubectl/cmd/set/set_image_test.go
View file @
765f9ec6
...
...
@@ -63,8 +63,8 @@ func TestImageLocal(t *testing.T) {
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"output"
,
"name"
)
cmd
.
Flags
()
.
Set
(
"local"
,
"true"
)
mapper
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
,
Mapper
:
mapper
}
_
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
}
opts
:=
ImageOptions
{
FilenameOptions
:
resource
.
FilenameOptions
{
Filenames
:
[]
string
{
"../../../../examples/storage/cassandra/cassandra-controller.yaml"
}},
...
...
@@ -80,7 +80,7 @@ func TestImageLocal(t *testing.T) {
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
if
!
strings
.
Contains
(
buf
.
String
(),
"replicationcontroller
s
/cassandra"
)
{
if
!
strings
.
Contains
(
buf
.
String
(),
"replicationcontroller/cassandra"
)
{
t
.
Errorf
(
"did not set image: %s"
,
buf
.
String
())
}
}
...
...
@@ -166,8 +166,8 @@ func TestSetMultiResourcesImageLocal(t *testing.T) {
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"output"
,
"name"
)
cmd
.
Flags
()
.
Set
(
"local"
,
"true"
)
mapper
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
,
Mapper
:
mapper
}
_
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
}
opts
:=
ImageOptions
{
FilenameOptions
:
resource
.
FilenameOptions
{
Filenames
:
[]
string
{
"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"
}},
...
...
@@ -183,7 +183,7 @@ func TestSetMultiResourcesImageLocal(t *testing.T) {
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
expectedOut
:=
"replicationcontroller
s/first-rc
\n
replicationcontrollers
/second-rc
\n
"
expectedOut
:=
"replicationcontroller
/first-rc
\n
replicationcontroller
/second-rc
\n
"
if
buf
.
String
()
!=
expectedOut
{
t
.
Errorf
(
"expected out:
\n
%s
\n
but got:
\n
%s"
,
expectedOut
,
buf
.
String
())
}
...
...
pkg/kubectl/cmd/set/set_resources_test.go
View file @
765f9ec6
...
...
@@ -63,8 +63,8 @@ func TestResourcesLocal(t *testing.T) {
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"output"
,
"name"
)
cmd
.
Flags
()
.
Set
(
"local"
,
"true"
)
mapper
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
,
Mapper
:
mapper
}
_
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
}
opts
:=
ResourcesOptions
{
FilenameOptions
:
resource
.
FilenameOptions
{
Filenames
:
[]
string
{
"../../../../examples/storage/cassandra/cassandra-controller.yaml"
}},
...
...
@@ -84,7 +84,7 @@ func TestResourcesLocal(t *testing.T) {
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
if
!
strings
.
Contains
(
buf
.
String
(),
"replicationcontroller
s
/cassandra"
)
{
if
!
strings
.
Contains
(
buf
.
String
(),
"replicationcontroller/cassandra"
)
{
t
.
Errorf
(
"did not set resources: %s"
,
buf
.
String
())
}
}
...
...
@@ -107,8 +107,8 @@ func TestSetMultiResourcesLimitsLocal(t *testing.T) {
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"output"
,
"name"
)
cmd
.
Flags
()
.
Set
(
"local"
,
"true"
)
mapper
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
,
Mapper
:
mapper
}
_
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
}
opts
:=
ResourcesOptions
{
FilenameOptions
:
resource
.
FilenameOptions
{
Filenames
:
[]
string
{
"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"
}},
...
...
@@ -128,7 +128,7 @@ func TestSetMultiResourcesLimitsLocal(t *testing.T) {
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
expectedOut
:=
"replicationcontroller
s/first-rc
\n
replicationcontrollers
/second-rc
\n
"
expectedOut
:=
"replicationcontroller
/first-rc
\n
replicationcontroller
/second-rc
\n
"
if
buf
.
String
()
!=
expectedOut
{
t
.
Errorf
(
"expected out:
\n
%s
\n
but got:
\n
%s"
,
expectedOut
,
buf
.
String
())
}
...
...
@@ -448,8 +448,8 @@ func TestSetResourcesRemote(t *testing.T) {
testapi
.
Default
=
testapi
.
Groups
[
input
.
testAPIGroup
]
f
,
tf
,
_
,
ns
:=
cmdtesting
.
NewAPIFactory
()
codec
:=
scheme
.
Codecs
.
CodecForVersions
(
scheme
.
Codecs
.
LegacyCodec
(
groupVersion
),
scheme
.
Codecs
.
UniversalDecoder
(
groupVersion
),
groupVersion
,
groupVersion
)
mapper
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
testapi
.
Default
.
Codec
()},
Typer
:
typer
,
Mapper
:
mapper
}
_
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
testapi
.
Default
.
Codec
()},
Typer
:
typer
}
tf
.
Namespace
=
"test"
tf
.
CategoryExpander
=
categories
.
LegacyCategoryExpander
tf
.
Client
=
&
fake
.
RESTClient
{
...
...
pkg/kubectl/cmd/set/set_selector_test.go
View file @
765f9ec6
...
...
@@ -335,11 +335,11 @@ func TestSelectorTest(t *testing.T) {
cmd
.
Flags
()
.
Set
(
"local"
,
"true"
)
cmd
.
Flags
()
.
Set
(
"filename"
,
"../../../../examples/storage/cassandra/cassandra-service.yaml"
)
mapper
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
,
Mapper
:
mapper
}
_
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
}
cmd
.
Run
(
cmd
,
[]
string
{
"environment=qa"
})
if
!
strings
.
Contains
(
buf
.
String
(),
"service
s
/cassandra"
)
{
if
!
strings
.
Contains
(
buf
.
String
(),
"service/cassandra"
)
{
t
.
Errorf
(
"did not set selector: %s"
,
buf
.
String
())
}
}
pkg/kubectl/cmd/set/set_serviceaccount_test.go
View file @
765f9ec6
...
...
@@ -116,8 +116,8 @@ func TestSetServiceAccountMultiLocal(t *testing.T) {
cmd
.
SetOutput
(
buf
)
cmd
.
Flags
()
.
Set
(
"output"
,
"name"
)
cmd
.
Flags
()
.
Set
(
"local"
,
"true"
)
mapper
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
,
Mapper
:
mapper
}
_
,
typer
:=
f
.
Object
()
tf
.
Printer
=
&
printers
.
NamePrinter
{
Decoders
:
[]
runtime
.
Decoder
{
codec
},
Typer
:
typer
}
opts
:=
serviceAccountConfig
{
fileNameOptions
:
resource
.
FilenameOptions
{
Filenames
:
[]
string
{
"../../../../test/fixtures/pkg/kubectl/cmd/set/multi-resource-yaml.yaml"
}},
out
:
buf
,
...
...
@@ -130,7 +130,7 @@ func TestSetServiceAccountMultiLocal(t *testing.T) {
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
expectedOut
:=
"replicationcontroller
s/first-rc
\n
replicationcontrollers
/second-rc
\n
"
expectedOut
:=
"replicationcontroller
/first-rc
\n
replicationcontroller
/second-rc
\n
"
if
buf
.
String
()
!=
expectedOut
{
t
.
Errorf
(
"expected out:
\n
%s
\n
but got:
\n
%s"
,
expectedOut
,
buf
.
String
())
}
...
...
pkg/kubectl/cmd/util/factory_builder.go
View file @
765f9ec6
...
...
@@ -48,15 +48,12 @@ func NewBuilderFactory(clientAccessFactory ClientAccessFactory, objectMappingFac
}
func
(
f
*
ring2Factory
)
PrinterForOptions
(
options
*
printers
.
PrintOptions
)
(
printers
.
ResourcePrinter
,
error
)
{
var
mapper
meta
.
RESTMapper
var
typer
runtime
.
ObjectTyper
mapper
,
typer
=
f
.
objectMappingFactory
.
Object
()
_
,
typer
:=
f
.
objectMappingFactory
.
Object
()
// TODO: used by the custom column implementation and the name implementation, break this dependency
decoders
:=
[]
runtime
.
Decoder
{
f
.
clientAccessFactory
.
Decoder
(
true
),
unstructured
.
UnstructuredJSONScheme
}
encoder
:=
f
.
clientAccessFactory
.
JSONEncoder
()
return
printerForOptions
(
mapper
,
typer
,
encoder
,
decoders
,
options
)
return
printerForOptions
(
typer
,
encoder
,
decoders
,
options
)
}
func
(
f
*
ring2Factory
)
PrinterForMapping
(
options
*
printers
.
PrintOptions
,
mapping
*
meta
.
RESTMapping
)
(
printers
.
ResourcePrinter
,
error
)
{
...
...
pkg/kubectl/cmd/util/printing.go
View file @
765f9ec6
...
...
@@ -20,7 +20,6 @@ import (
"fmt"
"strings"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
...
...
@@ -84,8 +83,8 @@ func ValidateOutputArgs(cmd *cobra.Command) error {
// printerForOptions returns the printer for the outputOptions (if given) or
// returns the default printer for the command. Requires that printer flags have
// been added to cmd (see AddPrinterFlags).
func
printerForOptions
(
mapper
meta
.
RESTMapper
,
typer
runtime
.
ObjectTyper
,
encoder
runtime
.
Encoder
,
decoders
[]
runtime
.
Decoder
,
options
*
printers
.
PrintOptions
)
(
printers
.
ResourcePrinter
,
error
)
{
printer
,
err
:=
printers
.
GetStandardPrinter
(
mapper
,
typer
,
encoder
,
decoders
,
*
options
)
func
printerForOptions
(
typer
runtime
.
ObjectTyper
,
encoder
runtime
.
Encoder
,
decoders
[]
runtime
.
Decoder
,
options
*
printers
.
PrintOptions
)
(
printers
.
ResourcePrinter
,
error
)
{
printer
,
err
:=
printers
.
GetStandardPrinter
(
typer
,
encoder
,
decoders
,
*
options
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
pkg/kubectl/resource/builder.go
View file @
765f9ec6
...
...
@@ -598,10 +598,27 @@ func (b *Builder) SingleResourceType() *Builder {
return
b
}
// mappingFor returns the RESTMapping for the Kind referenced by the resource.
// prefers a fully specified GroupVersionResource match. If we don't have one match on GroupResource
func
(
b
*
Builder
)
mappingFor
(
resourceArg
string
)
(
*
meta
.
RESTMapping
,
error
)
{
fullySpecifiedGVR
,
groupResource
:=
schema
.
ParseResourceArg
(
resourceArg
)
// mappingFor returns the RESTMapping for the Kind given, or the Kind referenced by the resource.
// prefers a fully specified GroupVersionKind match. If we don't have one, match on a fully specified
// GroupVersionResource, or fallback to a match on GroupResource.
func
(
b
*
Builder
)
mappingFor
(
resourceOrKindArg
string
)
(
*
meta
.
RESTMapping
,
error
)
{
fullySpecifiedGVK
,
groupKind
:=
schema
.
ParseKindArg
(
resourceOrKindArg
)
if
fullySpecifiedGVK
==
nil
{
gvk
:=
groupKind
.
WithVersion
(
""
)
fullySpecifiedGVK
=
&
gvk
}
if
!
fullySpecifiedGVK
.
Empty
()
{
if
mapping
,
err
:=
b
.
mapper
.
RESTMapping
(
fullySpecifiedGVK
.
GroupKind
(),
fullySpecifiedGVK
.
Version
);
err
==
nil
{
return
mapping
,
nil
}
else
{
if
mapping
,
err
:=
b
.
mapper
.
RESTMapping
(
groupKind
,
""
);
err
==
nil
{
return
mapping
,
nil
}
}
}
fullySpecifiedGVR
,
groupResource
:=
schema
.
ParseResourceArg
(
resourceOrKindArg
)
gvk
:=
schema
.
GroupVersionKind
{}
if
fullySpecifiedGVR
!=
nil
{
gvk
,
_
=
b
.
mapper
.
KindFor
(
*
fullySpecifiedGVR
)
...
...
pkg/printers/BUILD
View file @
765f9ec6
...
...
@@ -26,6 +26,7 @@ go_library(
"//vendor/github.com/ghodss/yaml:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1/unstructured:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
...
...
pkg/printers/internalversion/printers_test.go
View file @
765f9ec6
...
...
@@ -108,7 +108,7 @@ func TestPrintDefault(t *testing.T) {
}
for
_
,
test
:=
range
printerTests
{
printer
,
err
:=
printers
.
GetStandardPrinter
(
nil
,
nil
,
legacyscheme
.
Codecs
.
LegacyCodec
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
printers
.
PrintOptions
{
AllowMissingKeys
:
false
})
printer
,
err
:=
printers
.
GetStandardPrinter
(
nil
,
legacyscheme
.
Codecs
.
LegacyCodec
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
printers
.
PrintOptions
{
AllowMissingKeys
:
false
})
if
err
!=
nil
{
t
.
Errorf
(
"in %s, unexpected error: %#v"
,
test
.
Name
,
err
)
}
...
...
@@ -278,12 +278,12 @@ func TestPrinter(t *testing.T) {
{
"test jsonpath"
,
&
printers
.
PrintOptions
{
OutputFormatType
:
"jsonpath"
,
OutputFormatArgument
:
"{.metadata.name}"
,
AllowMissingKeys
:
true
},
podTest
,
[]
schema
.
GroupVersion
{
v1
.
SchemeGroupVersion
},
"foo"
},
{
"test jsonpath list"
,
&
printers
.
PrintOptions
{
OutputFormatType
:
"jsonpath"
,
OutputFormatArgument
:
"{.items[*].metadata.name}"
,
AllowMissingKeys
:
true
},
podListTest
,
[]
schema
.
GroupVersion
{
v1
.
SchemeGroupVersion
},
"foo bar"
},
{
"test jsonpath empty list"
,
&
printers
.
PrintOptions
{
OutputFormatType
:
"jsonpath"
,
OutputFormatArgument
:
"{.items[*].metadata.name}"
,
AllowMissingKeys
:
true
},
emptyListTest
,
[]
schema
.
GroupVersion
{
v1
.
SchemeGroupVersion
},
""
},
{
"test name"
,
&
printers
.
PrintOptions
{
OutputFormatType
:
"name"
,
AllowMissingKeys
:
true
},
podTest
,
[]
schema
.
GroupVersion
{
v1
.
SchemeGroupVersion
},
"pod
s
/foo
\n
"
},
{
"test name"
,
&
printers
.
PrintOptions
{
OutputFormatType
:
"name"
,
AllowMissingKeys
:
true
},
podTest
,
[]
schema
.
GroupVersion
{
v1
.
SchemeGroupVersion
},
"pod/foo
\n
"
},
{
"emits versioned objects"
,
&
printers
.
PrintOptions
{
OutputFormatType
:
"template"
,
OutputFormatArgument
:
"{{.kind}}"
,
AllowMissingKeys
:
true
},
testapi
,
[]
schema
.
GroupVersion
{
v1
.
SchemeGroupVersion
},
"Pod"
},
}
for
_
,
test
:=
range
printerTests
{
buf
:=
bytes
.
NewBuffer
([]
byte
{})
printer
,
err
:=
printers
.
GetStandardPrinter
(
legacyscheme
.
Registry
.
RESTMapper
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
legacyscheme
.
Scheme
,
legacyscheme
.
Codecs
.
LegacyCodec
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
*
test
.
PrintOpts
)
printer
,
err
:=
printers
.
GetStandardPrinter
(
legacyscheme
.
Scheme
,
legacyscheme
.
Codecs
.
LegacyCodec
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
*
test
.
PrintOpts
)
if
err
!=
nil
{
t
.
Errorf
(
"in %s, unexpected error: %#v"
,
test
.
Name
,
err
)
}
...
...
@@ -313,7 +313,7 @@ func TestBadPrinter(t *testing.T) {
{
"unknown format"
,
&
printers
.
PrintOptions
{
OutputFormatType
:
"anUnknownFormat"
,
OutputFormatArgument
:
""
,
AllowMissingKeys
:
false
},
fmt
.
Errorf
(
"output format
\"
anUnknownFormat
\"
not recognized"
)},
}
for
_
,
test
:=
range
badPrinterTests
{
_
,
err
:=
printers
.
GetStandardPrinter
(
legacyscheme
.
Registry
.
RESTMapper
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
legacyscheme
.
Scheme
,
legacyscheme
.
Codecs
.
LegacyCodec
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
*
test
.
PrintOpts
)
_
,
err
:=
printers
.
GetStandardPrinter
(
legacyscheme
.
Scheme
,
legacyscheme
.
Codecs
.
LegacyCodec
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
*
test
.
PrintOpts
)
if
err
==
nil
||
err
.
Error
()
!=
test
.
Error
.
Error
()
{
t
.
Errorf
(
"in %s, expect %s, got %s"
,
test
.
Name
,
test
.
Error
,
err
)
}
...
...
@@ -489,7 +489,7 @@ func TestNamePrinter(t *testing.T) {
Name
:
"foo"
,
},
},
"pod
s
/foo
\n
"
},
"pod/foo
\n
"
},
"List"
:
{
&
v1
.
List
{
TypeMeta
:
metav1
.
TypeMeta
{
...
...
@@ -504,10 +504,10 @@ func TestNamePrinter(t *testing.T) {
},
},
},
"pod
s/foo
\n
pods
/bar
\n
"
},
"pod
/foo
\n
pod
/bar
\n
"
},
}
printOpts
:=
&
printers
.
PrintOptions
{
OutputFormatType
:
"name"
,
AllowMissingKeys
:
false
}
printer
,
_
:=
printers
.
GetStandardPrinter
(
legacyscheme
.
Registry
.
RESTMapper
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
legacyscheme
.
Scheme
,
legacyscheme
.
Codecs
.
LegacyCodec
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
*
printOpts
)
printer
,
_
:=
printers
.
GetStandardPrinter
(
legacyscheme
.
Scheme
,
legacyscheme
.
Codecs
.
LegacyCodec
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
*
printOpts
)
for
name
,
item
:=
range
tests
{
buff
:=
&
bytes
.
Buffer
{}
err
:=
printer
.
PrintObj
(
item
.
obj
,
buff
)
...
...
@@ -682,7 +682,6 @@ func TestPrinters(t *testing.T) {
"name"
:
&
printers
.
NamePrinter
{
Typer
:
legacyscheme
.
Scheme
,
Decoders
:
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
Mapper
:
legacyscheme
.
Registry
.
RESTMapper
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
},
}
AddHandlers
((
allPrinters
[
"humanReadable"
])
.
(
*
printers
.
HumanReadablePrinter
))
...
...
@@ -2819,7 +2818,7 @@ func TestAllowMissingKeys(t *testing.T) {
}
for
_
,
test
:=
range
tests
{
buf
:=
bytes
.
NewBuffer
([]
byte
{})
printer
,
err
:=
printers
.
GetStandardPrinter
(
legacyscheme
.
Registry
.
RESTMapper
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
legacyscheme
.
Scheme
,
legacyscheme
.
Codecs
.
LegacyCodec
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
*
test
.
PrintOpts
)
printer
,
err
:=
printers
.
GetStandardPrinter
(
legacyscheme
.
Scheme
,
legacyscheme
.
Codecs
.
LegacyCodec
(
legacyscheme
.
Registry
.
EnabledVersions
()
...
),
[]
runtime
.
Decoder
{
legacyscheme
.
Codecs
.
UniversalDecoder
(),
unstructured
.
UnstructuredJSONScheme
},
*
test
.
PrintOpts
)
if
err
!=
nil
{
t
.
Errorf
(
"in %s, unexpected error: %#v"
,
test
.
Name
,
err
)
}
...
...
pkg/printers/name.go
View file @
765f9ec6
...
...
@@ -19,8 +19,10 @@ package printers
import
(
"fmt"
"io"
"strings"
"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"
)
...
...
@@ -29,7 +31,6 @@ import (
type
NamePrinter
struct
{
Decoders
[]
runtime
.
Decoder
Typer
runtime
.
ObjectTyper
Mapper
meta
.
RESTMapper
}
func
(
p
*
NamePrinter
)
AfterPrint
(
w
io
.
Writer
,
res
string
)
error
{
...
...
@@ -64,18 +65,27 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
groupVersionKind
:=
obj
.
GetObjectKind
()
.
GroupVersionKind
()
if
len
(
groupVersionKind
.
Kind
)
>
0
{
if
mappings
,
err
:=
p
.
Mapper
.
RESTMappings
(
groupVersionKind
.
GroupKind
(),
groupVersionKind
.
Version
);
err
==
nil
&&
len
(
mappings
)
>
0
{
fmt
.
Fprintf
(
w
,
"%s/%s
\n
"
,
mappings
[
0
]
.
Resource
,
name
)
return
nil
}
kind
:=
groupVersionKind
.
Kind
group
:=
groupVersionKind
.
Group
return
printObj
(
w
,
name
,
group
,
kind
)
}
if
gvks
,
_
,
err
:=
p
.
Typer
.
ObjectKinds
(
obj
);
err
==
nil
{
for
_
,
gvk
:=
range
gvks
{
if
mappings
,
err
:=
p
.
Mapper
.
RESTMappings
(
gvk
.
GroupKind
(),
gvk
.
Version
);
err
==
nil
&&
len
(
mappings
)
>
0
{
fmt
.
Fprintf
(
w
,
"%s/%s
\n
"
,
mappings
[
0
]
.
Resource
,
name
)
return
nil
if
len
(
gvk
.
Kind
)
==
0
{
continue
}
return
printObj
(
w
,
name
,
gvk
.
Group
,
gvk
.
Kind
)
}
}
if
uns
,
ok
:=
obj
.
(
*
unstructured
.
Unstructured
);
ok
{
group
:=
uns
.
GroupVersionKind
()
.
Group
kind
:=
uns
.
GroupVersionKind
()
.
Kind
if
len
(
kind
)
>
0
{
return
printObj
(
w
,
name
,
group
,
kind
)
}
}
...
...
@@ -83,6 +93,20 @@ func (p *NamePrinter) PrintObj(obj runtime.Object, w io.Writer) error {
return
nil
}
func
printObj
(
w
io
.
Writer
,
name
,
group
,
kind
string
)
error
{
if
len
(
kind
)
==
0
{
return
fmt
.
Errorf
(
"missing kind for resource with name %v"
,
name
)
}
if
len
(
group
)
==
0
{
fmt
.
Fprintf
(
w
,
"%s/%s
\n
"
,
strings
.
ToLower
(
kind
),
name
)
return
nil
}
fmt
.
Fprintf
(
w
,
"%s.%s/%s
\n
"
,
strings
.
ToLower
(
kind
),
group
,
name
)
return
nil
}
// TODO: implement HandledResources()
func
(
p
*
NamePrinter
)
HandledResources
()
[]
string
{
return
[]
string
{}
...
...
pkg/printers/printers.go
View file @
765f9ec6
...
...
@@ -21,7 +21,6 @@ import (
"io/ioutil"
"os"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
)
...
...
@@ -29,7 +28,7 @@ import (
// a printer or an error. The printer is agnostic to schema versions, so you must
// send arguments to PrintObj in the version you wish them to be shown using a
// VersionedPrinter (typically when generic is true).
func
GetStandardPrinter
(
mapper
meta
.
RESTMapper
,
typer
runtime
.
ObjectTyper
,
encoder
runtime
.
Encoder
,
decoders
[]
runtime
.
Decoder
,
options
PrintOptions
)
(
ResourcePrinter
,
error
)
{
func
GetStandardPrinter
(
typer
runtime
.
ObjectTyper
,
encoder
runtime
.
Encoder
,
decoders
[]
runtime
.
Decoder
,
options
PrintOptions
)
(
ResourcePrinter
,
error
)
{
format
,
formatArgument
,
allowMissingTemplateKeys
:=
options
.
OutputFormatType
,
options
.
OutputFormatArgument
,
options
.
AllowMissingKeys
var
printer
ResourcePrinter
...
...
@@ -45,7 +44,6 @@ func GetStandardPrinter(mapper meta.RESTMapper, typer runtime.ObjectTyper, encod
printer
=
&
NamePrinter
{
Typer
:
typer
,
Decoders
:
decoders
,
Mapper
:
mapper
,
}
case
"template"
,
"go-template"
:
...
...
staging/src/k8s.io/apimachinery/pkg/runtime/schema/group_version.go
View file @
765f9ec6
...
...
@@ -36,6 +36,21 @@ func ParseResourceArg(arg string) (*GroupVersionResource, GroupResource) {
return
gvr
,
ParseGroupResource
(
arg
)
}
// ParseKindArg takes the common style of string which may be either `Kind.group.com` or `Kind.version.group.com`
// and parses it out into both possibilities. This code takes no responsibility for knowing which representation was intended
// but with a knowledge of all GroupKinds, calling code can take a very good guess. If there are only two segments, then
// `*GroupVersionResource` is nil.
// `Kind.group.com` -> `group=com, version=group, kind=Kind` and `group=group.com, kind=Kind`
func
ParseKindArg
(
arg
string
)
(
*
GroupVersionKind
,
GroupKind
)
{
var
gvk
*
GroupVersionKind
if
strings
.
Count
(
arg
,
"."
)
>=
2
{
s
:=
strings
.
SplitN
(
arg
,
"."
,
3
)
gvk
=
&
GroupVersionKind
{
Group
:
s
[
2
],
Version
:
s
[
1
],
Kind
:
s
[
0
]}
}
return
gvk
,
ParseGroupKind
(
arg
)
}
// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
// concepts during lookup stages without having partially valid types
type
GroupResource
struct
{
...
...
@@ -58,6 +73,15 @@ func (gr *GroupResource) String() string {
return
gr
.
Resource
+
"."
+
gr
.
Group
}
func
ParseGroupKind
(
gk
string
)
GroupKind
{
i
:=
strings
.
Index
(
gk
,
"."
)
if
i
==
-
1
{
return
GroupKind
{
Kind
:
gk
}
}
return
GroupKind
{
Group
:
gk
[
i
+
1
:
],
Kind
:
gk
[
:
i
]}
}
// ParseGroupResource turns "resource.group" string into a GroupResource struct. Empty strings are allowed
// for each field.
func
ParseGroupResource
(
gr
string
)
GroupResource
{
...
...
staging/src/k8s.io/client-go/discovery/restmapper.go
View file @
765f9ec6
...
...
@@ -18,6 +18,7 @@ package discovery
import
(
"fmt"
"strings"
"sync"
"k8s.io/apimachinery/pkg/api/meta"
...
...
@@ -108,6 +109,7 @@ func NewRESTMapper(groupResources []*APIGroupResources, versionInterfaces meta.V
plural
:=
gv
.
WithResource
(
resource
.
Name
)
singular
:=
gv
.
WithResource
(
resource
.
SingularName
)
versionMapper
.
AddSpecific
(
gv
.
WithKind
(
resource
.
Kind
),
plural
,
singular
,
scope
)
versionMapper
.
AddSpecific
(
gv
.
WithKind
(
strings
.
ToLower
(
resource
.
Kind
)),
plural
,
singular
,
scope
)
// TODO this is producing unsafe guesses that don't actually work, but it matches previous behavior
versionMapper
.
Add
(
gv
.
WithKind
(
resource
.
Kind
+
"List"
),
scope
)
}
...
...
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