From 764225dfc8f0595e820a885cbdfd48fe659defa2 Mon Sep 17 00:00:00 2001 From: Mauro Ezequiel Moltrasio Date: Wed, 14 Oct 2026 18:02:14 +0200 Subject: [PATCH 1/2] feat: ask for confirmation before teardown This is a small change that asks the user before the teardown command goes through in interactive shells, intended to help prevent situations where something is accidentally teardown from unintended inertia or when working with multiple clusters. --- cmd/teardown.go | 17 +++++++++++++++++ internal/helpers/helpers.go | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/cmd/teardown.go b/cmd/teardown.go index 0b5c09d..8fa01d8 100644 --- a/cmd/teardown.go +++ b/cmd/teardown.go @@ -10,11 +10,16 @@ import ( "github.com/stackrox/roxie/internal/component" "github.com/stackrox/roxie/internal/deployer" "github.com/stackrox/roxie/internal/env" + "github.com/stackrox/roxie/internal/helpers" "github.com/stackrox/roxie/internal/k8s" log "github.com/stackrox/roxie/internal/logger" "github.com/stackrox/roxie/internal/manifest" ) +var ( + force bool +) + func newTeardownCmd(settings *deployer.Config) *cobra.Command { cmd := &cobra.Command{ Use: "teardown [component]", @@ -37,6 +42,8 @@ func newTeardownCmd(settings *deployer.Config) *cobra.Command { }), ) + cmd.Flags().BoolVarP(&force, "force", "f", false, "Skip confirmation prompt") + return cmd } @@ -50,6 +57,16 @@ func runTeardown(cmd *cobra.Command, args []string) error { return err } + if !force && env.RunningInteractively { + confirmed, err := helpers.WaitForConfirmation("About to teardown %s on %s, continue?", components, env.GetCurrentContext()) + if err != nil { + return err + } + if !confirmed { + log.Info("Aborting teardown") + return nil + } + } log.Infof("Tearing down %s", components) if dryRun { diff --git a/internal/helpers/helpers.go b/internal/helpers/helpers.go index 4c08605..91c0363 100644 --- a/internal/helpers/helpers.go +++ b/internal/helpers/helpers.go @@ -1,13 +1,17 @@ package helpers import ( + "bufio" "bytes" "fmt" "os" "os/exec" "reflect" + "strings" "gopkg.in/yaml.v3" + + log "github.com/stackrox/roxie/internal/logger" ) // RunCommandWithOutput executes a command and captures stdout/stderr @@ -150,3 +154,16 @@ func IsNil(i interface{}) bool { } return false } + +// Wait for user confirmation +func WaitForConfirmation(f string, a ...any) (bool, error) { + reader := bufio.NewReader(os.Stdin) + prompt := fmt.Sprintf(f, a...) + log.Warningf("%s [y/N]", prompt) + response, err := reader.ReadString('\n') + if err != nil { + return false, err + } + response = strings.ToLower(strings.TrimSpace(response)) + return response == "y" || response == "yes", nil +} From ab8d5b2101726c4adb135a44d0f73b838a3dc3af Mon Sep 17 00:00:00 2001 From: Mauro Ezequiel Moltrasio Date: Thu, 15 Oct 2026 10:44:19 +0200 Subject: [PATCH 2/2] Prompt on stdout and treat terminal EOF as cancellation --- internal/helpers/helpers.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/internal/helpers/helpers.go b/internal/helpers/helpers.go index 91c0363..1339698 100644 --- a/internal/helpers/helpers.go +++ b/internal/helpers/helpers.go @@ -4,6 +4,7 @@ import ( "bufio" "bytes" "fmt" + "io" "os" "os/exec" "reflect" @@ -11,7 +12,7 @@ import ( "gopkg.in/yaml.v3" - log "github.com/stackrox/roxie/internal/logger" + "github.com/fatih/color" ) // RunCommandWithOutput executes a command and captures stdout/stderr @@ -157,11 +158,14 @@ func IsNil(i interface{}) bool { // Wait for user confirmation func WaitForConfirmation(f string, a ...any) (bool, error) { + yellow := color.New(color.FgYellow, color.Bold) reader := bufio.NewReader(os.Stdin) prompt := fmt.Sprintf(f, a...) - log.Warningf("%s [y/N]", prompt) + yellow.Printf("%s [y/N]: ", prompt) response, err := reader.ReadString('\n') - if err != nil { + if err == io.EOF { + return false, nil + } else if err != nil { return false, err } response = strings.ToLower(strings.TrimSpace(response))