From 0a4669e96d605f4a2337ea734ff0af7593d4ade1 Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Tue, 22 Sep 2020 21:37:37 -0400 Subject: [PATCH] Remove dev mode from controller/worker, and streamline flags on dev command (#413) --- .../cmd/commands/controller/controller.go | 206 +++--------------- internal/cmd/commands/dev/dev.go | 137 ++++++------ internal/cmd/commands/worker/worker.go | 78 ++----- 3 files changed, 109 insertions(+), 312 deletions(-) diff --git a/internal/cmd/commands/controller/controller.go b/internal/cmd/commands/controller/controller.go index 607ff72da..d457058fe 100644 --- a/internal/cmd/commands/controller/controller.go +++ b/internal/cmd/commands/controller/controller.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/hashicorp/boundary/globals" - "github.com/hashicorp/boundary/internal/auth/password" "github.com/hashicorp/boundary/internal/cmd/base" "github.com/hashicorp/boundary/internal/cmd/config" "github.com/hashicorp/boundary/internal/servers/controller" @@ -36,18 +35,11 @@ type Command struct { configWrapper wrapping.Wrapper - flagConfig string - flagConfigKms string - flagLogLevel string - flagLogFormat string - flagCombineLogs bool - flagDev bool - flagDevLoginName string - flagDevPassword string - flagDevControllerAPIListenAddr string - flagDevControllerClusterListenAddr string - flagDevAuthMethodId string - flagDevSkipAuthMethodCreation bool + flagConfig string + flagConfigKms string + flagLogLevel string + flagLogFormat string + flagCombineLogs bool } func (c *Command) Synopsis() string { @@ -69,7 +61,7 @@ Usage: boundary controller [options] } func (c *Command) Flags() *base.FlagSets { - set := c.FlagSet(base.FlagSetHTTP) + set := c.FlagSet(base.FlagSetNone) f := set.NewFlagSet("Command Options") @@ -111,67 +103,6 @@ func (c *Command) Flags() *base.FlagSets { Usage: `Log format. Supported values are "standard" and "json".`, }) - f = set.NewFlagSet("Dev Options") - - f.BoolVar(&base.BoolVar{ - Name: "dev", - Target: &c.flagDev, - Usage: "Enable development mode. As the name implies, do not run \"dev\" mode in " + - "production.", - }) - - f.StringVar(&base.StringVar{ - Name: "dev-auth-method-id", - Target: &c.flagDevAuthMethodId, - EnvVar: "BOUNDARY_DEV_AUTH_METHOD_ID", - Usage: "Auto-created auth method ID. This only applies when running in \"dev\" " + - "mode.", - }) - - f.BoolVar(&base.BoolVar{ - Name: "dev-skip-auth-method-creation", - Target: &c.flagDevSkipAuthMethodCreation, - Usage: "If set, an auth method will not be created as part of the dev instance. The recovery KMS will be needed to perform any actions.", - }) - - f.StringVar(&base.StringVar{ - Name: "dev-password", - Target: &c.flagDevPassword, - EnvVar: "BOUNDARY_DEV_PASSWORD", - Usage: "Initial admin password. This only applies when running in \"dev\" " + - "mode.", - }) - - f.StringVar(&base.StringVar{ - Name: "dev-login-name", - Target: &c.flagDevLoginName, - EnvVar: "BOUNDARY_DEV_LOGIN_NAME", - Usage: "Initial admin login name. This only applies when running in \"dev\" " + - "mode.", - }) - - f.StringVar(&base.StringVar{ - Name: "dev-api-listen-address", - Target: &c.flagDevControllerAPIListenAddr, - EnvVar: "BOUNDARY_DEV_CONTROLLER_API_LISTEN_ADDRESS", - Usage: "Address to bind the controller to in \"dev\" mode for \"api\" purpose.", - }) - - f.StringVar(&base.StringVar{ - Name: "dev-cluster-listen-address", - Target: &c.flagDevControllerClusterListenAddr, - EnvVar: "BOUNDARY_DEV_CONTROLLER_CLUSTER_LISTEN_ADDRESS", - Usage: "Address to bind the controller to in \"dev\" mode for \"cluster\" purpose.", - }) - - f.BoolVar(&base.BoolVar{ - Name: "combine-logs", - Target: &c.flagCombineLogs, - Usage: "If set, both startup information and logs will be sent to stdout. If not set (the default), startup information will go to stdout and logs will be sent to stderr.", - }) - - base.DevOnlyControllerFlags(c.Command, f) - return set } @@ -233,7 +164,7 @@ func (c *Command) Run(args []string) int { // If mlockall(2) isn't supported, show a warning. We disable this in dev // because it is quite scary to see when first using Boundary. We also disable // this if the user has explicitly disabled mlock in configuration. - if !c.flagDev && !c.Config.DisableMlock && !mlock.Supported() { + if !c.Config.DisableMlock && !mlock.Supported() { c.UI.Warn(base.WrapAtLength( "WARNING! mlock is not supported on this system! An mlockall(2)-like " + "syscall to prevent memory from being swapped to disk is not " + @@ -292,37 +223,19 @@ func (c *Command) Run(args []string) int { return 1 } - if c.flagDev { - var opts []base.Option - if c.flagDevSkipAuthMethodCreation { - opts = append(opts, base.WithSkipAuthMethodCreation()) - switch { - case c.flagDevAuthMethodId != "", - c.flagDevLoginName != "", - c.flagDevPassword != "": - c.UI.Warn("-dev-skip-auth-method-creation set, skipping any auth-method related flags") - } - } - if err := c.CreateDevDatabase("postgres", opts...); err != nil { - c.UI.Error(fmt.Errorf("Error creating dev database container: %w", err).Error()) - return 1 - } - c.ShutdownFuncs = append(c.ShutdownFuncs, c.DestroyDevDatabase) - } else { - if c.Config.Database == nil || c.Config.Database.Url == "" { - c.UI.Error(`"url" not specified in "database" config block"`) - return 1 - } - dbaseUrl, err := config.ParseAddress(c.Config.Database.Url) - if err != nil && err != config.ErrNotAUrl { - c.UI.Error(fmt.Errorf("Error parsing database url: %w", err).Error()) - return 1 - } - c.DatabaseUrl = strings.TrimSpace(dbaseUrl) - if err := c.ConnectToDatabase("postgres"); err != nil { - c.UI.Error(fmt.Errorf("Error connecting to database: %w", err).Error()) - return 1 - } + if c.Config.Database == nil || c.Config.Database.Url == "" { + c.UI.Error(`"url" not specified in "database" config block"`) + return 1 + } + dbaseUrl, err := config.ParseAddress(c.Config.Database.Url) + if err != nil && err != config.ErrNotAUrl { + c.UI.Error(fmt.Errorf("Error parsing database url: %w", err).Error()) + return 1 + } + c.DatabaseUrl = strings.TrimSpace(dbaseUrl) + if err := c.ConnectToDatabase("postgres"); err != nil { + c.UI.Error(fmt.Errorf("Error connecting to database: %w", err).Error()) + return 1 } defer func() { @@ -369,78 +282,15 @@ func (c *Command) ParseFlagsAndConfig(args []string) int { } } - // Validation - if !c.flagDev { - switch { - case len(c.flagConfig) == 0: - c.UI.Error("Must specify a config file using -config") - return 1 - case c.flagDevPassword != "": - c.UI.Warn(base.WrapAtLength( - "You cannot specify a custom admin password outside of \"dev\" mode. " + - "Your request has been ignored.")) - c.flagDevPassword = "" - case c.flagDevLoginName != "": - c.UI.Warn(base.WrapAtLength( - "You cannot specify a custom admin login name outside of \"dev\" mode. " + - "Your request has been ignored.")) - c.flagDevLoginName = "" - } + if len(c.flagConfig) == 0 { + c.UI.Error("Must specify a config file using -config") + return 1 + } - c.Config, err = config.LoadFile(c.flagConfig, wrapper) - if err != nil { - c.UI.Error("Error parsing config: " + err.Error()) - return 1 - } - - } else { - if len(c.flagConfig) == 0 { - c.Config, err = config.DevController() - } else { - c.Config, err = config.LoadFile(c.flagConfig, wrapper) - } - if err != nil { - c.UI.Error(fmt.Errorf("Error creating dev config: %w", err).Error()) - return 1 - } - - if c.flagDevAuthMethodId != "" { - prefix := password.AuthMethodPrefix + "_" - if !strings.HasPrefix(c.flagDevAuthMethodId, prefix) { - c.UI.Error(fmt.Sprintf("Invalid dev auth method ID, must start with %q", prefix)) - return 1 - } - if len(c.flagDevAuthMethodId) != 15 { - c.UI.Error(fmt.Sprintf("Invalid dev auth method ID, must be 10 base62 characters after %q", prefix)) - return 1 - } - c.DevAuthMethodId = c.flagDevAuthMethodId - } - if c.flagDevLoginName != "" { - c.DevLoginName = c.flagDevLoginName - } - if c.flagDevPassword != "" { - c.DevPassword = c.flagDevPassword - } - - c.Config.PassthroughDirectory = c.FlagDevPassthroughDirectory - - for _, l := range c.Config.Listeners { - if len(l.Purpose) != 1 { - continue - } - switch l.Purpose[0] { - case "api": - if c.flagDevControllerAPIListenAddr != "" { - l.Address = c.flagDevControllerAPIListenAddr - } - - case "cluster": - if c.flagDevControllerClusterListenAddr != "" { - l.Address = c.flagDevControllerClusterListenAddr - } - } - } + c.Config, err = config.LoadFile(c.flagConfig, wrapper) + if err != nil { + c.UI.Error("Error parsing config: " + err.Error()) + return 1 } return 0 diff --git a/internal/cmd/commands/dev/dev.go b/internal/cmd/commands/dev/dev.go index 9dc038fbf..7100eb5b6 100644 --- a/internal/cmd/commands/dev/dev.go +++ b/internal/cmd/commands/dev/dev.go @@ -11,6 +11,7 @@ import ( controllercmd "github.com/hashicorp/boundary/internal/cmd/commands/controller" workercmd "github.com/hashicorp/boundary/internal/cmd/commands/worker" "github.com/hashicorp/boundary/internal/cmd/config" + "github.com/hashicorp/boundary/internal/servers/controller/handlers" "github.com/mitchellh/cli" "github.com/posener/complete" ) @@ -26,18 +27,19 @@ type Command struct { ReloadedCh chan struct{} SigUSR2Ch chan struct{} - flagLogLevel string - flagLogFormat string - flagCombineLogs bool - flagDevLoginName string - flagDevPassword string - flagDevAuthMethodId string - flagDevControllerAPIListenAddr string - flagDevControllerClusterListenAddr string - flagDevWorkerProxyListenAddr string - flagDevWorkerPublicAddr string - flagDevSkipAuthMethodCreation bool - flagDevDisableDatabaseDestruction bool + flagLogLevel string + flagLogFormat string + flagCombineLogs bool + flagLoginName string + flagPassword string + flagIdSuffix string + flagControllerAPIListenAddr string + flagControllerClusterListenAddr string + flagWorkerProxyListenAddr string + flagWorkerPublicAddr string + flagPassthroughDirectory string + flagRecoveryKey string + flagDisableDatabaseDestruction bool } func (c *Command) Synopsis() string { @@ -81,69 +83,58 @@ func (c *Command) Flags() *base.FlagSets { Usage: `Log format. Supported values are "standard" and "json".`, }) - f = set.NewFlagSet("Dev Options") - f.StringVar(&base.StringVar{ - Name: "dev-auth-method-id", - Target: &c.flagDevAuthMethodId, - EnvVar: "BOUNDARY_DEV_AUTH_METHOD_ID", - Usage: "Auto-created auth method ID. This only applies when running in \"dev\" " + - "mode.", + Name: "id-suffix", + Target: &c.flagIdSuffix, + EnvVar: "BOUNDARY_DEV_ID_SUFFIX", + Usage: `If set, auto-created resources will use this value for their identifier (along with their resource-specific prefix). Must be 10 alphanumeric characters. As an example, if this is set to "1234567890", the generated password auth method ID will be "ampw_1234567890", the generated TCP target ID will be "ttcp_1234567890", and so on.`, }) f.StringVar(&base.StringVar{ - Name: "dev-password", - Target: &c.flagDevPassword, + Name: "password", + Target: &c.flagPassword, EnvVar: "BOUNDARY_DEV_PASSWORD", - Usage: "Initial admin password. This only applies when running in \"dev\" " + - "mode.", + Usage: "Initial login password.", }) f.StringVar(&base.StringVar{ - Name: "dev-login-name", - Target: &c.flagDevLoginName, + Name: "login-name", + Target: &c.flagLoginName, EnvVar: "BOUNDARY_DEV_LOGIN_NAME", - Usage: "Initial admin login name. This only applies when running in \"dev\" " + - "mode.", + Usage: "Initial admin login name.", }) f.StringVar(&base.StringVar{ - Name: "dev-api-listen-address", - Target: &c.flagDevControllerAPIListenAddr, + Name: "api-listen-address", + Target: &c.flagControllerAPIListenAddr, EnvVar: "BOUNDARY_DEV_CONTROLLER_API_LISTEN_ADDRESS", Usage: "Address to bind to for controller \"api\" purpose.", }) f.StringVar(&base.StringVar{ - Name: "dev-cluster-listen-address", - Target: &c.flagDevControllerClusterListenAddr, + Name: "cluster-listen-address", + Target: &c.flagControllerClusterListenAddr, EnvVar: "BOUNDARY_DEV_CONTROLLER_CLUSTER_LISTEN_ADDRESS", Usage: "Address to bind to for controller \"cluster\" purpose.", }) f.StringVar(&base.StringVar{ - Name: "dev-proxy-listen-address", - Target: &c.flagDevWorkerProxyListenAddr, + Name: "proxy-listen-address", + Target: &c.flagWorkerProxyListenAddr, EnvVar: "BOUNDARY_DEV_WORKER_PROXY_LISTEN_ADDRESS", Usage: "Address to bind to for worker \"proxy\" purpose.", }) f.StringVar(&base.StringVar{ - Name: "dev-worker-public-address", - Target: &c.flagDevWorkerPublicAddr, + Name: "worker-public-address", + Target: &c.flagWorkerPublicAddr, EnvVar: "BOUNDARY_DEV_WORKER_PUBLIC_ADDRESS", Usage: "Public address at which the worker is reachable for session proxying.", }) f.BoolVar(&base.BoolVar{ - Name: "dev-skip-auth-method-creation", - Target: &c.flagDevSkipAuthMethodCreation, - Usage: "If set, an auth method will not be created as part of the dev instance. The recovery KMS will be needed to perform any actions.", - }) - - f.BoolVar(&base.BoolVar{ - Name: "dev-disable-database-destruction", - Target: &c.flagDevDisableDatabaseDestruction, + Name: "disable-database-destruction", + Target: &c.flagDisableDatabaseDestruction, Usage: "If set, if a database is created automatically in Docker, it will not be removed when the dev server is shut down.", }) @@ -153,7 +144,19 @@ func (c *Command) Flags() *base.FlagSets { Usage: "If set, both startup information and logs will be sent to stdout. If not set (the default), startup information will go to stdout and logs will be sent to stderr.", }) - base.DevOnlyControllerFlags(c.Command, f) + f.StringVar(&base.StringVar{ + Name: "passthrough-directory", + Target: &c.flagPassthroughDirectory, + EnvVar: "BOUNDARY_DEV_PASSTHROUGH_DIRECTORY", + Usage: "Enables a passthrough directory in the webserver at /", + }) + + f.StringVar(&base.StringVar{ + Name: "recovery-key", + Target: &c.flagRecoveryKey, + EnvVar: "BOUNDARY_DEV_RECOVERY_KEY", + Usage: "Specifies the base64'd 256-bit AES key to use for recovery operations", + }) return set } @@ -185,23 +188,22 @@ func (c *Command) Run(args []string) int { c.UI.Error(fmt.Errorf("Error creating controller dev config: %w", err).Error()) return 1 } - if c.flagDevAuthMethodId != "" { - prefix := password.AuthMethodPrefix + "_" - if !strings.HasPrefix(c.flagDevAuthMethodId, prefix) { - c.UI.Error(fmt.Sprintf("Invalid dev auth method ID, must start with %q", prefix)) + if c.flagIdSuffix != "" { + if len(c.flagIdSuffix) != 10 { + c.UI.Error("Invalid ID suffix, must be exactly 10 characters") return 1 } - if len(c.flagDevAuthMethodId) != 15 { - c.UI.Error(fmt.Sprintf("Invalid dev auth method ID, must be 10 base62 characters after %q", prefix)) + if !handlers.ValidId("abc", "abc_"+c.flagIdSuffix) { + c.UI.Error("Invalid ID suffix, must be in the set A-Za-z0-9") return 1 } - c.DevAuthMethodId = c.flagDevAuthMethodId + c.DevAuthMethodId = fmt.Sprintf("%s_%s", password.AuthMethodPrefix, c.flagIdSuffix) } - if c.flagDevLoginName != "" { - c.DevLoginName = c.flagDevLoginName + if c.flagLoginName != "" { + c.DevLoginName = c.flagLoginName } - if c.flagDevPassword != "" { - c.DevPassword = c.flagDevPassword + if c.flagPassword != "" { + c.DevPassword = c.flagPassword } devConfig.PassthroughDirectory = c.FlagDevPassthroughDirectory @@ -212,18 +214,18 @@ func (c *Command) Run(args []string) int { } switch l.Purpose[0] { case "api": - if c.flagDevControllerAPIListenAddr != "" { - l.Address = c.flagDevControllerAPIListenAddr + if c.flagControllerAPIListenAddr != "" { + l.Address = c.flagControllerAPIListenAddr } case "cluster": - if c.flagDevControllerClusterListenAddr != "" { - l.Address = c.flagDevControllerClusterListenAddr + if c.flagControllerClusterListenAddr != "" { + l.Address = c.flagControllerClusterListenAddr } case "proxy": - if c.flagDevWorkerProxyListenAddr != "" { - l.Address = c.flagDevWorkerProxyListenAddr + if c.flagWorkerProxyListenAddr != "" { + l.Address = c.flagWorkerProxyListenAddr } } } @@ -268,7 +270,7 @@ func (c *Command) Run(args []string) int { return 1 } - if err := c.SetupWorkerPublicAddress(devConfig, c.flagDevWorkerPublicAddr); err != nil { + if err := c.SetupWorkerPublicAddress(devConfig, c.flagWorkerPublicAddr); err != nil { c.UI.Error(err.Error()) return 1 } @@ -288,20 +290,11 @@ func (c *Command) Run(args []string) int { }() var opts []base.Option - if c.flagDevSkipAuthMethodCreation { - opts = append(opts, base.WithSkipAuthMethodCreation()) - switch { - case c.flagDevAuthMethodId != "", - c.flagDevLoginName != "", - c.flagDevPassword != "": - c.UI.Warn("-dev-skip-auth-method-creation set, skipping any auth-method related flags") - } - } if err := c.CreateDevDatabase("postgres", opts...); err != nil { c.UI.Error(fmt.Errorf("Error creating dev database container: %w", err).Error()) return 1 } - if !c.flagDevDisableDatabaseDestruction { + if !c.flagDisableDatabaseDestruction { c.ShutdownFuncs = append(c.ShutdownFuncs, c.DestroyDevDatabase) } diff --git a/internal/cmd/commands/worker/worker.go b/internal/cmd/commands/worker/worker.go index add51b946..40d619605 100644 --- a/internal/cmd/commands/worker/worker.go +++ b/internal/cmd/commands/worker/worker.go @@ -36,14 +36,11 @@ type Command struct { configWrapper wrapping.Wrapper - flagConfig string - flagConfigKms string - flagLogLevel string - flagLogFormat string - flagDev bool - flagDevWorkerProxyListenAddr string - flagDevWorkerPublicAddr string - flagCombineLogs bool + flagConfig string + flagConfigKms string + flagLogLevel string + flagLogFormat string + flagCombineLogs bool } func (c *Command) Synopsis() string { @@ -65,7 +62,7 @@ Usage: boundary worker [options] } func (c *Command) Flags() *base.FlagSets { - set := c.FlagSet(base.FlagSetHTTP) + set := c.FlagSet(base.FlagSetNone) f := set.NewFlagSet("Command Options") @@ -107,29 +104,6 @@ func (c *Command) Flags() *base.FlagSets { Usage: `Log format. Supported values are "standard" and "json".`, }) - f = set.NewFlagSet("Dev Options") - - f.BoolVar(&base.BoolVar{ - Name: "dev", - Target: &c.flagDev, - Usage: "Enable development mode. As the name implies, do not run \"dev\" mode in " + - "production.", - }) - - f.StringVar(&base.StringVar{ - Name: "dev-proxy-listen-address", - Target: &c.flagDevWorkerProxyListenAddr, - EnvVar: "BOUNDARY_DEV_WORKER_PROXY_LISTEN_ADDRESS", - Usage: "Address to bind the worker to in \"dev\" mode.", - }) - - f.StringVar(&base.StringVar{ - Name: "dev-worker-public-address", - Target: &c.flagDevWorkerPublicAddr, - EnvVar: "BOUNDARY_DEV_WORKER_PUBLIC_ADDRESS", - Usage: "Public address at which the worker is reachable for session proxying.", - }) - f.BoolVar(&base.BoolVar{ Name: "combine-logs", Target: &c.flagCombineLogs, @@ -187,7 +161,7 @@ func (c *Command) Run(args []string) int { // If mlockall(2) isn't supported, show a warning. We disable this in dev // because it is quite scary to see when first using Boundary. We also disable // this if the user has explicitly disabled mlock in configuration. - if !c.flagDev && !c.Config.DisableMlock && !mlock.Supported() { + if !c.Config.DisableMlock && !mlock.Supported() { c.UI.Warn(base.WrapAtLength( "WARNING! mlock is not supported on this system! An mlockall(2)-like " + "syscall to prevent memory from being swapped to disk is not " + @@ -201,10 +175,7 @@ func (c *Command) Run(args []string) int { return 1 } - if !c.flagDev { - c.flagDevWorkerPublicAddr = "" - } - if err := c.SetupWorkerPublicAddress(c.Config, c.flagDevWorkerPublicAddr); err != nil { + if err := c.SetupWorkerPublicAddress(c.Config, ""); err != nil { c.UI.Error(err.Error()) return 1 } @@ -262,31 +233,14 @@ func (c *Command) ParseFlagsAndConfig(args []string) int { } // Validation - if !c.flagDev { - if len(c.flagConfig) == 0 { - c.UI.Error("Must supply a config file with -config") - return 1 - } - c.Config, err = config.LoadFile(c.flagConfig, wrapper) - if err != nil { - c.UI.Error("Error parsing config: " + err.Error()) - return 1 - } - - } else { - if len(c.flagConfig) == 0 { - c.Config, err = config.DevWorker() - } else { - c.Config, err = config.LoadFile(c.flagConfig, wrapper) - } - if err != nil { - c.UI.Error(fmt.Errorf("Error creating dev config: %s", err).Error()) - return 1 - } - - if c.flagDevWorkerProxyListenAddr != "" { - c.Config.Listeners[0].Address = c.flagDevWorkerProxyListenAddr - } + if len(c.flagConfig) == 0 { + c.UI.Error("Must supply a config file with -config") + return 1 + } + c.Config, err = config.LoadFile(c.flagConfig, wrapper) + if err != nil { + c.UI.Error("Error parsing config: " + err.Error()) + return 1 } return 0