From ab38c1bbea5bf7c01066469302600fa4c3d2f304 Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Fri, 30 Aug 2019 08:15:50 -0400 Subject: [PATCH] cli: split -dev and -dev-connect flags --- CHANGELOG.md | 2 +- command/agent/command.go | 22 +++++--- command/agent/config.go | 55 ++++++++----------- command/agent/config_test.go | 31 ++++++----- .../source/docs/commands/agent.html.md.erb | 4 +- 5 files changed, 56 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fac2b68b2..11aa24cae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,9 @@ IMPROVEMENTS: * core: Added host volumes [[GH-6100](https://github.com/hashicorp/nomad/pull/6100)] * agent: Allowed the job GC interval to be configured [[GH-5978](https://github.com/hashicorp/nomad/issues/5978)] - * agent: Added `-dev=connect` parameter to support running in dev mode with Consul Connect [[GH-6126](https://github.com/hashicorp/nomad/issues/6126)] * agent: Added `log_level` to be reloaded on SIGHUP [[GH-5996](https://github.com/hashicorp/nomad/pull/5996)] * api: Added follow parameter to file streaming endpoint to support older browsers [[GH-6049](https://github.com/hashicorp/nomad/issues/6049)] + * cli: Added `-dev-connect` parameter to support running in dev mode with Consul Connect [[GH-6126](https://github.com/hashicorp/nomad/issues/6126)] * metrics: Add job status (pending, running, dead) metrics [[GH-6003](https://github.com/hashicorp/nomad/issues/6003)] * ui: Added creation time to evaluations table [[GH-6050](https://github.com/hashicorp/nomad/pull/6050)] diff --git a/command/agent/command.go b/command/agent/command.go index ad7047b7a..49d63c80b 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -77,10 +77,10 @@ func (c *Command) readConfig() *Config { flags.Usage = func() { c.Ui.Error(c.Help()) } // Role options - flags.Var((flaghelper.FuncOptionalStringVar)(func(s string) (err error) { - dev, err = newDevModeConfig(s) - return err - }), "dev", "") + var devMode bool + var devConnectMode bool + flags.BoolVar(&devMode, "dev", false, "") + flags.BoolVar(&devConnectMode, "dev-connect", false, "") flags.BoolVar(&cmdConfig.Server.Enabled, "server", false, "") flags.BoolVar(&cmdConfig.Client.Enabled, "client", false, "") @@ -206,6 +206,11 @@ func (c *Command) readConfig() *Config { } // Load the configuration + dev, err := newDevModeConfig(devMode, devConnectMode) + if err != nil { + c.Ui.Error(err.Error()) + return nil + } var config *Config if dev != nil { config = DevConfig(dev) @@ -483,6 +488,7 @@ func (c *Command) AutocompleteFlags() complete.Flags { return map[string]complete.Predictor{ "-dev": complete.PredictNothing, + "-dev-connect": complete.PredictNothing, "-server": complete.PredictNothing, "-client": complete.PredictNothing, "-bootstrap-expect": complete.PredictAnything, @@ -1170,10 +1176,10 @@ General Options (clients and servers): agent in this mode, but you may pass an optional comma-separated list of mode configurations: - -dev=connect - Start the agent in development mode, but bind to a public network - interface rather than localhost for using Consul Connect. This - mode is supported only on Linux as root. + -dev-connect + Start the agent in development mode, but bind to a public network + interface rather than localhost for using Consul Connect. This + mode is supported only on Linux as root. Server Options: diff --git a/command/agent/config.go b/command/agent/config.go index a20912e38..69a14d766 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -670,9 +670,9 @@ func (r *Resources) CanParseReserved() error { return err } -// devModeConfig holds the config for the -dev flag +// devModeConfig holds the config for the -dev and -dev-connect flags type devModeConfig struct { - // mode flags are set at the command line via -dev= + // mode flags are set at the command line via -dev and -dev-connect defaultMode bool connectMode bool @@ -681,38 +681,31 @@ type devModeConfig struct { } // newDevModeConfig parses the optional string value of the -dev flag -func newDevModeConfig(s string) (*devModeConfig, error) { - if s == "" { - return nil, nil // no -dev flag +func newDevModeConfig(devMode, connectMode bool) (*devModeConfig, error) { + if !devMode && !connectMode { + return nil, nil } mode := &devModeConfig{} - modeFlags := strings.Split(s, ",") - for _, modeFlag := range modeFlags { - switch modeFlag { - case "true": // -dev flag with no params - mode.defaultMode = true - case "connect": - if runtime.GOOS != "linux" { - // strictly speaking -dev=connect only binds to the - // non-localhost interface, but given its purpose - // is to support a feature with network namespaces - // we'll return an error here rather than let the agent - // come up and fail unexpectedly to run jobs - return nil, fmt.Errorf("-dev=connect is only supported on linux.") - } - u, err := user.Current() - if err != nil { - return nil, fmt.Errorf( - "-dev=connect uses network namespaces and is only supported for root: %v", err) - } - if u.Uid != "0" { - return nil, fmt.Errorf( - "-dev=connect uses network namespaces and is only supported for root.") - } - mode.connectMode = true - default: - return nil, fmt.Errorf("invalid -dev flag: %q", s) + mode.defaultMode = devMode + if connectMode { + if runtime.GOOS != "linux" { + // strictly speaking -dev-connect only binds to the + // non-localhost interface, but given its purpose + // is to support a feature with network namespaces + // we'll return an error here rather than let the agent + // come up and fail unexpectedly to run jobs + return nil, fmt.Errorf("-dev-connect is only supported on linux.") } + u, err := user.Current() + if err != nil { + return nil, fmt.Errorf( + "-dev-connect uses network namespaces and is only supported for root: %v", err) + } + if u.Uid != "0" { + return nil, fmt.Errorf( + "-dev-connect uses network namespaces and is only supported for root.") + } + mode.connectMode = true } err := mode.networkConfig() if err != nil { diff --git a/command/agent/config_test.go b/command/agent/config_test.go index 2f9e99d71..0813d5a76 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -625,40 +625,41 @@ func TestConfig_Listener(t *testing.T) { func TestConfig_DevModeFlag(t *testing.T) { cases := []struct { - flag string + dev bool + connect bool expected *devModeConfig expectedErr string }{} if runtime.GOOS != "linux" { cases = []struct { - flag string + dev bool + connect bool expected *devModeConfig expectedErr string }{ - {"", nil, ""}, - {"true", &devModeConfig{defaultMode: true, connectMode: false}, ""}, - {"true,connect", nil, "-dev=connect is only supported on linux"}, - {"connect", nil, "-dev=connect is only supported on linux"}, - {"xxx", nil, "invalid -dev flag"}, + {false, false, nil, ""}, + {true, false, &devModeConfig{defaultMode: true, connectMode: false}, ""}, + {true, true, nil, "-dev-connect is only supported on linux"}, + {false, true, nil, "-dev-connect is only supported on linux"}, } } if runtime.GOOS == "linux" { testutil.RequireRoot(t) cases = []struct { - flag string + dev bool + connect bool expected *devModeConfig expectedErr string }{ - {"", nil, ""}, - {"true", &devModeConfig{defaultMode: true, connectMode: false}, ""}, - {"true,connect", &devModeConfig{defaultMode: true, connectMode: true}, ""}, - {"connect", &devModeConfig{defaultMode: false, connectMode: true}, ""}, - {"xxx", nil, "invalid -dev flag"}, + {false, false, nil, ""}, + {true, false, &devModeConfig{defaultMode: true, connectMode: false}, ""}, + {true, true, &devModeConfig{defaultMode: true, connectMode: true}, ""}, + {false, true, &devModeConfig{defaultMode: false, connectMode: true}, ""}, } } for _, c := range cases { - t.Run(c.flag, func(t *testing.T) { - mode, err := newDevModeConfig(c.flag) + t.Run("", func(t *testing.T) { + mode, err := newDevModeConfig(c.dev, c.connect) if err != nil && c.expectedErr == "" { t.Fatalf("unexpected error: %v", err) } diff --git a/website/source/docs/commands/agent.html.md.erb b/website/source/docs/commands/agent.html.md.erb index 80ee6fa56..524692f8a 100644 --- a/website/source/docs/commands/agent.html.md.erb +++ b/website/source/docs/commands/agent.html.md.erb @@ -57,11 +57,9 @@ via CLI arguments. The `agent` command accepts the following arguments: dual-role agent (client + server) which is useful for developing or testing Nomad. No other configuration is required to start the agent in this mode, but you may pass an optional comma-separated list of mode configurations: - - `-dev=connect`: Start the agent in development mode, but bind to a public +* `-dev-connect`: Start the agent in development mode, but bind to a public network interface rather than localhost for using Consul Connect. This mode is supported only on Linux as root. - * `-encrypt`: Set the Serf encryption key. See the [Encryption Overview](/guides/security/encryption.html) for more details. * `-join=
`: Address of another agent to join upon starting up. This can be specified multiple times to specify multiple agents to join.