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
5dfc904c
Commit
5dfc904c
authored
Aug 25, 2015
by
Yu-Ju Hong
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #10979 from kargakis/resource-builder-name-method
Support default types in the resource builder
parents
49883a04
f3c63ba1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
77 additions
and
9 deletions
+77
-9
builder.go
pkg/kubectl/resource/builder.go
+44
-8
builder_test.go
pkg/kubectl/resource/builder_test.go
+33
-1
No files found.
pkg/kubectl/resource/builder.go
View file @
5dfc904c
...
@@ -184,6 +184,28 @@ func (b *Builder) ResourceTypes(types ...string) *Builder {
...
@@ -184,6 +184,28 @@ func (b *Builder) ResourceTypes(types ...string) *Builder {
return
b
return
b
}
}
// ResourceNames accepts a default type and one or more names, and creates tuples of
// resources
func
(
b
*
Builder
)
ResourceNames
(
resource
string
,
names
...
string
)
*
Builder
{
for
_
,
name
:=
range
names
{
// See if this input string is of type/name format
tuple
,
ok
,
err
:=
splitResourceTypeName
(
name
)
if
err
!=
nil
{
b
.
errs
=
append
(
b
.
errs
,
err
)
return
b
}
if
ok
{
b
.
resourceTuples
=
append
(
b
.
resourceTuples
,
tuple
)
continue
}
// Use the given default type to create a resource tuple
b
.
resourceTuples
=
append
(
b
.
resourceTuples
,
resourceTuple
{
Resource
:
resource
,
Name
:
name
})
}
return
b
}
// SelectorParam defines a selector that should be applied to the object types to load.
// SelectorParam defines a selector that should be applied to the object types to load.
// This will not affect files loaded from disk or URL. If the parameter is empty it is
// This will not affect files loaded from disk or URL. If the parameter is empty it is
// a no-op - to select all resources invoke `b.Selector(labels.Everything)`.
// a no-op - to select all resources invoke `b.Selector(labels.Everything)`.
...
@@ -279,17 +301,14 @@ func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string
...
@@ -279,17 +301,14 @@ func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string
return
b
return
b
}
}
for
_
,
s
:=
range
args
{
for
_
,
s
:=
range
args
{
seg
:=
strings
.
Split
(
s
,
"/"
)
tuple
,
ok
,
err
:=
splitResourceTypeName
(
s
)
if
len
(
seg
)
!=
2
{
if
err
!=
nil
{
b
.
errs
=
append
(
b
.
errs
,
fmt
.
Errorf
(
"arguments in resource/name form may not have more than one slash"
)
)
b
.
errs
=
append
(
b
.
errs
,
err
)
return
b
return
b
}
}
resource
,
name
:=
seg
[
0
],
seg
[
1
]
if
ok
{
if
len
(
resource
)
==
0
||
len
(
name
)
==
0
||
len
(
SplitResourceArgument
(
resource
))
!=
1
{
b
.
resourceTuples
=
append
(
b
.
resourceTuples
,
tuple
)
b
.
errs
=
append
(
b
.
errs
,
fmt
.
Errorf
(
"arguments in resource/name form must have a single resource and name"
))
return
b
}
}
b
.
resourceTuples
=
append
(
b
.
resourceTuples
,
resourceTuple
{
Resource
:
resource
,
Name
:
name
})
}
}
return
b
return
b
}
}
...
@@ -346,6 +365,23 @@ func hasCombinedTypeArgs(args []string) (bool, error) {
...
@@ -346,6 +365,23 @@ func hasCombinedTypeArgs(args []string) (bool, error) {
}
}
}
}
// splitResourceTypeName handles type/name resource formats and returns a resource tuple
// (empty or not), whether it successfully found one, and an error
func
splitResourceTypeName
(
s
string
)
(
resourceTuple
,
bool
,
error
)
{
if
!
strings
.
Contains
(
s
,
"/"
)
{
return
resourceTuple
{},
false
,
nil
}
seg
:=
strings
.
Split
(
s
,
"/"
)
if
len
(
seg
)
!=
2
{
return
resourceTuple
{},
false
,
fmt
.
Errorf
(
"arguments in resource/name form may not have more than one slash"
)
}
resource
,
name
:=
seg
[
0
],
seg
[
1
]
if
len
(
resource
)
==
0
||
len
(
name
)
==
0
||
len
(
SplitResourceArgument
(
resource
))
!=
1
{
return
resourceTuple
{},
false
,
fmt
.
Errorf
(
"arguments in resource/name form must have a single resource and name"
)
}
return
resourceTuple
{
Resource
:
resource
,
Name
:
name
},
true
,
nil
}
// Flatten will convert any objects with a field named "Items" that is an array of runtime.Object
// Flatten will convert any objects with a field named "Items" that is an array of runtime.Object
// compatible types into individual entries and give them their own items. The original object
// compatible types into individual entries and give them their own items. The original object
// is not passed to any visitors.
// is not passed to any visitors.
...
...
pkg/kubectl/resource/builder_test.go
View file @
5dfc904c
...
@@ -114,6 +114,10 @@ func testData() (*api.PodList, *api.ServiceList) {
...
@@ -114,6 +114,10 @@ func testData() (*api.PodList, *api.ServiceList) {
Items
:
[]
api
.
Service
{
Items
:
[]
api
.
Service
{
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"baz"
,
Namespace
:
"test"
,
ResourceVersion
:
"12"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"baz"
,
Namespace
:
"test"
,
ResourceVersion
:
"12"
},
Spec
:
api
.
ServiceSpec
{
Type
:
"ClusterIP"
,
SessionAffinity
:
"None"
,
},
},
},
},
},
}
}
...
@@ -374,7 +378,7 @@ func TestResourceByName(t *testing.T) {
...
@@ -374,7 +378,7 @@ func TestResourceByName(t *testing.T) {
t
.
Fatalf
(
"unexpected response: %v %t %#v"
,
err
,
singular
,
test
.
Infos
)
t
.
Fatalf
(
"unexpected response: %v %t %#v"
,
err
,
singular
,
test
.
Infos
)
}
}
if
!
reflect
.
DeepEqual
(
&
pods
.
Items
[
0
],
test
.
Objects
()[
0
])
{
if
!
reflect
.
DeepEqual
(
&
pods
.
Items
[
0
],
test
.
Objects
()[
0
])
{
t
.
Errorf
(
"unexpected object: %#v"
,
test
.
Objects
())
t
.
Errorf
(
"unexpected object: %#v"
,
test
.
Objects
()
[
0
]
)
}
}
mapping
,
err
:=
b
.
Do
()
.
ResourceMapping
()
mapping
,
err
:=
b
.
Do
()
.
ResourceMapping
()
...
@@ -418,6 +422,34 @@ func TestMultipleResourceByTheSameName(t *testing.T) {
...
@@ -418,6 +422,34 @@ func TestMultipleResourceByTheSameName(t *testing.T) {
}
}
}
}
func
TestResourceNames
(
t
*
testing
.
T
)
{
pods
,
svc
:=
testData
()
b
:=
NewBuilder
(
latest
.
RESTMapper
,
api
.
Scheme
,
fakeClientWith
(
""
,
t
,
map
[
string
]
string
{
"/namespaces/test/pods/foo"
:
runtime
.
EncodeOrDie
(
latest
.
Codec
,
&
pods
.
Items
[
0
]),
"/namespaces/test/services/baz"
:
runtime
.
EncodeOrDie
(
latest
.
Codec
,
&
svc
.
Items
[
0
]),
}))
.
NamespaceParam
(
"test"
)
test
:=
&
testVisitor
{}
if
b
.
Do
()
.
Err
()
==
nil
{
t
.
Errorf
(
"unexpected non-error"
)
}
b
.
ResourceNames
(
"pods"
,
"foo"
,
"services/baz"
)
err
:=
b
.
Do
()
.
Visit
(
test
.
Handle
)
if
err
!=
nil
||
len
(
test
.
Infos
)
!=
2
{
t
.
Fatalf
(
"unexpected response: %v %#v"
,
err
,
test
.
Infos
)
}
if
!
reflect
.
DeepEqual
(
&
pods
.
Items
[
0
],
test
.
Objects
()[
0
])
{
t
.
Errorf
(
"unexpected object:
\n
%#v, expected:
\n
%#v"
,
test
.
Objects
()[
0
],
&
pods
.
Items
[
0
])
}
if
!
reflect
.
DeepEqual
(
&
svc
.
Items
[
0
],
test
.
Objects
()[
1
])
{
t
.
Errorf
(
"unexpected object:
\n
%#v, expected:
\n
%#v"
,
test
.
Objects
()[
1
],
&
svc
.
Items
[
0
])
}
}
func
TestResourceByNameWithoutRequireObject
(
t
*
testing
.
T
)
{
func
TestResourceByNameWithoutRequireObject
(
t
*
testing
.
T
)
{
b
:=
NewBuilder
(
latest
.
RESTMapper
,
api
.
Scheme
,
fakeClientWith
(
""
,
t
,
map
[
string
]
string
{}))
.
b
:=
NewBuilder
(
latest
.
RESTMapper
,
api
.
Scheme
,
fakeClientWith
(
""
,
t
,
map
[
string
]
string
{}))
.
NamespaceParam
(
"test"
)
NamespaceParam
(
"test"
)
...
...
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