Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Env Flag Filtering #16683

Merged
merged 9 commits into from Aug 18, 2022
Merged
2 changes: 1 addition & 1 deletion command/base.go
Expand Up @@ -589,7 +589,7 @@ func (f *FlagSets) Parse(args []string) error {
err := f.mainSet.Parse(args)

warnings := generateFlagWarnings(f.Args())
if warnings != "" {
if warnings != "" && Format(f.ui) != "json" {
maxcoulombe marked this conversation as resolved.
Show resolved Hide resolved
f.ui.Warn(warnings)
}

Expand Down
19 changes: 16 additions & 3 deletions command/base_helpers.go
Expand Up @@ -296,13 +296,26 @@ func parseFlagFile(raw string) (string, error) {
func generateFlagWarnings(args []string) string {
var trailingFlags []string
for _, arg := range args {
if strings.HasPrefix(arg, "-") {
trailingFlags = append(trailingFlags, arg)
if !strings.HasPrefix(arg, "-") {
continue
}

isGlobalFlag := false
trimmedArg, _, _ := strings.Cut(strings.TrimLeft(arg, "-"), "=")
for _, flag := range envFlags {
if trimmedArg == flag {
isGlobalFlag = true
}
}
if isGlobalFlag {
continue
}

trailingFlags = append(trailingFlags, arg)
}

if len(trailingFlags) > 0 {
return fmt.Sprintf("Flags must be provided before positional arguments. "+
return fmt.Sprintf("Command flags must be provided before positional arguments. "+
"The following arguments will not be parsed as flags: [%s]", strings.Join(trailingFlags, ","))
} else {
return ""
Expand Down
20 changes: 20 additions & 0 deletions command/base_helpers_test.go
Expand Up @@ -242,6 +242,26 @@ func TestArgWarnings(t *testing.T) {
[]string{"-a", "b"},
"-a",
},
{
[]string{globalFlagDetailed},
"",
},
{
[]string{"-" + globalFlagOutputCurlString + "=true"},
"",
},
{
[]string{"--" + globalFlagFormat + "=false"},
"",
},
{
[]string{"-x" + globalFlagDetailed},
"-x" + globalFlagDetailed,
},
{
[]string{"--x=" + globalFlagDetailed},
"--x=" + globalFlagDetailed,
},
}

for _, tc := range cases {
Expand Down
51 changes: 33 additions & 18 deletions command/main.go
Expand Up @@ -24,6 +24,17 @@ type VaultUI struct {
detailed bool
}

const (
globalFlagOutputCurlString = "output-curl-string"
globalFlagOutputPolicy = "output-policy"
globalFlagFormat = "format"
globalFlagDetailed = "detailed"
)

var envFlags = []string{
maxcoulombe marked this conversation as resolved.
Show resolved Hide resolved
globalFlagOutputCurlString, globalFlagOutputPolicy, globalFlagFormat, globalFlagDetailed,
}

// setupEnv parses args and may replace them and sets some env vars to known
// values based on format options
func setupEnv(args []string) (retArgs []string, format string, detailed bool, outputCurlString bool, outputPolicy bool) {
Expand All @@ -47,46 +58,36 @@ func setupEnv(args []string) (retArgs []string, format string, detailed bool, ou
break
}

if arg == "-output-curl-string" || arg == "--output-curl-string" {
if isEnvFlag(arg, globalFlagOutputCurlString) {
outputCurlString = true
continue
}

if arg == "-output-policy" || arg == "--output-policy" {
if isEnvFlag(arg, globalFlagOutputPolicy) {
outputPolicy = true
continue
}

// Parse a given flag here, which overrides the env var
if strings.HasPrefix(arg, "--format=") {
format = strings.TrimPrefix(arg, "--format=")
}
if strings.HasPrefix(arg, "-format=") {
format = strings.TrimPrefix(arg, "-format=")
if isEnvFlagWithValue(arg, globalFlagFormat) {
format = getEnvFlagValue(arg)
}
// For backwards compat, it could be specified without an equal sign
if arg == "-format" || arg == "--format" {
if isEnvFlag(arg, globalFlagFormat) {
nextArgFormat = true
}

// Parse a given flag here, which overrides the env var
if strings.HasPrefix(arg, "--detailed=") {
detailed, err = strconv.ParseBool(strings.TrimPrefix(arg, "--detailed="))
if err != nil {
detailed = false
}
haveDetailed = true
}
if strings.HasPrefix(arg, "-detailed=") {
detailed, err = strconv.ParseBool(strings.TrimPrefix(arg, "-detailed="))
if isEnvFlagWithValue(arg, globalFlagDetailed) {
detailed, err = strconv.ParseBool(getEnvFlagValue(globalFlagDetailed))
if err != nil {
detailed = false
}
haveDetailed = true
}
// For backwards compat, it could be specified without an equal sign to enable
// detailed output.
if arg == "-detailed" || arg == "--detailed" {
if isEnvFlag(arg, globalFlagDetailed) {
detailed = true
haveDetailed = true
}
Expand Down Expand Up @@ -115,6 +116,20 @@ func setupEnv(args []string) (retArgs []string, format string, detailed bool, ou
return args, format, detailed, outputCurlString, outputPolicy
}

func isEnvFlag(arg string, flag string) bool {
maxcoulombe marked this conversation as resolved.
Show resolved Hide resolved
return arg == "-"+flag || arg == "--"+flag
}

func isEnvFlagWithValue(arg string, flag string) bool {
maxcoulombe marked this conversation as resolved.
Show resolved Hide resolved
return strings.HasPrefix(arg, "--"+flag+"=") || strings.HasPrefix(arg, "-"+flag+"=")
}

func getEnvFlagValue(arg string) string {
maxcoulombe marked this conversation as resolved.
Show resolved Hide resolved
_, value, _ := strings.Cut(arg, "=")

return value
}

type RunOptions struct {
TokenHelper token.TokenHelper
Stdout io.Writer
Expand Down