diff --git a/pkg/kubectl/cmd/annotate.go b/pkg/kubectl/cmd/annotate.go index dd65ac0761c..cfd0e45722b 100644 --- a/pkg/kubectl/cmd/annotate.go +++ b/pkg/kubectl/cmd/annotate.go @@ -183,7 +183,7 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro return err } - changeCause := f.Command() + changeCause := f.Command(cmd, false) mapper, typer, err := f.UnstructuredObject() if err != nil { diff --git a/pkg/kubectl/cmd/apply.go b/pkg/kubectl/cmd/apply.go index 98085275df6..51f73320fc7 100644 --- a/pkg/kubectl/cmd/apply.go +++ b/pkg/kubectl/cmd/apply.go @@ -258,7 +258,7 @@ func RunApply(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opti } if cmdutil.ShouldRecord(cmd, info) { - if err := cmdutil.RecordChangeCause(info.Object, f.Command()); err != nil { + if err := cmdutil.RecordChangeCause(info.Object, f.Command(cmd, false)); err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } } @@ -313,7 +313,7 @@ func RunApply(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opti } if cmdutil.ShouldRecord(cmd, info) { - if patch, patchType, err := cmdutil.ChangeResourcePatch(info, f.Command()); err == nil { + if patch, patchType, err := cmdutil.ChangeResourcePatch(info, f.Command(cmd, true)); err == nil { if _, err = helper.Patch(info.Namespace, info.Name, patchType, patch); err != nil { glog.V(4).Infof("error recording reason: %v", err) } diff --git a/pkg/kubectl/cmd/autoscale.go b/pkg/kubectl/cmd/autoscale.go index 0fb1e726528..0c1a796bb34 100644 --- a/pkg/kubectl/cmd/autoscale.go +++ b/pkg/kubectl/cmd/autoscale.go @@ -156,7 +156,7 @@ func RunAutoscale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s return err } if cmdutil.ShouldRecord(cmd, hpa) { - if err := cmdutil.RecordChangeCause(hpa.Object, f.Command()); err != nil { + if err := cmdutil.RecordChangeCause(hpa.Object, f.Command(cmd, false)); err != nil { return err } object = hpa.Object diff --git a/pkg/kubectl/cmd/create.go b/pkg/kubectl/cmd/create.go index 90adab0346f..17d9089c536 100644 --- a/pkg/kubectl/cmd/create.go +++ b/pkg/kubectl/cmd/create.go @@ -154,7 +154,7 @@ func RunCreate(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opt } if cmdutil.ShouldRecord(cmd, info) { - if err := cmdutil.RecordChangeCause(info.Object, f.Command()); err != nil { + if err := cmdutil.RecordChangeCause(info.Object, f.Command(cmd, false)); err != nil { return cmdutil.AddSourceToErr("creating", info.Source, err) } } diff --git a/pkg/kubectl/cmd/edit.go b/pkg/kubectl/cmd/edit.go index a6de724706a..1b66b8938fe 100644 --- a/pkg/kubectl/cmd/edit.go +++ b/pkg/kubectl/cmd/edit.go @@ -536,7 +536,7 @@ func visitAnnotation(cmd *cobra.Command, f cmdutil.Factory, annotationVisitor re return err } if cmdutil.ShouldRecord(cmd, info) { - if err := cmdutil.RecordChangeCause(info.Object, f.Command()); err != nil { + if err := cmdutil.RecordChangeCause(info.Object, f.Command(cmd, false)); err != nil { return err } } diff --git a/pkg/kubectl/cmd/expose.go b/pkg/kubectl/cmd/expose.go index 3fac9d093c7..f5690fdea66 100644 --- a/pkg/kubectl/cmd/expose.go +++ b/pkg/kubectl/cmd/expose.go @@ -248,7 +248,7 @@ func RunExpose(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri return err } if cmdutil.ShouldRecord(cmd, info) { - if err := cmdutil.RecordChangeCause(object, f.Command()); err != nil { + if err := cmdutil.RecordChangeCause(object, f.Command(cmd, false)); err != nil { return err } } diff --git a/pkg/kubectl/cmd/label.go b/pkg/kubectl/cmd/label.go index 5c84b8babbb..caae1e93d00 100644 --- a/pkg/kubectl/cmd/label.go +++ b/pkg/kubectl/cmd/label.go @@ -178,7 +178,7 @@ func (o *LabelOptions) RunLabel(f cmdutil.Factory, cmd *cobra.Command) error { return err } - changeCause := f.Command() + changeCause := f.Command(cmd, false) mapper, typer, err := f.UnstructuredObject() if err != nil { diff --git a/pkg/kubectl/cmd/patch.go b/pkg/kubectl/cmd/patch.go index 6115279c391..f70b13e85a5 100644 --- a/pkg/kubectl/cmd/patch.go +++ b/pkg/kubectl/cmd/patch.go @@ -189,7 +189,7 @@ func RunPatch(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin infoCopy := *info infoCopy.Object = patchedObj infoCopy.VersionedObject = patchedObj - if patch, patchType, err := cmdutil.ChangeResourcePatch(&infoCopy, f.Command()); err == nil { + if patch, patchType, err := cmdutil.ChangeResourcePatch(&infoCopy, f.Command(cmd, true)); err == nil { if _, err = helper.Patch(info.Namespace, info.Name, patchType, patch); err != nil { glog.V(4).Infof("error recording reason: %v", err) } diff --git a/pkg/kubectl/cmd/replace.go b/pkg/kubectl/cmd/replace.go index e6383607b9d..c3d737279e3 100644 --- a/pkg/kubectl/cmd/replace.go +++ b/pkg/kubectl/cmd/replace.go @@ -151,7 +151,7 @@ func RunReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str } if cmdutil.ShouldRecord(cmd, info) { - if err := cmdutil.RecordChangeCause(info.Object, f.Command()); err != nil { + if err := cmdutil.RecordChangeCause(info.Object, f.Command(cmd, false)); err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } } @@ -272,7 +272,7 @@ func forceReplace(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []s } if cmdutil.ShouldRecord(cmd, info) { - if err := cmdutil.RecordChangeCause(info.Object, f.Command()); err != nil { + if err := cmdutil.RecordChangeCause(info.Object, f.Command(cmd, false)); err != nil { return cmdutil.AddSourceToErr("replacing", info.Source, err) } } diff --git a/pkg/kubectl/cmd/run.go b/pkg/kubectl/cmd/run.go index 2cbcadbcc93..01e4a01ceb5 100644 --- a/pkg/kubectl/cmd/run.go +++ b/pkg/kubectl/cmd/run.go @@ -585,7 +585,7 @@ func createGeneratedObject(f cmdutil.Factory, cmd *cobra.Command, generator kube return nil, "", nil, nil, err } if cmdutil.GetRecordFlag(cmd) || len(annotations[kubectl.ChangeCauseAnnotation]) > 0 { - if err := cmdutil.RecordChangeCause(obj, f.Command()); err != nil { + if err := cmdutil.RecordChangeCause(obj, f.Command(cmd, false)); err != nil { return nil, "", nil, nil, err } } diff --git a/pkg/kubectl/cmd/scale.go b/pkg/kubectl/cmd/scale.go index 2526dbf70bf..930233d6002 100644 --- a/pkg/kubectl/cmd/scale.go +++ b/pkg/kubectl/cmd/scale.go @@ -164,7 +164,7 @@ func RunScale(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []strin return err } if cmdutil.ShouldRecord(cmd, info) { - patchBytes, patchType, err := cmdutil.ChangeResourcePatch(info, f.Command()) + patchBytes, patchType, err := cmdutil.ChangeResourcePatch(info, f.Command(cmd, true)) if err != nil { return err } diff --git a/pkg/kubectl/cmd/set/set_image.go b/pkg/kubectl/cmd/set/set_image.go index f4cdd75c413..327652ec293 100644 --- a/pkg/kubectl/cmd/set/set_image.go +++ b/pkg/kubectl/cmd/set/set_image.go @@ -119,7 +119,7 @@ func (o *ImageOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st o.Encoder = f.JSONEncoder() o.ShortOutput = cmdutil.GetFlagString(cmd, "output") == "name" o.Record = cmdutil.GetRecordFlag(cmd) - o.ChangeCause = f.Command() + o.ChangeCause = f.Command(cmd, false) o.PrintObject = f.PrintObject o.DryRun = cmdutil.GetDryRunFlag(cmd) o.Output = cmdutil.GetFlagString(cmd, "output") diff --git a/pkg/kubectl/cmd/set/set_resources.go b/pkg/kubectl/cmd/set/set_resources.go index 4edb588c06c..2525a10fc20 100644 --- a/pkg/kubectl/cmd/set/set_resources.go +++ b/pkg/kubectl/cmd/set/set_resources.go @@ -131,7 +131,7 @@ func (o *ResourcesOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args o.Encoder = f.JSONEncoder() o.ShortOutput = cmdutil.GetFlagString(cmd, "output") == "name" o.Record = cmdutil.GetRecordFlag(cmd) - o.ChangeCause = f.Command() + o.ChangeCause = f.Command(cmd, false) o.PrintObject = f.PrintObject o.Cmd = cmd diff --git a/pkg/kubectl/cmd/set/set_selector.go b/pkg/kubectl/cmd/set/set_selector.go index ea486b87128..00a67c9ca39 100644 --- a/pkg/kubectl/cmd/set/set_selector.go +++ b/pkg/kubectl/cmd/set/set_selector.go @@ -112,7 +112,7 @@ func (o *SelectorOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ return err } - o.changeCause = f.Command() + o.changeCause = f.Command(cmd, false) mapper, _ := f.Object() o.mapper = mapper o.encoder = f.JSONEncoder() diff --git a/pkg/kubectl/cmd/testing/fake.go b/pkg/kubectl/cmd/testing/fake.go index 3ec2be83235..c5c5cbf2596 100644 --- a/pkg/kubectl/cmd/testing/fake.go +++ b/pkg/kubectl/cmd/testing/fake.go @@ -437,7 +437,7 @@ func (f *FakeFactory) EditorEnvs() []string { func (f *FakeFactory) PrintObjectSpecificMessage(obj runtime.Object, out io.Writer) { } -func (f *FakeFactory) Command() string { +func (f *FakeFactory) Command(*cobra.Command, bool) string { return f.tf.Command } @@ -638,7 +638,7 @@ func (f *fakeAPIFactory) DefaultNamespace() (string, bool, error) { return f.tf.Namespace, false, f.tf.Err } -func (f *fakeAPIFactory) Command() string { +func (f *fakeAPIFactory) Command(*cobra.Command, bool) string { return f.tf.Command } diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go index 6e213a2038b..e086a1d9cb6 100644 --- a/pkg/kubectl/cmd/util/factory.go +++ b/pkg/kubectl/cmd/util/factory.go @@ -130,7 +130,7 @@ type ClientAccessFactory interface { FlagSet() *pflag.FlagSet // Command will stringify and return all environment arguments ie. a command run by a client // using the factory. - Command() string + Command(cmd *cobra.Command, showSecrets bool) string // BindFlags adds any flags that are common to all kubectl sub commands. BindFlags(flags *pflag.FlagSet) // BindExternalFlags adds any flags defined by external projects (not part of pflags) diff --git a/pkg/kubectl/cmd/util/factory_client_access.go b/pkg/kubectl/cmd/util/factory_client_access.go index 4c271c8ace2..83359aa52fd 100644 --- a/pkg/kubectl/cmd/util/factory_client_access.go +++ b/pkg/kubectl/cmd/util/factory_client_access.go @@ -330,14 +330,35 @@ func (f *ring0Factory) FlagSet() *pflag.FlagSet { return f.flags } -// TODO: We need to filter out stuff like secrets. -func (f *ring0Factory) Command() string { +// Set showSecrets false to filter out stuff like secrets. +func (f *ring0Factory) Command(cmd *cobra.Command, showSecrets bool) string { if len(os.Args) == 0 { return "" } + + flags := "" + parseFunc := func(flag *pflag.Flag, value string) error { + flags = flags + " --" + flag.Name + if set, ok := flag.Annotations["classified"]; showSecrets || !ok || len(set) == 0 { + flags = flags + "=" + value + } else { + flags = flags + "=CLASSIFIED" + } + return nil + } + var err error + err = cmd.Flags().ParseAll(os.Args[1:], parseFunc) + if err != nil || !cmd.Flags().Parsed() { + return "" + } + + args := "" + if arguments := cmd.Flags().Args(); len(arguments) > 0 { + args = " " + strings.Join(arguments, " ") + } + base := filepath.Base(os.Args[0]) - args := append([]string{base}, os.Args[1:]...) - return strings.Join(args, " ") + return base + args + flags } func (f *ring0Factory) BindFlags(flags *pflag.FlagSet) { diff --git a/staging/src/k8s.io/client-go/tools/clientcmd/overrides.go b/staging/src/k8s.io/client-go/tools/clientcmd/overrides.go index 8622981a9e7..f18aa6a4ae2 100644 --- a/staging/src/k8s.io/client-go/tools/clientcmd/overrides.go +++ b/staging/src/k8s.io/client-go/tools/clientcmd/overrides.go @@ -85,16 +85,23 @@ type FlagInfo struct { Description string } +// AddSecretAnnotation add secret flag to Annotation. +func (f FlagInfo) AddSecretAnnotation(flags *pflag.FlagSet) FlagInfo { + flags.SetAnnotation(f.LongName, "classified", []string{"true"}) + return f +} + // BindStringFlag binds the flag based on the provided info. If LongName == "", nothing is registered -func (f FlagInfo) BindStringFlag(flags *pflag.FlagSet, target *string) { +func (f FlagInfo) BindStringFlag(flags *pflag.FlagSet, target *string) FlagInfo { // you can't register a flag without a long name if len(f.LongName) > 0 { flags.StringVarP(target, f.LongName, f.ShortName, f.Default, f.Description) } + return f } // BindBoolFlag binds the flag based on the provided info. If LongName == "", nothing is registered -func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) { +func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) FlagInfo { // you can't register a flag without a long name if len(f.LongName) > 0 { // try to parse Default as a bool. If it fails, assume false @@ -105,6 +112,7 @@ func (f FlagInfo) BindBoolFlag(flags *pflag.FlagSet, target *bool) { flags.BoolVarP(target, f.LongName, f.ShortName, boolVal, f.Description) } + return f } const ( @@ -180,12 +188,12 @@ func BindOverrideFlags(overrides *ConfigOverrides, flags *pflag.FlagSet, flagNam // BindAuthInfoFlags is a convenience method to bind the specified flags to their associated variables func BindAuthInfoFlags(authInfo *clientcmdapi.AuthInfo, flags *pflag.FlagSet, flagNames AuthOverrideFlags) { - flagNames.ClientCertificate.BindStringFlag(flags, &authInfo.ClientCertificate) - flagNames.ClientKey.BindStringFlag(flags, &authInfo.ClientKey) - flagNames.Token.BindStringFlag(flags, &authInfo.Token) - flagNames.Impersonate.BindStringFlag(flags, &authInfo.Impersonate) - flagNames.Username.BindStringFlag(flags, &authInfo.Username) - flagNames.Password.BindStringFlag(flags, &authInfo.Password) + flagNames.ClientCertificate.BindStringFlag(flags, &authInfo.ClientCertificate).AddSecretAnnotation(flags) + flagNames.ClientKey.BindStringFlag(flags, &authInfo.ClientKey).AddSecretAnnotation(flags) + flagNames.Token.BindStringFlag(flags, &authInfo.Token).AddSecretAnnotation(flags) + flagNames.Impersonate.BindStringFlag(flags, &authInfo.Impersonate).AddSecretAnnotation(flags) + flagNames.Username.BindStringFlag(flags, &authInfo.Username).AddSecretAnnotation(flags) + flagNames.Password.BindStringFlag(flags, &authInfo.Password).AddSecretAnnotation(flags) } // BindClusterFlags is a convenience method to bind the specified flags to their associated variables