diff --git a/utils/cobrautil/describe.go b/utils/cobrautil/describe.go index 52ee0454..8bdc96ed 100644 --- a/utils/cobrautil/describe.go +++ b/utils/cobrautil/describe.go @@ -36,6 +36,7 @@ func DescribeFlags(fs *pflag.FlagSet, format DescribeFormat) (string, error) { type FlagsDescriber struct { Format DescribeFormat + Unredacted bool ShowNotChanged bool ShowHidden bool } @@ -54,17 +55,24 @@ func (d FlagsDescriber) DescribeFlags(fs *pflag.FlagSet) (string, error) { return } - if f.Value.Type() == "bool" { - args[f.Name] = f.Value + val := f.Value + if d.Unredacted { + if v, ok := f.Value.(redactedValue); ok { + val = v.Unredacted() + } + } + + if val.Type() == "bool" { + args[f.Name] = val } else { - if sv, ok := f.Value.(sliceValue); ok { + if sv, ok := val.(sliceValue); ok { if d.Format == Plain { args[f.Name] = strings.Join(sv.GetSlice(), ",") } else { args[f.Name] = sv.GetSlice() } } else { - args[f.Name] = f.Value.String() + args[f.Name] = val.String() } } }) @@ -100,3 +108,7 @@ func (d FlagsDescriber) DescribeFlags(fs *pflag.FlagSet) (string, error) { type sliceValue interface { GetSlice() []string } + +type redactedValue interface { + Unredacted() pflag.Value +} diff --git a/utils/cobrautil/describe_test.go b/utils/cobrautil/describe_test.go index 48f75874..2ffb6337 100644 --- a/utils/cobrautil/describe_test.go +++ b/utils/cobrautil/describe_test.go @@ -23,6 +23,10 @@ d=false`, `key=false`, `key=val`, `key=false`, + `a=val +b=redacted`, + `a=val +b=val`, `a=val`, `key=false`, ``, @@ -36,6 +40,8 @@ func TestDescribeFlagsAsJSON(t *testing.T) { `{"key":false}`, `{"key":"val"}`, `{"key":false}`, + `{"a":"val","b":"redacted"}`, + `{"a":"val","b":"val"}`, `{"a":"val"}`, `{"key":false}`, `{}`, @@ -52,6 +58,10 @@ d: false`, `key: false`, `key: val`, `key: false`, + `a: val +b: redacted`, + `a: val +b: val`, `a: val`, `key: false`, `{}`, @@ -103,6 +113,31 @@ func testDescribeFlags(t *testing.T, f DescribeFormat, expected []string) { //no return fs }, }, + { + name: "value is redacted", + flags: func() *pflag.FlagSet { + fs := pflag.NewFlagSet("flags", pflag.ContinueOnError) + fs.String("a", "", "") + v := mockRedactedValue{fs.Lookup("a").Value} + fs.Var(&v, "b", "") + fs.Set("a", "val") + return fs + }, + }, + { + name: "value is unredacted", + flags: func() *pflag.FlagSet { + fs := pflag.NewFlagSet("flags", pflag.ContinueOnError) + fs.String("a", "", "") + v := mockRedactedValue{fs.Lookup("a").Value} + fs.Var(&v, "b", "") + fs.Set("a", "val") + return fs + }, + decorate: func(d *FlagsDescriber) { + d.Unredacted = true + }, + }, { name: "not changed is not shown", flags: func() *pflag.FlagSet { @@ -168,3 +203,15 @@ func testDescribeFlags(t *testing.T, f DescribeFormat, expected []string) { //no }) } } + +type mockRedactedValue struct { + pflag.Value +} + +func (v mockRedactedValue) Unredacted() pflag.Value { + return v.Value +} + +func (v mockRedactedValue) String() string { + return "redacted" +}