Merge pull request #60717 from liggitt/field-selector

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Add field selector support to delete, label, annotate

**What this PR does / why we need it**:

Builds out field selector support for more bulk commands

**Release note**:
```release-note
kubectl now supports --field-selector for `delete`, `label`, and `annotate`
```
pull/8/head
Kubernetes Submit Queue 2018-05-01 11:20:24 -07:00 committed by GitHub
commit d39ff8e651
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 10 deletions

View File

@ -56,6 +56,7 @@ type AnnotateOptions struct {
all bool
resourceVersion string
selector string
fieldSelector string
outputFormat string
// results of arg parsing
@ -144,6 +145,7 @@ func NewCmdAnnotate(parent string, f cmdutil.Factory, ioStreams genericclioption
cmd.Flags().BoolVar(&o.overwrite, "overwrite", o.overwrite, "If true, allow annotations to be overwritten, otherwise reject annotation updates that overwrite existing annotations.")
cmd.Flags().BoolVar(&o.local, "local", o.local, "If true, annotation will NOT contact api-server but run locally.")
cmd.Flags().StringVarP(&o.selector, "selector", "l", o.selector, "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2).")
cmd.Flags().StringVar(&o.fieldSelector, "field-selector", o.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(&o.all, "all", o.all, "Select all resources, including uninitialized ones, in the namespace of the specified resource types.")
cmd.Flags().StringVar(&o.resourceVersion, "resource-version", o.resourceVersion, i18n.T("If non-empty, the annotation update will only succeed if this is the current resource-version for the object. Only valid when specifying a single resource."))
usage := "identifying the resource to update the annotation"
@ -205,6 +207,9 @@ func (o AnnotateOptions) Validate() error {
if o.all && len(o.selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time")
}
if o.all && len(o.fieldSelector) > 0 {
return fmt.Errorf("cannot set --all and --field-selector at the same time")
}
if len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>")
}
@ -227,6 +232,7 @@ func (o AnnotateOptions) RunAnnotate() error {
if !o.local {
b = b.LabelSelectorParam(o.selector).
FieldSelectorParam(o.fieldSelector).
ResourceTypeOrNameArgs(o.all, o.resources...).
Latest()
}

View File

@ -90,7 +90,8 @@ var (
type DeleteOptions struct {
resource.FilenameOptions
Selector string
LabelSelector string
FieldSelector string
DeleteAll bool
IgnoreNotFound bool
Cascade bool
@ -143,9 +144,6 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
deleteFlags.AddFlags(cmd)
// flag-specific output flag, as this command does not depend on PrintFlags
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones.")
cmdutil.AddIncludeUninitializedFlag(cmd)
return cmd
}
@ -156,7 +154,6 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args
return err
}
o.Selector = cmdutil.GetFlagString(cmd, "selector")
o.Reaper = f.Reaper
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
@ -165,7 +162,8 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
LabelSelectorParam(o.Selector).
LabelSelectorParam(o.LabelSelector).
FieldSelectorParam(o.FieldSelector).
IncludeUninitialized(includeUninitialized).
SelectAllParam(o.DeleteAll).
ResourceTypeOrNameArgs(false, args...).RequireObject(false).
@ -186,9 +184,12 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args
}
func (o *DeleteOptions) Validate(cmd *cobra.Command) error {
if o.DeleteAll && len(o.Selector) > 0 {
if o.DeleteAll && len(o.LabelSelector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time")
}
if o.DeleteAll && len(o.FieldSelector) > 0 {
return fmt.Errorf("cannot set --all and --field-selector at the same time")
}
if o.DeleteAll {
f := cmd.Flags().Lookup("ignore-not-found")
// The flag should never be missing

View File

@ -59,6 +59,8 @@ func (o *FileNameFlags) AddFlags(cmd *cobra.Command) {
// used for commands requiring deletion logic.
type DeleteFlags struct {
FileNameFlags *FileNameFlags
LabelSelector *string
FieldSelector *string
All *bool
Cascade *bool
@ -80,6 +82,12 @@ func (f *DeleteFlags) ToOptions(out, errOut io.Writer) *DeleteOptions {
if f.FileNameFlags != nil {
options.FilenameOptions = f.FileNameFlags.ToOptions()
}
if f.LabelSelector != nil {
options.LabelSelector = *f.LabelSelector
}
if f.FieldSelector != nil {
options.FieldSelector = *f.FieldSelector
}
// add output format
if f.Output != nil {
@ -113,7 +121,12 @@ func (f *DeleteFlags) ToOptions(out, errOut io.Writer) *DeleteOptions {
func (f *DeleteFlags) AddFlags(cmd *cobra.Command) {
f.FileNameFlags.AddFlags(cmd)
if f.LabelSelector != nil {
cmd.Flags().StringVarP(f.LabelSelector, "selector", "l", *f.LabelSelector, "Selector (label query) to filter on, not including uninitialized ones.")
}
if f.FieldSelector != nil {
cmd.Flags().StringVarP(f.FieldSelector, "field-selector", "", *f.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.")
}
if f.All != nil {
cmd.Flags().BoolVar(f.All, "all", *f.All, "Delete all resources, including uninitialized ones, in the namespace of the specified resource types.")
}
@ -153,6 +166,8 @@ func NewDeleteCommandFlags(usage string) *DeleteFlags {
ignoreNotFound := false
now := false
output := ""
labelSelector := ""
fieldSelector := ""
timeout := time.Duration(0)
filenames := []string{}
@ -160,6 +175,8 @@ func NewDeleteCommandFlags(usage string) *DeleteFlags {
return &DeleteFlags{
FileNameFlags: &FileNameFlags{Usage: usage, Filenames: &filenames, Recursive: &recursive},
LabelSelector: &labelSelector,
FieldSelector: &fieldSelector,
Cascade: &cascade,
GracePeriod: &gracePeriod,

View File

@ -52,8 +52,6 @@ func fakecmd() *cobra.Command {
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
},
}
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones.")
return cmd
}

View File

@ -59,6 +59,7 @@ type LabelOptions struct {
all bool
resourceVersion string
selector string
fieldSelector string
outputFormat string
// results of arg parsing
@ -146,6 +147,7 @@ func NewCmdLabel(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobr
cmd.Flags().BoolVar(&o.list, "list", o.list, "If true, display the labels for a given resource.")
cmd.Flags().BoolVar(&o.local, "local", o.local, "If true, label will NOT contact api-server but run locally.")
cmd.Flags().StringVarP(&o.selector, "selector", "l", o.selector, "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2).")
cmd.Flags().StringVar(&o.fieldSelector, "field-selector", o.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(&o.all, "all", o.all, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().StringVar(&o.resourceVersion, "resource-version", o.resourceVersion, i18n.T("If non-empty, the labels update will only succeed if this is the current resource-version for the object. Only valid when specifying a single resource."))
usage := "identifying the resource to update the labels"
@ -209,6 +211,9 @@ func (o *LabelOptions) Validate() error {
if o.all && len(o.selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time")
}
if o.all && len(o.fieldSelector) > 0 {
return fmt.Errorf("cannot set --all and --field-selector at the same time")
}
if len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>")
}
@ -231,6 +236,7 @@ func (o *LabelOptions) RunLabel() error {
if !o.local {
b = b.LabelSelectorParam(o.selector).
FieldSelectorParam(o.fieldSelector).
ResourceTypeOrNameArgs(o.all, o.resources...).
Latest()
}