mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-09 05:01:46 +00:00
Adds support for multiple resources to kubectl
You can specify multiple resources by name when using the delete, get and stop commands.
This commit is contained in:
@@ -48,7 +48,7 @@ type Builder struct {
|
||||
resources []string
|
||||
|
||||
namespace string
|
||||
name string
|
||||
names []string
|
||||
|
||||
defaultNamespace bool
|
||||
requireNamespace bool
|
||||
@@ -217,22 +217,25 @@ func (b *Builder) SelectAllParam(selectAll bool) *Builder {
|
||||
return b
|
||||
}
|
||||
|
||||
// ResourceTypeOrNameArgs indicates that the builder should accept one or two arguments
|
||||
// of the form `(<type1>[,<type2>,...]|<type> <name>)`. When one argument is received, the types
|
||||
// provided will be retrieved from the server (and be comma delimited). When two arguments are
|
||||
// received, they must be a single type and name. If more than two arguments are provided an
|
||||
// error is set. The allowEmptySelector permits to select all the resources (via Everything func).
|
||||
// ResourceTypeOrNameArgs indicates that the builder should accept arguments
|
||||
// of the form `(<type1>[,<type2>,...]|<type> <name1>[,<name2>,...])`. When one argument is
|
||||
// received, the types provided will be retrieved from the server (and be comma delimited).
|
||||
// When two or more arguments are received, they must be a single type and resource name(s).
|
||||
// The allowEmptySelector permits to select all the resources (via Everything func).
|
||||
func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string) *Builder {
|
||||
switch len(args) {
|
||||
case 2:
|
||||
b.name = args[1]
|
||||
switch {
|
||||
case len(args) > 2:
|
||||
b.names = append(b.names, args[1:]...)
|
||||
b.ResourceTypes(SplitResourceArgument(args[0])...)
|
||||
case 1:
|
||||
case len(args) == 2:
|
||||
b.names = append(b.names, args[1])
|
||||
b.ResourceTypes(SplitResourceArgument(args[0])...)
|
||||
case len(args) == 1:
|
||||
b.ResourceTypes(SplitResourceArgument(args[0])...)
|
||||
if b.selector == nil && allowEmptySelector {
|
||||
b.selector = labels.Everything()
|
||||
}
|
||||
case 0:
|
||||
case len(args) == 0:
|
||||
default:
|
||||
b.errs = append(b.errs, fmt.Errorf("when passing arguments, must be resource or resource and name"))
|
||||
}
|
||||
@@ -244,7 +247,7 @@ func (b *Builder) ResourceTypeOrNameArgs(allowEmptySelector bool, args ...string
|
||||
func (b *Builder) ResourceTypeAndNameArgs(args ...string) *Builder {
|
||||
switch len(args) {
|
||||
case 2:
|
||||
b.name = args[1]
|
||||
b.names = append(b.names, args[1])
|
||||
b.ResourceTypes(SplitResourceArgument(args[0])...)
|
||||
case 0:
|
||||
default:
|
||||
@@ -312,7 +315,7 @@ func (b *Builder) visitorResult() *Result {
|
||||
|
||||
// visit selectors
|
||||
if b.selector != nil {
|
||||
if len(b.name) != 0 {
|
||||
if len(b.names) != 0 {
|
||||
return &Result{err: fmt.Errorf("name cannot be provided when a selector is specified")}
|
||||
}
|
||||
if len(b.resources) == 0 {
|
||||
@@ -349,38 +352,49 @@ func (b *Builder) visitorResult() *Result {
|
||||
return &Result{visitor: VisitorList(visitors), sources: visitors}
|
||||
}
|
||||
|
||||
// visit single item specified by name
|
||||
if len(b.name) != 0 {
|
||||
// visit items specified by name
|
||||
if len(b.names) != 0 {
|
||||
isSingular := len(b.names) == 1
|
||||
|
||||
if len(b.paths) != 0 {
|
||||
return &Result{singular: true, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify a resource by arguments as well")}
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("when paths, URLs, or stdin is provided as input, you may not specify a resource by arguments as well")}
|
||||
}
|
||||
if len(b.resources) == 0 {
|
||||
return &Result{singular: true, err: fmt.Errorf("you must provide a resource and a resource name together")}
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("you must provide a resource and a resource name together")}
|
||||
}
|
||||
if len(b.resources) > 1 {
|
||||
return &Result{singular: true, err: fmt.Errorf("you must specify only one resource")}
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("you must specify only one resource")}
|
||||
}
|
||||
|
||||
mappings, err := b.resourceMappings()
|
||||
if err != nil {
|
||||
return &Result{singular: true, err: err}
|
||||
return &Result{singular: isSingular, err: err}
|
||||
}
|
||||
mapping := mappings[0]
|
||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||
b.namespace = ""
|
||||
} else {
|
||||
if len(b.namespace) == 0 {
|
||||
return &Result{singular: true, err: fmt.Errorf("namespace may not be empty when retrieving a resource by name")}
|
||||
}
|
||||
}
|
||||
|
||||
client, err := b.mapper.ClientForMapping(mapping)
|
||||
if err != nil {
|
||||
return &Result{singular: true, err: err}
|
||||
return &Result{err: err}
|
||||
}
|
||||
info := NewInfo(client, mappings[0], b.namespace, b.name)
|
||||
if err := info.Get(); err != nil {
|
||||
return &Result{singular: true, err: err}
|
||||
|
||||
selectorNamespace := b.namespace
|
||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||
selectorNamespace = ""
|
||||
} else {
|
||||
if len(b.namespace) == 0 {
|
||||
return &Result{singular: isSingular, err: fmt.Errorf("namespace may not be empty when retrieving a resource by name")}
|
||||
}
|
||||
}
|
||||
return &Result{singular: true, visitor: info, sources: []Visitor{info}}
|
||||
|
||||
visitors := []Visitor{}
|
||||
for _, name := range b.names {
|
||||
info := NewInfo(client, mapping, selectorNamespace, name)
|
||||
if err := info.Get(); err != nil {
|
||||
return &Result{singular: isSingular, err: err}
|
||||
}
|
||||
visitors = append(visitors, info)
|
||||
}
|
||||
return &Result{singular: isSingular, visitor: VisitorList(visitors), sources: visitors}
|
||||
}
|
||||
|
||||
// visit items specified by paths
|
||||
|
Reference in New Issue
Block a user