diff --git a/application/configuration.go b/application/configuration.go index af41f6625..d0373a3e2 100644 --- a/application/configuration.go +++ b/application/configuration.go @@ -3,10 +3,11 @@ package application import "github.com/cloudfoundry/bosh-bootloader/storage" type GlobalConfiguration struct { - StateDir string - Debug bool - Name string - TerraformBinary bool + StateDir string + Debug bool + Name string + TerraformBinary bool + DisableTfAutoApprove bool } type StringSlice []string diff --git a/bbl/main.go b/bbl/main.go index 904d385c4..c8bf5da14 100644 --- a/bbl/main.go +++ b/bbl/main.go @@ -94,14 +94,15 @@ func main() { // Terraform terraformOutputBuffer := bytes.NewBuffer([]byte{}) dotTerraformDir := filepath.Join(appConfig.Global.StateDir, "terraform", ".terraform") - bufferingCLI := terraform.NewCLI(terraformOutputBuffer, terraformOutputBuffer, dotTerraformDir, globals.TerraformBinary) + bufferingCLI := terraform.NewCLI(terraformOutputBuffer, terraformOutputBuffer, dotTerraformDir, globals.TerraformBinary, globals.DisableTfAutoApprove) + var ( terraformCLI terraform.CLI out io.Writer ) if appConfig.Global.Debug { errBuffer := io.MultiWriter(os.Stderr, terraformOutputBuffer) - terraformCLI = terraform.NewCLI(errBuffer, terraformOutputBuffer, dotTerraformDir, globals.TerraformBinary) + terraformCLI = terraform.NewCLI(errBuffer, terraformOutputBuffer, dotTerraformDir, globals.TerraformBinary, globals.DisableTfAutoApprove) out = os.Stdout } else { terraformCLI = bufferingCLI diff --git a/commands/usage.go b/commands/usage.go index 1d3c540b1..fcdd3f345 100644 --- a/commands/usage.go +++ b/commands/usage.go @@ -13,12 +13,14 @@ Usage: bbl [GLOBAL OPTIONS] %s [OPTIONS] Global Options: - --help [-h] Prints usage. Use "bbl [command] --help" for more information about a command - --state-dir [-s] Directory containing the bbl state env:"BBL_STATE_DIRECTORY" - --debug [-d] Prints debugging output env:"BBL_DEBUG" - --version [-v] Prints version - --no-confirm [-n] No confirm - --terraform-binary Path of a terraform binary (optional). If the file does not exist the embedded binary is used. env:"BBL_TERRAFORM_BINARY" + --help [-h] Prints usage. Use "bbl [command] --help" for more information about a command + --state-dir [-s] Directory containing the bbl state env:"BBL_STATE_DIRECTORY" + --debug [-d] Prints debugging output env:"BBL_DEBUG" + --version [-v] Prints version + --no-confirm [-n] No confirm + --terraform-binary Path of a terraform binary (optional). If the file does not exist the embedded binary is used. env:"BBL_TERRAFORM_BINARY" + --disable-tf-auto-approve Do not use the '-auto-approve' option with terraform (debug mode required) env:"BBL_DISABLE_TF_AUTO_APPROVE" + %s ` CommandUsage = ` diff --git a/commands/usage_test.go b/commands/usage_test.go index 2f42d0b2f..61f81d61c 100644 --- a/commands/usage_test.go +++ b/commands/usage_test.go @@ -39,12 +39,13 @@ Usage: bbl [GLOBAL OPTIONS] COMMAND [OPTIONS] Global Options: - --help [-h] Prints usage. Use "bbl [command] --help" for more information about a command - --state-dir [-s] Directory containing the bbl state env:"BBL_STATE_DIRECTORY" - --debug [-d] Prints debugging output env:"BBL_DEBUG" - --version [-v] Prints version - --no-confirm [-n] No confirm - --terraform-binary Path of a terraform binary (optional). If the file does not exist the embedded binary is used. env:"BBL_TERRAFORM_BINARY" + --help [-h] Prints usage. Use "bbl [command] --help" for more information about a command + --state-dir [-s] Directory containing the bbl state env:"BBL_STATE_DIRECTORY" + --debug [-d] Prints debugging output env:"BBL_DEBUG" + --version [-v] Prints version + --no-confirm [-n] No confirm + --terraform-binary Path of a terraform binary (optional). If the file does not exist the embedded binary is used. env:"BBL_TERRAFORM_BINARY" + --disable-tf-auto-approve Do not use the '-auto-approve' option with terraform (debug mode required) env:"BBL_DISABLE_TF_AUTO_APPROVE" Basic Commands: A good place to start up Deploys BOSH director on an IAAS, creates CF/Concourse load balancers. Updates existing director. @@ -85,12 +86,13 @@ Troubleshooting Commands: bbl [GLOBAL OPTIONS] my-command [OPTIONS] Global Options: - --help [-h] Prints usage. Use "bbl [command] --help" for more information about a command - --state-dir [-s] Directory containing the bbl state env:"BBL_STATE_DIRECTORY" - --debug [-d] Prints debugging output env:"BBL_DEBUG" - --version [-v] Prints version - --no-confirm [-n] No confirm - --terraform-binary Path of a terraform binary (optional). If the file does not exist the embedded binary is used. env:"BBL_TERRAFORM_BINARY" + --help [-h] Prints usage. Use "bbl [command] --help" for more information about a command + --state-dir [-s] Directory containing the bbl state env:"BBL_STATE_DIRECTORY" + --debug [-d] Prints debugging output env:"BBL_DEBUG" + --version [-v] Prints version + --no-confirm [-n] No confirm + --terraform-binary Path of a terraform binary (optional). If the file does not exist the embedded binary is used. env:"BBL_TERRAFORM_BINARY" + --disable-tf-auto-approve Do not use the '-auto-approve' option with terraform (debug mode required) env:"BBL_DISABLE_TF_AUTO_APPROVE" [my-command command options] some message diff --git a/config/global_flags.go b/config/global_flags.go index 7ada1f3ac..a3b573c19 100644 --- a/config/global_flags.go +++ b/config/global_flags.go @@ -1,15 +1,16 @@ package config type GlobalFlags struct { - Help bool `short:"h" long:"help"` - Debug bool `short:"d" long:"debug" env:"BBL_DEBUG"` - Version bool `short:"v" long:"version"` - NoConfirm bool `short:"n" long:"no-confirm"` - StateDir string `short:"s" long:"state-dir" env:"BBL_STATE_DIRECTORY"` - StateBucket string ` long:"state-bucket" env:"BBL_STATE_BUCKET"` - EnvID string ` long:"name"` - IAAS string ` long:"iaas" env:"BBL_IAAS"` - TerraformBinary string ` long:"terraform-binary" env:"BBL_TERRAFORM_BINARY"` + Help bool `short:"h" long:"help"` + Debug bool `short:"d" long:"debug" env:"BBL_DEBUG"` + Version bool `short:"v" long:"version"` + NoConfirm bool `short:"n" long:"no-confirm"` + StateDir string `short:"s" long:"state-dir" env:"BBL_STATE_DIRECTORY"` + StateBucket string ` long:"state-bucket" env:"BBL_STATE_BUCKET"` + EnvID string ` long:"name"` + IAAS string ` long:"iaas" env:"BBL_IAAS"` + TerraformBinary string ` long:"terraform-binary" env:"BBL_TERRAFORM_BINARY"` + DisableTfAutoApprove bool ` long:"disable-tf-auto-approve" env:"BBL_DISABLE_TF_AUTO_APPROVE"` AWSAccessKeyID string `long:"aws-access-key-id" env:"BBL_AWS_ACCESS_KEY_ID"` AWSSecretAccessKey string `long:"aws-secret-access-key" env:"BBL_AWS_SECRET_ACCESS_KEY"` diff --git a/terraform/cli.go b/terraform/cli.go index 43bc64e4a..ed9e06fcd 100644 --- a/terraform/cli.go +++ b/terraform/cli.go @@ -1,6 +1,7 @@ package terraform import ( + "bytes" "fmt" "io" "os" @@ -8,18 +9,20 @@ import ( ) type CLI struct { - errorBuffer io.Writer - outputBuffer io.Writer - tfDataDir string - terraformBinary string + errorBuffer io.Writer + outputBuffer io.Writer + tfDataDir string + terraformBinary string + disableTfAutoApprove bool } -func NewCLI(errorBuffer, outputBuffer io.Writer, tfDataDir string, terraformBinary string) CLI { +func NewCLI(errorBuffer, outputBuffer io.Writer, tfDataDir string, terraformBinary string, disableTfAutoApprove bool) CLI { return CLI{ - errorBuffer: errorBuffer, - outputBuffer: outputBuffer, - tfDataDir: tfDataDir, - terraformBinary: terraformBinary, + errorBuffer: errorBuffer, + outputBuffer: outputBuffer, + tfDataDir: tfDataDir, + terraformBinary: terraformBinary, + disableTfAutoApprove: disableTfAutoApprove, } } @@ -40,9 +43,14 @@ func (c CLI) RunWithEnv(stdout io.Writer, workingDirectory string, args []string command.Stdout = io.MultiWriter(stdout, c.outputBuffer) command.Stderr = c.errorBuffer + command.Stdin = os.Stdin err = command.Run() if err != nil { + _, isBuffer := c.errorBuffer.(*bytes.Buffer) + if !isBuffer { + return fmt.Errorf("command execution failed got: %s", err) + } return fmt.Errorf("command execution failed got: %s stderr:\n %s", err, c.errorBuffer) } diff --git a/terraform/executor.go b/terraform/executor.go index b75f6c800..ab21d497e 100644 --- a/terraform/executor.go +++ b/terraform/executor.go @@ -177,7 +177,14 @@ func (e Executor) Init() error { } func (e Executor) Apply(credentials map[string]string) error { - args := []string{"apply", "--auto-approve"} + args := []string{"apply"} + cli, ok := e.cli.(CLI) + if !ok || !cli.disableTfAutoApprove || !e.debug { + args = append(args, "--auto-approve") + } + if cli.disableTfAutoApprove && !e.debug { + return fmt.Errorf("%s", "Debug mode is mandatory when terraform auto approve is disabled.") + } for key, value := range credentials { arg := fmt.Sprintf("%s=%s", key, value) args = append(args, "-var", arg) @@ -231,7 +238,14 @@ func (e Executor) Validate(credentials map[string]string) error { } func (e Executor) Destroy(credentials map[string]string) error { - args := []string{"destroy", "-auto-approve"} + args := []string{"destroy"} + cli, ok := e.cli.(CLI) + if !ok || !cli.disableTfAutoApprove || !e.debug { + args = append(args, "-auto-approve") + } + if cli.disableTfAutoApprove && !e.debug { + return fmt.Errorf("%s", "Debug mode is mandatory when terraform auto approve is disabled.") + } for key, value := range credentials { arg := fmt.Sprintf("%s=%s", key, value) args = append(args, "-var", arg)