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

Add global -error-on-missing-key CLI argument #1434

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 21 additions & 10 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func NewCLI(out, err io.Writer) *CLI {
// status from the command.
func (cli *CLI) Run(args []string) int {
// Parse the flags
config, paths, dry, isVersion, err := cli.ParseFlags(args[1:])
config, paths, dry, errorOnMissingKey, isVersion, err := cli.ParseFlags(args[1:])
if err != nil {
if err == flag.ErrHelp {
fmt.Fprintf(cli.errStream, usage, version.Name)
Expand All @@ -82,7 +82,10 @@ func (cli *CLI) Run(args []string) int {
return logError(err, ExitCodeConfigError)
}

config.Finalize()
// Finalize the config by setting default values in place of nil.
// The default value for each template's errorOnMissingKey is
// the global errorOnMissingKey CLI argument
config.Finalize(errorOnMissingKey)

// Setup the config and logging
config, err = cli.setup(config)
Expand Down Expand Up @@ -137,7 +140,7 @@ func (cli *CLI) Run(args []string) int {
if err != nil {
return logError(err, ExitCodeConfigError)
}
config.Finalize()
config.Finalize(errorOnMissingKey)

// Load the new configuration from disk
config, err = cli.setup(config)
Expand Down Expand Up @@ -189,16 +192,16 @@ func (cli *CLI) stop() {
// small, but it also makes writing tests for parsing command line arguments
// much easier and cleaner.
func (cli *CLI) ParseFlags(args []string) (
*config.Config, []string, bool, bool, error,
*config.Config, []string, bool, bool, bool, error,
) {
var dry, isVersion bool
var dry, errorOnMissingKey, isVersion bool

c := config.DefaultConfig()

if s := os.Getenv("CT_LOCAL_CONFIG"); s != "" {
envConfig, err := config.Parse(s)
if err != nil {
return nil, nil, false, false, err
return nil, nil, false, false, false, err
}
c = c.Merge(envConfig)
}
Expand Down Expand Up @@ -332,6 +335,8 @@ func (cli *CLI) ParseFlags(args []string) (

flags.BoolVar(&dry, "dry", false, "")

flags.BoolVar(&errorOnMissingKey, "error-on-missing-key", false, "")

flags.Var((funcVar)(func(s string) error {
c.Exec.Enabled = config.Bool(true)
c.Exec.Command = config.String(s)
Expand Down Expand Up @@ -552,16 +557,16 @@ func (cli *CLI) ParseFlags(args []string) (

// If there was a parser error, stop
if err := flags.Parse(args); err != nil {
return nil, nil, false, false, err
return nil, nil, false, false, false, err
}

// Error if extra arguments are present
args = flags.Args()
if len(args) > 0 {
return nil, nil, false, false, fmt.Errorf("cli: extra args: %q", args)
return nil, nil, false, false, false, fmt.Errorf("cli: extra args: %q", args)
}

return c, configPaths, dry, isVersion, nil
return c, configPaths, dry, errorOnMissingKey, isVersion, nil
}

// loadConfigs loads the configuration from the list of paths. The optional
Expand All @@ -581,7 +586,7 @@ func loadConfigs(paths []string, o *config.Config) (*config.Config, error) {
}

finalC = finalC.Merge(o)
finalC.Finalize()
finalC.Finalize(false)
return finalC, nil
}

Expand Down Expand Up @@ -692,6 +697,12 @@ Options:
-dry
Print generated templates to stdout instead of rendering

-error-on-missing-key
For all templates, exit with an error when accessing a struct or map
field/key that does not exist. The default behavior will print
"<no value>" when accessing a field that does not exist. It is highly
recommended you specify this when retrieving secrets from Vault.

-exec=<command>
Enable exec mode to run as a supervisor-like process - the given command
will receive all signals provided to the parent process and will receive a
Expand Down
19 changes: 16 additions & 3 deletions cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,19 @@ func TestCLI_ParseFlags(t *testing.T) {
},
false,
},
{
"template_err_on_missing_key",
[]string{"-error-on-missing-key", "-template", "/tmp/in.tpl"},
&config.Config{
Templates: &config.TemplateConfigs{
&config.TemplateConfig{
Source: config.String("/tmp/in.tpl"),
ErrMissingKey: config.Bool(true),
},
},
},
false,
},
{
"vault-addr",
[]string{"-vault-addr", "vault_addr"},
Expand Down Expand Up @@ -706,16 +719,16 @@ func TestCLI_ParseFlags(t *testing.T) {
out := gatedio.NewByteBuffer()
cli := NewCLI(out, out)

a, _, _, _, err := cli.ParseFlags(tc.f)
a, _, _, errOnMissingKey, _, err := cli.ParseFlags(tc.f)
if (err != nil) != tc.err {
t.Fatal(err)
}
a.Finalize()
a.Finalize(errOnMissingKey)

var e *config.Config
if tc.e != nil {
e = config.DefaultConfig().Merge(tc.e)
e.Finalize()
e.Finalize(false)
}

if !reflect.DeepEqual(e, a) {
Expand Down
7 changes: 4 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ func Must(s string) *Config {
// configuration taking precedence.
func TestConfig(c *Config) *Config {
d := DefaultConfig().Merge(c)
d.Finalize()
d.Finalize(false)
return d
}

Expand Down Expand Up @@ -478,7 +478,8 @@ func DefaultConfig() *Config {
// intelligently tries to activate stanzas that should be "enabled" because
// data was given, but the user did not explicitly add "Enabled: true" to the
// configuration.
func (c *Config) Finalize() {
// The default for errorOnMissingKey is passed from upstream configuration.
func (c *Config) Finalize(errorOnMissingKey bool) {
if c == nil {
return
}
Expand Down Expand Up @@ -532,7 +533,7 @@ func (c *Config) Finalize() {
if c.Templates == nil {
c.Templates = DefaultTemplateConfigs()
}
c.Templates.Finalize()
c.Templates.Finalize(errorOnMissingKey)

if c.Vault == nil {
c.Vault = DefaultVaultConfig()
Expand Down
6 changes: 3 additions & 3 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1648,7 +1648,7 @@ func TestFinalize(t *testing.T) {

for i, tc := range cases {
t.Run(fmt.Sprintf("%d_%s", i, tc.name), func(t *testing.T) {
tc.test.Finalize()
tc.test.Finalize(false)
switch tc.isEqual {
case nil:
if !reflect.DeepEqual(tc.expt.Wait, tc.test.Wait) {
Expand Down Expand Up @@ -2130,14 +2130,14 @@ func TestDefaultConfig(t *testing.T) {
for i, tc := range cases {
t.Run(fmt.Sprintf("%d_%s", i, tc.env), func(t *testing.T) {
r := DefaultConfig().Merge(tc.e)
r.Finalize()
r.Finalize(false)

if err := os.Setenv(tc.env, tc.val); err != nil {
t.Fatal(err)
}
defer os.Unsetenv(tc.env)
c := DefaultConfig()
c.Finalize()
c.Finalize(false)

if !reflect.DeepEqual(r, c) {
t.Errorf("Config diff: %s", r.Diff(c))
Expand Down
8 changes: 4 additions & 4 deletions config/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ func (c *TemplateConfig) Merge(o *TemplateConfig) *TemplateConfig {

// Finalize ensures the configuration has no nil pointers and sets default
// values.
func (c *TemplateConfig) Finalize() {
func (c *TemplateConfig) Finalize(errorOnMissingKey bool) {
if c.Backup == nil {
c.Backup = Bool(false)
}
Expand All @@ -264,7 +264,7 @@ func (c *TemplateConfig) Finalize() {
}

if c.ErrMissingKey == nil {
c.ErrMissingKey = Bool(false)
c.ErrMissingKey = Bool(errorOnMissingKey)
}

if c.Exec == nil {
Expand Down Expand Up @@ -416,13 +416,13 @@ func (c *TemplateConfigs) Merge(o *TemplateConfigs) *TemplateConfigs {

// Finalize ensures the configuration has no nil pointers and sets default
// values.
func (c *TemplateConfigs) Finalize() {
func (c *TemplateConfigs) Finalize(errorOnMissingKey bool) {
if c == nil {
*c = *DefaultTemplateConfigs()
}

for _, t := range *c {
t.Finalize()
t.Finalize(errorOnMissingKey)
}
}

Expand Down
2 changes: 1 addition & 1 deletion config/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ func TestTemplateConfig_Finalize(t *testing.T) {

for i, tc := range cases {
t.Run(fmt.Sprintf("%d_%s", i, tc.name), func(t *testing.T) {
tc.i.Finalize()
tc.i.Finalize(false)
if !reflect.DeepEqual(tc.r, tc.i) {
t.Errorf("\nexp: %#v\nact: %#v", tc.r, tc.i)
}
Expand Down
2 changes: 1 addition & 1 deletion manager/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ func (r *Runner) runTemplate(tmpl *template.Template, runCtx *templateRunCtx) (*
func (r *Runner) init() error {
// Ensure default configuration values
r.config = config.DefaultConfig().Merge(r.config)
r.config.Finalize()
r.config.Finalize(false)

// Print the final config for debugging
result, err := json.Marshal(r.config)
Expand Down
20 changes: 10 additions & 10 deletions manager/runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ func TestRunner_Run(t *testing.T) {

c := config.TestConfig(tc.c)
c.Once = true
c.Finalize()
c.Finalize(false)

r, err := NewRunner(c, true)
if err != nil {
Expand Down Expand Up @@ -498,7 +498,7 @@ func TestRunner_Start(t *testing.T) {
},
},
})
c.Finalize()
c.Finalize(false)

r, err := NewRunner(c, false)
if err != nil {
Expand Down Expand Up @@ -541,7 +541,7 @@ func TestRunner_Start(t *testing.T) {
},
},
})
c.Finalize()
c.Finalize(false)

r, err := NewRunner(c, false)
if err != nil {
Expand Down Expand Up @@ -590,7 +590,7 @@ func TestRunner_Start(t *testing.T) {
},
},
})
c.Finalize()
c.Finalize(false)

r, err := NewRunner(c, false)
if err != nil {
Expand Down Expand Up @@ -640,7 +640,7 @@ func TestRunner_Start(t *testing.T) {
},
},
})
c.Finalize()
c.Finalize(false)

r, err := NewRunner(c, false)
if err != nil {
Expand Down Expand Up @@ -687,7 +687,7 @@ func TestRunner_Start(t *testing.T) {
},
},
})
c.Finalize()
c.Finalize(false)

r, err := NewRunner(c, false)
if err != nil {
Expand Down Expand Up @@ -744,7 +744,7 @@ func TestRunner_Start(t *testing.T) {
},
Once: true,
})
c.Finalize()
c.Finalize(false)

r, err := NewRunner(c, false)
if err != nil {
Expand Down Expand Up @@ -812,7 +812,7 @@ func TestRunner_Start(t *testing.T) {
},
},
})
c.Finalize()
c.Finalize(false)

r, err := NewRunner(c, false)
if err != nil {
Expand Down Expand Up @@ -890,7 +890,7 @@ func TestRunner_Start(t *testing.T) {
},
},
})
c.Finalize()
c.Finalize(false)

r, err := NewRunner(c, false)
if err != nil {
Expand Down Expand Up @@ -942,7 +942,7 @@ func TestRunner_Start(t *testing.T) {
},
Once: true,
})
c.Finalize()
c.Finalize(false)

r, err := NewRunner(c, true)
if err != nil {
Expand Down