Skip to content

Commit

Permalink
Merge pull request kubernetes#51323 from dixudx/conflict_flags
Browse files Browse the repository at this point in the history
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>.

kubectl should return an error if "-l" and "--all" are both specified

**What this PR does / why we need it**:
Per discussion in [kubernetes#50497](kubernetes#50497 (comment))

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #

**Special notes for your reviewer**:
/assign @caesarxuchao @mengqiy 

**Release note**:

```release-note
kubectl should return an error if "-l" and "--all" are both specified
```
  • Loading branch information
Kubernetes Submit Queue committed Feb 6, 2018
2 parents aa1849e + e451178 commit 989e4f8
Show file tree
Hide file tree
Showing 11 changed files with 51 additions and 46 deletions.
18 changes: 8 additions & 10 deletions pkg/kubectl/cmd/annotate.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,11 @@ func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
}
cmdutil.AddPrinterFlags(cmd)
cmdutil.AddIncludeUninitializedFlag(cmd)
cmd.Flags().Bool("overwrite", false, "If true, allow annotations to be overwritten, otherwise reject annotation updates that overwrite existing annotations.")
cmd.Flags().Bool("local", false, "If true, annotation will NOT contact api-server but run locally.")
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2).")
cmd.Flags().Bool("all", false, "Select all resources, including uninitialized ones, in the namespace of the specified resource types.")
cmd.Flags().String("resource-version", "", 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."))
cmd.Flags().BoolVar(&options.overwrite, "overwrite", options.overwrite, "If true, allow annotations to be overwritten, otherwise reject annotation updates that overwrite existing annotations.")
cmd.Flags().BoolVar(&options.local, "local", options.local, "If true, annotation will NOT contact api-server but run locally.")
cmd.Flags().StringVarP(&options.selector, "selector", "l", options.selector, "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2).")
cmd.Flags().BoolVar(&options.all, "all", options.all, "Select all resources, including uninitialized ones, in the namespace of the specified resource types.")
cmd.Flags().StringVar(&options.resourceVersion, "resource-version", options.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"
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmdutil.AddDryRunFlag(cmd)
Expand All @@ -138,11 +138,6 @@ func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
// Complete adapts from the command line args and factory to the data required.
func (o *AnnotateOptions) Complete(out io.Writer, cmd *cobra.Command, args []string) (err error) {
o.out = out
o.local = cmdutil.GetFlagBool(cmd, "local")
o.overwrite = cmdutil.GetFlagBool(cmd, "overwrite")
o.all = cmdutil.GetFlagBool(cmd, "all")
o.resourceVersion = cmdutil.GetFlagString(cmd, "resource-version")
o.selector = cmdutil.GetFlagString(cmd, "selector")
o.outputFormat = cmdutil.GetFlagString(cmd, "output")
o.dryrun = cmdutil.GetDryRunFlag(cmd)
o.recordChangeCause = cmdutil.GetRecordFlag(cmd)
Expand All @@ -160,6 +155,9 @@ func (o *AnnotateOptions) Complete(out io.Writer, cmd *cobra.Command, args []str

// Validate checks to the AnnotateOptions to see if there is sufficient information run the command.
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 len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
return fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>")
}
Expand Down
6 changes: 2 additions & 4 deletions pkg/kubectl/cmd/annotate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -563,8 +563,7 @@ func TestAnnotateLocal(t *testing.T) {

buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(f, buf)
cmd.Flags().Set("local", "true")
options := &AnnotateOptions{}
options := &AnnotateOptions{local: true}
options.Filenames = []string{"../../../examples/storage/cassandra/cassandra-controller.yaml"}
args := []string{"a=b"}
if err := options.Complete(buf, cmd, args); err != nil {
Expand Down Expand Up @@ -618,8 +617,7 @@ func TestAnnotateMultipleObjects(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdAnnotate(f, buf)
cmd.SetOutput(buf)
cmd.Flags().Set("all", "true")
options := &AnnotateOptions{}
options := &AnnotateOptions{all: true}
args := []string{"pods", "a=b", "c-"}
if err := options.Complete(buf, cmd, args); err != nil {
t.Fatalf("unexpected error: %v", err)
Expand Down
11 changes: 7 additions & 4 deletions pkg/kubectl/cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ type ApplyOptions struct {
PruneResources []pruneResource
Timeout time.Duration
cmdBaseName string
all bool
}

const (
Expand Down Expand Up @@ -112,7 +113,7 @@ func NewCmdApply(baseName string, f cmdutil.Factory, out, errOut io.Writer) *cob
Example: applyExample,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(validateArgs(cmd, args))
cmdutil.CheckErr(validatePruneAll(options.Prune, cmdutil.GetFlagBool(cmd, "all"), options.Selector))
cmdutil.CheckErr(validatePruneAll(options.Prune, options.all, options.Selector))
cmdutil.CheckErr(RunApply(f, cmd, out, errOut, &options))
},
}
Expand All @@ -127,8 +128,8 @@ func NewCmdApply(baseName string, f cmdutil.Factory, out, errOut io.Writer) *cob
cmd.Flags().BoolVar(&options.Force, "force", false, fmt.Sprintf("Delete and re-create the specified resource, when PATCH encounters conflict and has retried for %d times.", maxPatchRetry))
cmd.Flags().DurationVar(&options.Timeout, "timeout", 0, "Only relevant during a force apply. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object. Any other values should contain a corresponding time unit (e.g. 1s, 2m, 3h).")
cmdutil.AddValidateFlags(cmd)
cmd.Flags().StringVarP(&options.Selector, "selector", "l", "", "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().Bool("all", false, "Select all resources in the namespace of the specified resource types.")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().BoolVar(&options.all, "all", options.all, "Select all resources in the namespace of the specified resource types.")
cmd.Flags().StringArray("prune-whitelist", []string{}, "Overwrite the default whitelist with <group/version/kind> for --prune")
cmd.Flags().Bool("openapi-patch", true, "If true, use openapi to calculate diff when the openapi presents and the resource can be found in the openapi spec. Otherwise, fall back to use baked-in types.")
cmdutil.AddDryRunFlag(cmd)
Expand All @@ -149,11 +150,13 @@ func validateArgs(cmd *cobra.Command, args []string) error {
if len(args) != 0 {
return cmdutil.UsageErrorf(cmd, "Unexpected args: %v", args)
}

return nil
}

func validatePruneAll(prune, all bool, selector string) error {
if all && len(selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time")
}
if prune && !all && selector == "" {
return fmt.Errorf("all resources selected for prune without explicitly passing --all. To prune all resources, pass the --all flag. If you did not mean to prune all resources, specify a label selector.")
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/kubectl/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
usage := "containing the resource to delete."
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmd.Flags().StringVarP(&options.Selector, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones.")
cmd.Flags().BoolVar(&options.DeleteAll, "all", false, "Delete all resources, including uninitialized ones, in the namespace of the specified resource types.")
cmd.Flags().BoolVar(&options.DeleteAll, "all", options.DeleteAll, "Delete all resources, including uninitialized ones, in the namespace of the specified resource types.")
cmd.Flags().BoolVar(&options.IgnoreNotFound, "ignore-not-found", false, "Treat \"resource not found\" as a successful delete. Defaults to \"true\" when --all is specified.")
cmd.Flags().BoolVar(&options.Cascade, "cascade", true, "If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.")
cmd.Flags().IntVar(&options.GracePeriod, "grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
Expand Down Expand Up @@ -187,6 +187,9 @@ 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 {
return fmt.Errorf("cannot set --all and --selector at the same time")
}
if o.DeleteAll {
f := cmd.Flags().Lookup("ignore-not-found")
// The flag should never be missing
Expand Down
19 changes: 8 additions & 11 deletions pkg/kubectl/cmd/label.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ func NewCmdLabel(f cmdutil.Factory, out io.Writer) *cobra.Command {
ArgAliases: kubectl.ResourceAliases(validArgs),
}
cmdutil.AddPrinterFlags(cmd)
cmd.Flags().Bool("overwrite", false, "If true, allow labels to be overwritten, otherwise reject label updates that overwrite existing labels.")
cmd.Flags().BoolVar(&options.overwrite, "overwrite", false, "If true, allow labels to be overwritten, otherwise reject label updates that overwrite existing labels.")
cmd.Flags().BoolVar(&options.list, "list", options.list, "If true, display the labels for a given resource.")
cmd.Flags().Bool("local", false, "If true, label will NOT contact api-server but run locally.")
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2).")
cmd.Flags().Bool("all", false, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().String("resource-version", "", 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."))
cmd.Flags().BoolVar(&options.local, "local", options.local, "If true, label will NOT contact api-server but run locally.")
cmd.Flags().StringVarP(&options.selector, "selector", "l", options.selector, "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2).")
cmd.Flags().BoolVar(&options.all, "all", options.all, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().StringVar(&options.resourceVersion, "resource-version", options.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"
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmdutil.AddDryRunFlag(cmd)
Expand All @@ -137,12 +137,6 @@ func NewCmdLabel(f cmdutil.Factory, out io.Writer) *cobra.Command {
// Complete adapts from the command line args and factory to the data required.
func (o *LabelOptions) Complete(out io.Writer, cmd *cobra.Command, args []string) (err error) {
o.out = out
o.list = cmdutil.GetFlagBool(cmd, "list")
o.local = cmdutil.GetFlagBool(cmd, "local")
o.overwrite = cmdutil.GetFlagBool(cmd, "overwrite")
o.all = cmdutil.GetFlagBool(cmd, "all")
o.resourceVersion = cmdutil.GetFlagString(cmd, "resource-version")
o.selector = cmdutil.GetFlagString(cmd, "selector")
o.outputFormat = cmdutil.GetFlagString(cmd, "output")
o.dryrun = cmdutil.GetDryRunFlag(cmd)

Expand All @@ -162,6 +156,9 @@ func (o *LabelOptions) Complete(out io.Writer, cmd *cobra.Command, args []string

// Validate checks to the LabelOptions to see if there is sufficient information run the command.
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 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>")
}
Expand Down
8 changes: 3 additions & 5 deletions pkg/kubectl/cmd/label_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,9 +417,9 @@ func TestLabelLocal(t *testing.T) {

buf := bytes.NewBuffer([]byte{})
cmd := NewCmdLabel(f, buf)
cmd.Flags().Set("local", "true")
opts := LabelOptions{FilenameOptions: resource.FilenameOptions{
Filenames: []string{"../../../examples/storage/cassandra/cassandra-controller.yaml"}}}
Filenames: []string{"../../../examples/storage/cassandra/cassandra-controller.yaml"}},
local: true}
err := opts.Complete(buf, cmd, []string{"a=b"})
if err == nil {
err = opts.Validate()
Expand Down Expand Up @@ -471,9 +471,7 @@ func TestLabelMultipleObjects(t *testing.T) {

buf := bytes.NewBuffer([]byte{})
cmd := NewCmdLabel(f, buf)
cmd.Flags().Set("all", "true")

opts := LabelOptions{}
opts := LabelOptions{all: true}
err := opts.Complete(buf, cmd, []string{"pods", "a=b"})
if err == nil {
err = opts.Validate()
Expand Down
5 changes: 4 additions & 1 deletion pkg/kubectl/cmd/set/set_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func NewCmdEnv(f cmdutil.Factory, in io.Reader, out, errout io.Writer) *cobra.Co
cmd.Flags().BoolVar(&options.List, "list", options.List, "If true, display the environment and any changes in the standard format. this flag will removed when we have kubectl view env.")
cmd.Flags().BoolVar(&options.Resolve, "resolve", options.Resolve, "If true, show secret or configmap references when listing variables")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on")
cmd.Flags().BoolVar(&options.Local, "local", false, "If true, set env will NOT contact api-server but run locally.")
cmd.Flags().BoolVar(&options.Local, "local", options.Local, "If true, set env will NOT contact api-server but run locally.")
cmd.Flags().BoolVar(&options.All, "all", options.All, "If true, select all resources in the namespace of the specified resource types")
cmd.Flags().BoolVar(&options.Overwrite, "overwrite", true, "If true, allow environment to be overwritten, otherwise reject updates that overwrite existing environment.")

Expand All @@ -178,6 +178,9 @@ func keyToEnvName(key string) string {
}

func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
if o.All && len(o.Selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time")
}
resources, envArgs, ok := envutil.SplitEnvironmentFromResources(args)
if !ok {
return cmdutil.UsageErrorf(o.Cmd, "all resources must be specified before environment changes: %s", strings.Join(args, " "))
Expand Down
8 changes: 5 additions & 3 deletions pkg/kubectl/cmd/set/set_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ func NewCmdImage(f cmdutil.Factory, out, err io.Writer) *cobra.Command {
cmdutil.AddPrinterFlags(cmd)
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmd.Flags().BoolVar(&options.All, "all", false, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().BoolVar(&options.All, "all", options.All, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().BoolVar(&options.Local, "local", false, "If true, set image will NOT contact api-server but run locally.")
cmd.Flags().BoolVar(&options.Local, "local", options.Local, "If true, set image will NOT contact api-server but run locally.")
cmdutil.AddRecordFlag(cmd)
cmdutil.AddDryRunFlag(cmd)
cmdutil.AddIncludeUninitializedFlag(cmd)
Expand All @@ -126,7 +126,6 @@ func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st
o.Record = cmdutil.GetRecordFlag(cmd)
o.ChangeCause = f.Command(cmd, false)
o.PrintObject = f.PrintObject
o.Local = cmdutil.GetFlagBool(cmd, "local")
o.DryRun = cmdutil.GetDryRunFlag(cmd)
o.Output = cmdutil.GetFlagString(cmd, "output")
o.ResolveImage = f.ResolveImage
Expand Down Expand Up @@ -175,6 +174,9 @@ func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st

func (o *ImageOptions) Validate() error {
errors := []error{}
if o.All && len(o.Selector) > 0 {
errors = append(errors, fmt.Errorf("cannot set --all and --selector at the same time"))
}
if len(o.Resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
errors = append(errors, fmt.Errorf("one or more resources must be specified as <resource> <name> or <resource>/<name>"))
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/kubectl/cmd/set/set_resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,10 @@ func NewCmdResources(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.
//kubectl.AddJsonFilenameFlag(cmd, &options.Filenames, usage)
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmd.Flags().BoolVar(&options.All, "all", false, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().BoolVar(&options.All, "all", options.All, "Select all resources, including uninitialized ones, in the namespace of the specified resource types")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones,supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().StringVarP(&options.ContainerSelector, "containers", "c", "*", "The names of containers in the selected pod templates to change, all containers are selected by default - may use wildcards")
cmd.Flags().BoolVar(&options.Local, "local", false, "If true, set resources will NOT contact api-server but run locally.")
cmd.Flags().BoolVar(&options.Local, "local", options.Local, "If true, set resources will NOT contact api-server but run locally.")
cmdutil.AddDryRunFlag(cmd)
cmdutil.AddRecordFlag(cmd)
cmdutil.AddIncludeUninitializedFlag(cmd)
Expand All @@ -134,7 +134,6 @@ func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
o.Encoder = f.JSONEncoder()
o.Output = cmdutil.GetFlagString(cmd, "output")
o.Record = cmdutil.GetRecordFlag(cmd)
o.Local = cmdutil.GetFlagBool(cmd, "local")
o.ChangeCause = f.Command(cmd, false)
o.PrintObject = f.PrintObject
o.Cmd = cmd
Expand Down Expand Up @@ -178,6 +177,9 @@ func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args

func (o *ResourcesOptions) Validate() error {
var err error
if o.All && len(o.Selector) > 0 {
return fmt.Errorf("cannot set --all and --selector at the same time")
}
if len(o.Limits) == 0 && len(o.Requests) == 0 {
return fmt.Errorf("you must specify an update to requests or limits (in the form of --requests/--limits)")
}
Expand Down
1 change: 0 additions & 1 deletion pkg/kubectl/cmd/set/set_resources_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,6 @@ func TestSetResourcesRemote(t *testing.T) {
cmd.Flags().Set("output", "yaml")
opts := ResourcesOptions{
Out: buf,
Local: true,
Limits: "cpu=200m,memory=512Mi",
ContainerSelector: "*"}
err := opts.Complete(f, cmd, input.args)
Expand Down

0 comments on commit 989e4f8

Please sign in to comment.