From 4252cdadab81698bcfe66c2dd560a61162864204 Mon Sep 17 00:00:00 2001 From: Jack Henschel Date: Fri, 16 Oct 2020 09:46:32 +0200 Subject: [PATCH 1/6] Interactively ask user before destroying app To make sure users don't accidentally delete their deployment, ask for confirmation before doing so (similar to terraform destroy). This patch also adds a flag (-auto-approve) to override this interactive prompt (e.g. for scripting). Fixes https://github.com/hashicorp/waypoint/issues/284 --- internal/cli/base.go | 10 ++++++++++ internal/cli/destroy.go | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/internal/cli/base.go b/internal/cli/base.go index de55285e45a..d25a9915df6 100644 --- a/internal/cli/base.go +++ b/internal/cli/base.go @@ -90,6 +90,9 @@ type baseCommand struct { // flagConnection contains manual flag-based connection info. flagConnection clicontext.Config + // flagAutoApprove is whether to run an action automatically + flagAutoApprove bool + // args that were present after parsing flags args []string @@ -401,6 +404,13 @@ func (c *baseCommand) flagSet(bit flagSetBit, f func(*flag.Sets)) *flag.Sets { "This is specified to the data source type being used in your configuration. " + "This is used for example to set a specific Git ref to run against.", }) + + f.BoolVar(&flag.BoolVar{ + Name: "auto-approve", + Target: &c.flagAutoApprove, + Default: false, + Usage: "True to disable interactive destroy approval.", + }) } if bit&flagSetConnection != 0 { diff --git a/internal/cli/destroy.go b/internal/cli/destroy.go index 52947212c69..d2146b927c4 100644 --- a/internal/cli/destroy.go +++ b/internal/cli/destroy.go @@ -27,6 +27,21 @@ func (c *DestroyCommand) Run(args []string) int { } err := c.DoApp(c.Ctx, func(ctx context.Context, app *clientpkg.App) error { + if !c.flagAutoApprove { + // show confirmation dialog asking user for approval + choice, err := app.UI.Input(&terminal.Input{ + Prompt: "Are you sure you want to destroy this app? Type 'yes' to confirm.", + Style: terminal.WarningStyle, + }) + if err != nil { + return err + } + if choice != "yes" { + app.UI.Output("Aborting destroy.") + return nil + } + } + if err := app.Destroy(ctx, &pb.Job_DestroyOp{ Target: &pb.Job_DestroyOp_Workspace{ Workspace: &empty.Empty{}, From 762dbd385bb2349a8e6c8feac9a86eeb76b4a448 Mon Sep 17 00:00:00 2001 From: Jack Henschel Date: Mon, 19 Oct 2020 21:35:34 +0200 Subject: [PATCH 2/6] [squash] Use -force instead of -auto-approve flag --- internal/cli/base.go | 10 +++++----- internal/cli/destroy.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/cli/base.go b/internal/cli/base.go index d25a9915df6..8d952541e3f 100644 --- a/internal/cli/base.go +++ b/internal/cli/base.go @@ -90,8 +90,8 @@ type baseCommand struct { // flagConnection contains manual flag-based connection info. flagConnection clicontext.Config - // flagAutoApprove is whether to run an action automatically - flagAutoApprove bool + // flagForce is whether to run an action automatically + flagForce bool // args that were present after parsing flags args []string @@ -406,10 +406,10 @@ func (c *baseCommand) flagSet(bit flagSetBit, f func(*flag.Sets)) *flag.Sets { }) f.BoolVar(&flag.BoolVar{ - Name: "auto-approve", - Target: &c.flagAutoApprove, + Name: "force", + Target: &c.flagForce, Default: false, - Usage: "True to disable interactive destroy approval.", + Usage: "True to disable interactive approval.", }) } diff --git a/internal/cli/destroy.go b/internal/cli/destroy.go index d2146b927c4..973454c9082 100644 --- a/internal/cli/destroy.go +++ b/internal/cli/destroy.go @@ -27,7 +27,7 @@ func (c *DestroyCommand) Run(args []string) int { } err := c.DoApp(c.Ctx, func(ctx context.Context, app *clientpkg.App) error { - if !c.flagAutoApprove { + if !c.flagForce { // show confirmation dialog asking user for approval choice, err := app.UI.Input(&terminal.Input{ Prompt: "Are you sure you want to destroy this app? Type 'yes' to confirm.", From 4051749ca7a8ba8fd71e701e58fc879ef6876aa3 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 25 Mar 2021 08:02:21 -0700 Subject: [PATCH 3/6] Remove force flag from base commands --- internal/cli/base.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/internal/cli/base.go b/internal/cli/base.go index 8d952541e3f..de55285e45a 100644 --- a/internal/cli/base.go +++ b/internal/cli/base.go @@ -90,9 +90,6 @@ type baseCommand struct { // flagConnection contains manual flag-based connection info. flagConnection clicontext.Config - // flagForce is whether to run an action automatically - flagForce bool - // args that were present after parsing flags args []string @@ -404,13 +401,6 @@ func (c *baseCommand) flagSet(bit flagSetBit, f func(*flag.Sets)) *flag.Sets { "This is specified to the data source type being used in your configuration. " + "This is used for example to set a specific Git ref to run against.", }) - - f.BoolVar(&flag.BoolVar{ - Name: "force", - Target: &c.flagForce, - Default: false, - Usage: "True to disable interactive approval.", - }) } if bit&flagSetConnection != 0 { From 8231bd1da15770b6ef0b27f1ed25a569f35d088e Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 25 Mar 2021 08:09:09 -0700 Subject: [PATCH 4/6] cli/destroy: Require confirmation before destroy --- internal/cli/destroy.go | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/internal/cli/destroy.go b/internal/cli/destroy.go index 973454c9082..c07dc4e0a5d 100644 --- a/internal/cli/destroy.go +++ b/internal/cli/destroy.go @@ -14,6 +14,8 @@ import ( type DestroyCommand struct { *baseCommand + + confirm bool } func (c *DestroyCommand) Run(args []string) int { @@ -27,19 +29,9 @@ func (c *DestroyCommand) Run(args []string) int { } err := c.DoApp(c.Ctx, func(ctx context.Context, app *clientpkg.App) error { - if !c.flagForce { - // show confirmation dialog asking user for approval - choice, err := app.UI.Input(&terminal.Input{ - Prompt: "Are you sure you want to destroy this app? Type 'yes' to confirm.", - Style: terminal.WarningStyle, - }) - if err != nil { - return err - } - if choice != "yes" { - app.UI.Output("Aborting destroy.") - return nil - } + if !c.confirm { + app.UI.Output("Destroying app %q requires confirmation with `-auto-approve`.", app.Ref().GetApplication(), terminal.WithWarningStyle()) + return nil } if err := app.Destroy(ctx, &pb.Job_DestroyOp{ @@ -67,6 +59,13 @@ func (c *DestroyCommand) Run(args []string) int { func (c *DestroyCommand) Flags() *flag.Sets { return c.flagSet(flagSetOperation, func(set *flag.Sets) { + f := set.NewSet("Command Options") + f.BoolVar(&flag.BoolVar{ + Name: "auto-approve", + Target: &c.confirm, + Default: false, + Usage: "Confirm destroying all resources.", + }) }) } From e826edd5dce06baf0a10924fa8a3cda8b6ab1fb0 Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 25 Mar 2021 08:11:06 -0700 Subject: [PATCH 5/6] Update CHANGELOG entry --- .changelog/522.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/522.txt diff --git a/.changelog/522.txt b/.changelog/522.txt new file mode 100644 index 00000000000..55926172c87 --- /dev/null +++ b/.changelog/522.txt @@ -0,0 +1,3 @@ +```release-note:improvement +cli/destroy: Require confirmation before destroying all resources +``` From d046288810ab3b3387aa624346f7b9b9e58bcedf Mon Sep 17 00:00:00 2001 From: Brian Cain Date: Thu, 25 Mar 2021 08:36:50 -0700 Subject: [PATCH 6/6] Rename CHANGELOG file to match PR number --- .changelog/{522.txt => 1232.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changelog/{522.txt => 1232.txt} (100%) diff --git a/.changelog/522.txt b/.changelog/1232.txt similarity index 100% rename from .changelog/522.txt rename to .changelog/1232.txt