mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 12:43:23 +00:00
add fieldSelector for kubectl get
This commit is contained in:
parent
057b7bf767
commit
4a3131ddaa
@ -367,8 +367,8 @@ func RunApply(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opti
|
||||
clientFunc: f.UnstructuredClientForMapping,
|
||||
clientsetFunc: f.ClientSet,
|
||||
|
||||
selector: options.Selector,
|
||||
visitedUids: visitedUids,
|
||||
labelSelector: options.Selector,
|
||||
visitedUids: visitedUids,
|
||||
|
||||
cascade: options.Cascade,
|
||||
dryRun: dryRun,
|
||||
@ -453,8 +453,9 @@ type pruner struct {
|
||||
clientFunc resource.ClientMapperFunc
|
||||
clientsetFunc func() (internalclientset.Interface, error)
|
||||
|
||||
visitedUids sets.String
|
||||
selector string
|
||||
visitedUids sets.String
|
||||
labelSelector string
|
||||
fieldSelector string
|
||||
|
||||
cascade bool
|
||||
dryRun bool
|
||||
@ -474,7 +475,8 @@ func (p *pruner) prune(namespace string, mapping *meta.RESTMapping, shortOutput,
|
||||
mapping.GroupVersionKind.Version,
|
||||
false,
|
||||
&metav1.ListOptions{
|
||||
LabelSelector: p.selector,
|
||||
LabelSelector: p.labelSelector,
|
||||
FieldSelector: p.fieldSelector,
|
||||
IncludeUninitialized: includeUninitialized,
|
||||
},
|
||||
)
|
||||
|
@ -56,6 +56,7 @@ type GetOptions struct {
|
||||
ChunkSize int64
|
||||
|
||||
LabelSelector string
|
||||
FieldSelector string
|
||||
AllNamespaces bool
|
||||
Namespace string
|
||||
ExplicitNamespace bool
|
||||
@ -158,6 +159,7 @@ func NewCmdGet(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comman
|
||||
cmd.Flags().Int64Var(&options.ChunkSize, "chunk-size", 500, "Return large lists in chunks rather than all at once. Pass 0 to disable. This flag is beta and may change in the future.")
|
||||
cmd.Flags().BoolVar(&options.IgnoreNotFound, "ignore-not-found", options.IgnoreNotFound, "If the requested object does not exist the command will return exit code 0.")
|
||||
cmd.Flags().StringVarP(&options.LabelSelector, "selector", "l", options.LabelSelector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||
cmd.Flags().StringVar(&options.FieldSelector, "field-selector", options.FieldSelector, "Selector (field query) to filter on, supports '=', '==', and '!='.(e.g. --field-selector key1=value1,key2=value2). The server only supports a limited number of field queries per type.")
|
||||
cmd.Flags().BoolVar(&options.AllNamespaces, "all-namespaces", options.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
|
||||
cmdutil.AddIncludeUninitializedFlag(cmd)
|
||||
cmdutil.AddPrinterFlags(cmd)
|
||||
@ -234,6 +236,7 @@ func (options *GetOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []str
|
||||
NamespaceParam(options.Namespace).DefaultNamespace().AllNamespaces(options.AllNamespaces).
|
||||
FilenameParam(options.ExplicitNamespace, &options.FilenameOptions).
|
||||
LabelSelectorParam(options.LabelSelector).
|
||||
FieldSelectorParam(options.FieldSelector).
|
||||
ExportParam(options.Export).
|
||||
RequestChunksOf(options.ChunkSize).
|
||||
IncludeUninitialized(cmdutil.ShouldIncludeUninitialized(cmd, false)). // TODO: this needs to be better factored
|
||||
@ -451,6 +454,7 @@ func (options *GetOptions) watch(f cmdutil.Factory, cmd *cobra.Command, args []s
|
||||
NamespaceParam(options.Namespace).DefaultNamespace().AllNamespaces(options.AllNamespaces).
|
||||
FilenameParam(options.ExplicitNamespace, &options.FilenameOptions).
|
||||
LabelSelectorParam(options.LabelSelector).
|
||||
FieldSelectorParam(options.FieldSelector).
|
||||
ExportParam(options.Export).
|
||||
RequestChunksOf(options.ChunkSize).
|
||||
IncludeUninitialized(includeUninitialized).
|
||||
|
@ -54,6 +54,7 @@ type Builder struct {
|
||||
dir bool
|
||||
|
||||
labelSelector *string
|
||||
fieldSelector *string
|
||||
selectAll bool
|
||||
includeUninitialized bool
|
||||
limitChunks int64
|
||||
@ -296,6 +297,22 @@ func (b *Builder) LabelSelector(selector string) *Builder {
|
||||
return b
|
||||
}
|
||||
|
||||
// FieldSelectorParam 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
|
||||
// a no-op - to select all resources.
|
||||
func (b *Builder) FieldSelectorParam(s string) *Builder {
|
||||
s = strings.TrimSpace(s)
|
||||
if len(s) == 0 {
|
||||
return b
|
||||
}
|
||||
if b.selectAll {
|
||||
b.errs = append(b.errs, fmt.Errorf("found non-empty field selector %q with previously set 'all' parameter. ", s))
|
||||
return b
|
||||
}
|
||||
b.fieldSelector = &s
|
||||
return b
|
||||
}
|
||||
|
||||
// ExportParam accepts the export boolean for these resources
|
||||
func (b *Builder) ExportParam(export bool) *Builder {
|
||||
b.export = export
|
||||
@ -350,7 +367,7 @@ func (b *Builder) RequestChunksOf(chunkSize int64) *Builder {
|
||||
|
||||
// SelectEverythingParam
|
||||
func (b *Builder) SelectAllParam(selectAll bool) *Builder {
|
||||
if selectAll && b.labelSelector != nil {
|
||||
if selectAll && (b.labelSelector != nil || b.fieldSelector != nil) {
|
||||
b.errs = append(b.errs, fmt.Errorf("setting 'all' parameter but found a non empty selector. "))
|
||||
return b
|
||||
}
|
||||
@ -595,7 +612,7 @@ func (b *Builder) visitorResult() *Result {
|
||||
}
|
||||
|
||||
// visit selectors
|
||||
if b.labelSelector != nil {
|
||||
if b.labelSelector != nil || b.fieldSelector != nil {
|
||||
return b.visitBySelector()
|
||||
}
|
||||
|
||||
@ -635,6 +652,14 @@ func (b *Builder) visitBySelector() *Result {
|
||||
return result
|
||||
}
|
||||
|
||||
var labelSelector, fieldSelector string
|
||||
if b.labelSelector != nil {
|
||||
labelSelector = *b.labelSelector
|
||||
}
|
||||
if b.fieldSelector != nil {
|
||||
fieldSelector = *b.fieldSelector
|
||||
}
|
||||
|
||||
visitors := []Visitor{}
|
||||
for _, mapping := range mappings {
|
||||
client, err := b.mapper.ClientForMapping(mapping)
|
||||
@ -646,7 +671,7 @@ func (b *Builder) visitBySelector() *Result {
|
||||
if mapping.Scope.Name() != meta.RESTScopeNameNamespace {
|
||||
selectorNamespace = ""
|
||||
}
|
||||
visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, *b.labelSelector, b.export, b.includeUninitialized, b.limitChunks))
|
||||
visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, labelSelector, fieldSelector, b.export, b.includeUninitialized, b.limitChunks))
|
||||
}
|
||||
if b.continueOnError {
|
||||
result.visitor = EagerVisitorList(visitors)
|
||||
|
@ -75,15 +75,12 @@ func (m *Helper) List(namespace, apiVersion string, export bool, options *metav1
|
||||
return req.Do().Get()
|
||||
}
|
||||
|
||||
func (m *Helper) Watch(namespace, resourceVersion, apiVersion string, labelSelector string) (watch.Interface, error) {
|
||||
func (m *Helper) Watch(namespace, apiVersion string, options *metav1.ListOptions) (watch.Interface, error) {
|
||||
options.Watch = true
|
||||
return m.RESTClient.Get().
|
||||
NamespaceIfScoped(namespace, m.NamespaceScoped).
|
||||
Resource(m.Resource).
|
||||
VersionedParams(&metav1.ListOptions{
|
||||
ResourceVersion: resourceVersion,
|
||||
Watch: true,
|
||||
LabelSelector: labelSelector,
|
||||
}, metav1.ParameterCodec).
|
||||
VersionedParams(options, metav1.ParameterCodec).
|
||||
Watch()
|
||||
}
|
||||
|
||||
|
@ -31,18 +31,20 @@ type Selector struct {
|
||||
Mapping *meta.RESTMapping
|
||||
Namespace string
|
||||
LabelSelector string
|
||||
FieldSelector string
|
||||
Export bool
|
||||
IncludeUninitialized bool
|
||||
LimitChunks int64
|
||||
}
|
||||
|
||||
// NewSelector creates a resource selector which hides details of getting items by their label selector.
|
||||
func NewSelector(client RESTClient, mapping *meta.RESTMapping, namespace string, selector string, export, includeUninitialized bool, limitChunks int64) *Selector {
|
||||
func NewSelector(client RESTClient, mapping *meta.RESTMapping, namespace, labelSelector, fieldSelector string, export, includeUninitialized bool, limitChunks int64) *Selector {
|
||||
return &Selector{
|
||||
Client: client,
|
||||
Mapping: mapping,
|
||||
Namespace: namespace,
|
||||
LabelSelector: selector,
|
||||
LabelSelector: labelSelector,
|
||||
FieldSelector: fieldSelector,
|
||||
Export: export,
|
||||
IncludeUninitialized: includeUninitialized,
|
||||
LimitChunks: limitChunks,
|
||||
@ -59,6 +61,7 @@ func (r *Selector) Visit(fn VisitorFunc) error {
|
||||
r.Export,
|
||||
&metav1.ListOptions{
|
||||
LabelSelector: r.LabelSelector,
|
||||
FieldSelector: r.FieldSelector,
|
||||
IncludeUninitialized: r.IncludeUninitialized,
|
||||
Limit: r.LimitChunks,
|
||||
Continue: continueToken,
|
||||
@ -71,17 +74,17 @@ func (r *Selector) Visit(fn VisitorFunc) error {
|
||||
if errors.IsBadRequest(err) || errors.IsNotFound(err) {
|
||||
if se, ok := err.(*errors.StatusError); ok {
|
||||
// modify the message without hiding this is an API error
|
||||
if len(r.LabelSelector) == 0 {
|
||||
if len(r.LabelSelector) == 0 && len(r.FieldSelector) == 0 {
|
||||
se.ErrStatus.Message = fmt.Sprintf("Unable to list %q: %v", r.Mapping.Resource, se.ErrStatus.Message)
|
||||
} else {
|
||||
se.ErrStatus.Message = fmt.Sprintf("Unable to find %q that match the selector %q: %v", r.Mapping.Resource, r.LabelSelector, se.ErrStatus.Message)
|
||||
se.ErrStatus.Message = fmt.Sprintf("Unable to find %q that match label selector %q, field selector %q: %v", r.Mapping.Resource, r.LabelSelector, r.FieldSelector, se.ErrStatus.Message)
|
||||
}
|
||||
return se
|
||||
}
|
||||
if len(r.LabelSelector) == 0 {
|
||||
if len(r.LabelSelector) == 0 && len(r.FieldSelector) == 0 {
|
||||
return fmt.Errorf("Unable to list %q: %v", r.Mapping.Resource, err)
|
||||
}
|
||||
return fmt.Errorf("Unable to find %q that match the selector %q: %v", r.Mapping.Resource, r.LabelSelector, err)
|
||||
return fmt.Errorf("Unable to find %q that match label selector %q, field selector %q: %v", r.Mapping.Resource, r.LabelSelector, r.FieldSelector, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@ -107,7 +110,8 @@ func (r *Selector) Visit(fn VisitorFunc) error {
|
||||
}
|
||||
|
||||
func (r *Selector) Watch(resourceVersion string) (watch.Interface, error) {
|
||||
return NewHelper(r.Client, r.Mapping).Watch(r.Namespace, resourceVersion, r.ResourceMapping().GroupVersionKind.GroupVersion().String(), r.LabelSelector)
|
||||
return NewHelper(r.Client, r.Mapping).Watch(r.Namespace, r.ResourceMapping().GroupVersionKind.GroupVersion().String(),
|
||||
&metav1.ListOptions{ResourceVersion: resourceVersion, LabelSelector: r.LabelSelector, FieldSelector: r.FieldSelector})
|
||||
}
|
||||
|
||||
// ResourceMapping returns the mapping for this resource and implements ResourceMapping
|
||||
|
Loading…
Reference in New Issue
Block a user