From af52beda260257e81cc9e19e9e5108b682ee93d6 Mon Sep 17 00:00:00 2001 From: "Julian V. Modesto" Date: Sun, 15 Dec 2019 18:29:27 -0500 Subject: [PATCH] Extend --dry-run to support string values. * Extend --dry-run to support string values for dry run strategies 'client', 'server', and 'none' * Ensure --dry-run is set and accessed via cmdutil * Deprecate --dry-run (unset), --dry-run=true, and --dry-run=false --- .../kubectl/pkg/cmd/annotate/annotate.go | 2 +- .../src/k8s.io/kubectl/pkg/cmd/apply/apply.go | 7 +- .../pkg/cmd/apply/apply_set_last_applied.go | 2 +- .../kubectl/pkg/cmd/autoscale/autoscale.go | 2 +- .../k8s.io/kubectl/pkg/cmd/create/create.go | 4 +- .../kubectl/pkg/cmd/create/create_cronjob.go | 2 +- .../kubectl/pkg/cmd/create/create_job.go | 2 +- .../kubectl/pkg/cmd/create/create_role.go | 2 +- .../src/k8s.io/kubectl/pkg/cmd/drain/drain.go | 2 +- .../k8s.io/kubectl/pkg/cmd/expose/expose.go | 2 +- .../src/k8s.io/kubectl/pkg/cmd/label/label.go | 2 +- .../src/k8s.io/kubectl/pkg/cmd/patch/patch.go | 2 +- .../pkg/cmd/rollingupdate/rollingupdate.go | 2 +- .../kubectl/pkg/cmd/rollout/rollout_undo.go | 2 +- staging/src/k8s.io/kubectl/pkg/cmd/run/run.go | 2 +- .../src/k8s.io/kubectl/pkg/cmd/set/set_env.go | 2 +- .../k8s.io/kubectl/pkg/cmd/set/set_image.go | 2 +- .../kubectl/pkg/cmd/set/set_resources.go | 2 +- .../kubectl/pkg/cmd/set/set_selector.go | 2 +- .../kubectl/pkg/cmd/set/set_serviceaccount.go | 2 +- .../k8s.io/kubectl/pkg/cmd/set/set_subject.go | 2 +- .../k8s.io/kubectl/pkg/cmd/util/helpers.go | 73 ++++++++++++++++++- 22 files changed, 95 insertions(+), 27 deletions(-) diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go b/staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go index 604659283d7..13766b73cda 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/annotate/annotate.go @@ -164,7 +164,7 @@ func (o *AnnotateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ } o.outputFormat = cmdutil.GetFlagString(cmd, "output") - o.dryrun = cmdutil.GetDryRunFlag(cmd) + o.dryrun = cmdutil.GetClientSideDryRun(cmd) if o.dryrun { o.PrintFlags.Complete("%s (dry run)") diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go b/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go index 5a81e0a5e48..0deb5a8e724 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go @@ -192,8 +192,9 @@ func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions cmd.Flags().BoolVar(&o.All, "all", o.All, "Select all resources in the namespace of the specified resource types.") cmd.Flags().StringArrayVar(&o.PruneWhitelist, "prune-whitelist", o.PruneWhitelist, "Overwrite the default whitelist with for --prune") cmd.Flags().BoolVar(&o.OpenAPIPatch, "openapi-patch", o.OpenAPIPatch, "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.") - cmd.Flags().BoolVar(&o.ServerDryRun, "server-dry-run", o.ServerDryRun, "If true, request will be sent to server with dry-run flag, which means the modifications won't be persisted. This is an alpha feature and flag.") - cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it. Warning: --dry-run cannot accurately output the result of merging the local manifest and the server-side data. Use --server-dry-run to get the merged result instead.") + cmd.Flags().BoolVar(&o.ServerDryRun, "server-dry-run", o.ServerDryRun, "If true, request will be sent to server with dry-run flag, which means the modifications won't be persisted.") + cmd.Flags().MarkDeprecated("server-dry-run", "--server-dry-run is deprecated and can be replaced with --dry-run=server.") + cmdutil.AddDryRunFlag(cmd) cmdutil.AddServerSideApplyFlags(cmd) // apply subcommands @@ -210,7 +211,7 @@ func (o *ApplyOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { o.ServerSideApply = cmdutil.GetServerSideApplyFlag(cmd) o.ForceConflicts = cmdutil.GetForceConflictsFlag(cmd) o.FieldManager = cmdutil.GetFieldManagerFlag(cmd) - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) o.DynamicClient, err = f.DynamicClient() if err != nil { return err diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply_set_last_applied.go b/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply_set_last_applied.go index 6dfdd7c2b14..7c6eefa42fe 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply_set_last_applied.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/apply/apply_set_last_applied.go @@ -118,7 +118,7 @@ func NewCmdApplySetLastApplied(f cmdutil.Factory, ioStreams genericclioptions.IO // Complete populates dry-run and output flag options. func (o *SetLastAppliedOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { - o.dryRun = cmdutil.GetDryRunFlag(cmd) + o.dryRun = cmdutil.GetClientSideDryRun(cmd) o.output = cmdutil.GetFlagString(cmd, "output") o.shortOutput = o.output == "name" diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/autoscale/autoscale.go b/staging/src/k8s.io/kubectl/pkg/cmd/autoscale/autoscale.go index 9283b733513..604d63af647 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/autoscale/autoscale.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/autoscale/autoscale.go @@ -134,7 +134,7 @@ func NewCmdAutoscale(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) * // Complete verifies command line arguments and loads data from the command environment func (o *AutoscaleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { var err error - o.dryRun = cmdutil.GetFlagBool(cmd, "dry-run") + o.dryRun = cmdutil.GetClientSideDryRun(cmd) o.createAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag) o.builder = f.NewBuilder() discoveryClient, err := f.ToDiscoveryClient() diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create.go index 74e7ac9c8c6..fea4f363aa1 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create.go @@ -191,7 +191,7 @@ func (o *CreateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { return err } - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) if o.DryRun { o.PrintFlags.Complete("%s (dry run)") @@ -360,7 +360,7 @@ func (o *CreateSubcommandOptions) Complete(f cmdutil.Factory, cmd *cobra.Command o.Name = name o.StructuredGenerator = generator - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) o.CreateAnnotation = cmdutil.GetFlagBool(cmd, cmdutil.ApplyAnnotationsFlag) if o.DryRun { diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_cronjob.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_cronjob.go index 79988c7ac9b..1727b596ece 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_cronjob.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_cronjob.go @@ -133,7 +133,7 @@ func (o *CreateCronJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, a o.Builder = f.NewBuilder() o.Cmd = cmd - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) if o.DryRun { o.PrintFlags.Complete("%s (dry run)") } diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job.go index 0dda881417a..2213670421c 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_job.go @@ -132,7 +132,7 @@ func (o *CreateJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args o.Builder = f.NewBuilder() o.Cmd = cmd - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) if o.DryRun { o.PrintFlags.Complete("%s (dry run)") } diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_role.go b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_role.go index c080a2ee7f0..0a23e417044 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/create/create_role.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/create/create_role.go @@ -235,7 +235,7 @@ func (o *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args return err } - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) o.OutputFormat = cmdutil.GetFlagString(cmd, "output") if o.DryRun { diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/drain/drain.go b/staging/src/k8s.io/kubectl/pkg/cmd/drain/drain.go index a0d8f5bc150..5712fff5a93 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/drain/drain.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/drain/drain.go @@ -211,7 +211,7 @@ func (o *DrainCmdOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ return cmdutil.UsageErrorf(cmd, "error: cannot specify both a node name and a --selector option") } - o.drainer.DryRun = cmdutil.GetDryRunFlag(cmd) + o.drainer.DryRun = cmdutil.GetClientSideDryRun(cmd) if o.drainer.Client, err = f.KubernetesClientSet(); err != nil { return err diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/expose/expose.go b/staging/src/k8s.io/kubectl/pkg/cmd/expose/expose.go index bf010ded33f..942d8b0f8d9 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/expose/expose.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/expose/expose.go @@ -167,7 +167,7 @@ func NewCmdExposeService(f cmdutil.Factory, streams genericclioptions.IOStreams) } func (o *ExposeServiceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) if o.DryRun { o.PrintFlags.Complete("%s (dry run)") diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/label/label.go b/staging/src/k8s.io/kubectl/pkg/cmd/label/label.go index 6a5ce303fad..883a5fb1f28 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/label/label.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/label/label.go @@ -164,7 +164,7 @@ func (o *LabelOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st } o.outputFormat = cmdutil.GetFlagString(cmd, "output") - o.dryrun = cmdutil.GetDryRunFlag(cmd) + o.dryrun = cmdutil.GetClientSideDryRun(cmd) o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) { o.PrintFlags.NamePrintFlags.Operation = operation diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/patch/patch.go b/staging/src/k8s.io/kubectl/pkg/cmd/patch/patch.go index e44ebdca2a5..8616a85d3c7 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/patch/patch.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/patch/patch.go @@ -139,7 +139,7 @@ func (o *PatchOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st } o.outputFormat = cmdutil.GetFlagString(cmd, "output") - o.dryRun = cmdutil.GetFlagBool(cmd, "dry-run") + o.dryRun = cmdutil.GetClientSideDryRun(cmd) o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) { o.PrintFlags.NamePrintFlags.Operation = operation diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/rollingupdate/rollingupdate.go b/staging/src/k8s.io/kubectl/pkg/cmd/rollingupdate/rollingupdate.go index d4adc6e9b4a..b1ccd8ac9fd 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/rollingupdate/rollingupdate.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/rollingupdate/rollingupdate.go @@ -195,7 +195,7 @@ func (o *RollingUpdateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, a if len(args) > 0 { o.OldName = args[0] } - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) o.OutputFormat = cmdutil.GetFlagString(cmd, "output") o.KeepOldName = len(args) == 1 o.ShouldValidate = cmdutil.GetFlagBool(cmd, "validate") diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_undo.go b/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_undo.go index 8631a999cbc..802d6e161c4 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_undo.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/rollout/rollout_undo.go @@ -104,7 +104,7 @@ func NewCmdRolloutUndo(f cmdutil.Factory, streams genericclioptions.IOStreams) * // Complete completes al the required options func (o *UndoOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { o.Resources = args - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) var err error if o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace(); err != nil { diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/run/run.go b/staging/src/k8s.io/kubectl/pkg/cmd/run/run.go index 3e0b2fda17c..849f236d335 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/run/run.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/run/run.go @@ -217,7 +217,7 @@ func (o *RunOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { } o.ArgsLenAtDash = cmd.ArgsLenAtDash() - o.DryRun = cmdutil.GetFlagBool(cmd, "dry-run") + o.DryRun = cmdutil.GetClientSideDryRun(cmd) attachFlag := cmd.Flags().Lookup("attach") if !attachFlag.Changed && o.Interactive { diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_env.go b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_env.go index cb84c729647..c51b2a429f0 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_env.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_env.go @@ -216,7 +216,7 @@ func (o *EnvOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri o.updatePodSpecForObject = polymorphichelpers.UpdatePodSpecForObjectFn o.output = cmdutil.GetFlagString(cmd, "output") - o.dryRun = cmdutil.GetDryRunFlag(cmd) + o.dryRun = cmdutil.GetClientSideDryRun(cmd) if o.dryRun { // TODO(juanvallejo): This can be cleaned up even further by creating diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_image.go b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_image.go index 22c8d66f1ce..335ded07067 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_image.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_image.go @@ -138,7 +138,7 @@ func (o *SetImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ } o.UpdatePodSpecForObject = polymorphichelpers.UpdatePodSpecForObjectFn - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) o.Output = cmdutil.GetFlagString(cmd, "output") o.ResolveImage = resolveImageFunc diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_resources.go b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_resources.go index 34011e92058..26d175264fd 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_resources.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_resources.go @@ -150,7 +150,7 @@ func (o *SetResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, ar o.UpdatePodSpecForObject = polymorphichelpers.UpdatePodSpecForObjectFn o.Output = cmdutil.GetFlagString(cmd, "output") - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) if o.DryRun { o.PrintFlags.Complete("%s (dry run)") diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_selector.go b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_selector.go index d7fecdff7ed..93fb17aa158 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_selector.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_selector.go @@ -129,7 +129,7 @@ func (o *SetSelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg return err } - o.dryrun = cmdutil.GetDryRunFlag(cmd) + o.dryrun = cmdutil.GetClientSideDryRun(cmd) o.resources, o.selector, err = getResourcesAndSelector(args) if err != nil { diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_serviceaccount.go b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_serviceaccount.go index f826bf8a20a..be31b354e7f 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_serviceaccount.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_serviceaccount.go @@ -128,7 +128,7 @@ func (o *SetServiceAccountOptions) Complete(f cmdutil.Factory, cmd *cobra.Comman } o.shortOutput = cmdutil.GetFlagString(cmd, "output") == "name" - o.dryRun = cmdutil.GetDryRunFlag(cmd) + o.dryRun = cmdutil.GetClientSideDryRun(cmd) o.output = cmdutil.GetFlagString(cmd, "output") o.updatePodSpecForObject = polymorphichelpers.UpdatePodSpecForObjectFn diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_subject.go b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_subject.go index 41abc7092f0..30b7486ece0 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/set/set_subject.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/set/set_subject.go @@ -120,7 +120,7 @@ func NewCmdSubject(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobr // Complete completes all required options func (o *SubjectOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { o.Output = cmdutil.GetFlagString(cmd, "output") - o.DryRun = cmdutil.GetDryRunFlag(cmd) + o.DryRun = cmdutil.GetClientSideDryRun(cmd) if o.DryRun { o.PrintFlags.Complete("%s (dry run)") diff --git a/staging/src/k8s.io/kubectl/pkg/cmd/util/helpers.go b/staging/src/k8s.io/kubectl/pkg/cmd/util/helpers.go index c6a655a85d7..daee405272d 100644 --- a/staging/src/k8s.io/kubectl/pkg/cmd/util/helpers.go +++ b/staging/src/k8s.io/kubectl/pkg/cmd/util/helpers.go @@ -23,6 +23,7 @@ import ( "io" "net/url" "os" + "strconv" "strings" "time" @@ -409,7 +410,12 @@ func AddKustomizeFlag(flags *pflag.FlagSet, value *string) { // AddDryRunFlag adds dry-run flag to a command. Usually used by mutations. func AddDryRunFlag(cmd *cobra.Command) { - cmd.Flags().Bool("dry-run", false, "If true, only print the object that would be sent, without sending it.") + cmd.Flags().String( + "dry-run", + "none", + `Must be "none", "server", or "client". If client strategy, only print the object that would be sent, without sending it. If server strategy, submit server-side request without persisting the resource.`, + ) + cmd.Flags().Lookup("dry-run").NoOptDefVal = "unchanged" } func AddServerSideApplyFlags(cmd *cobra.Command) { @@ -498,8 +504,69 @@ func GetFieldManagerFlag(cmd *cobra.Command) string { return GetFlagString(cmd, "field-manager") } -func GetDryRunFlag(cmd *cobra.Command) bool { - return GetFlagBool(cmd, "dry-run") +type DryRunStrategy int + +const ( + DryRunNone DryRunStrategy = iota + DryRunClient + DryRunServer +) + +// TODO(julianvmodesto): remove GetClientSideDryRun once we support +// server-side dry-run in all commands +func GetClientSideDryRun(cmd *cobra.Command) bool { + dryRunStrategy, err := GetDryRunStrategy(cmd) + if err != nil { + klog.Fatalf("error accessing --dry-run flag for command %s: %v", cmd.Name(), err) + } + if dryRunStrategy == DryRunServer { + klog.Fatalf("--dry-run=server for command %s is not supported yet", cmd.Name()) + } + return dryRunStrategy == DryRunClient +} + +func GetDryRunStrategy(cmd *cobra.Command) (DryRunStrategy, error) { + var dryRunFlag = GetFlagString(cmd, "dry-run") + b, err := strconv.ParseBool(dryRunFlag) + // The flag is not a boolean + if err != nil { + switch dryRunFlag { + case cmd.Flag("dry-run").NoOptDefVal: + klog.Warning(`--dry-run is deprecated and can be replaced with --dry-run=client.`) + return DryRunClient, nil + case "client": + return DryRunClient, nil + case "server": + return DryRunServer, nil + case "none": + return DryRunNone, nil + default: + return DryRunNone, fmt.Errorf(`Invalid dry-run value (%v). Must be "none", "server", or "client".`, dryRunFlag) + } + } + // The flag was a boolean + if b { + klog.Warningf(`--dry-run=%v is deprecated (boolean value) and can be replaced with --dry-run=%s.`, dryRunFlag, "client") + return DryRunClient, nil + } + klog.Warningf(`--dry-run=%v is deprecated (boolean value) and can be replaced with --dry-run=%s.`, dryRunFlag, "none") + return DryRunNone, nil +} + +// PrintFlagsWithDryRunStrategy sets a success message at print time for the dry run strategy +// +// TODO(juanvallejo): This can be cleaned up even further by creating +// a PrintFlags struct that binds the --dry-run flag, and whose +// ToPrinter method returns a printer that understands how to print +// this success message. +func PrintFlagsWithDryRunStrategy(printFlags *genericclioptions.PrintFlags, dryRunStrategy DryRunStrategy) *genericclioptions.PrintFlags { + switch dryRunStrategy { + case DryRunClient: + printFlags.Complete("%s (dry run)") + case DryRunServer: + printFlags.Complete("%s (server dry run)") + } + return printFlags } // GetResourcesAndPairs retrieves resources and "KEY=VALUE or KEY-" pair args from given args