From c586c86f975c78d9955bcfbb473bcf334a63fc62 Mon Sep 17 00:00:00 2001 From: Henrique Santos Date: Thu, 23 Nov 2023 13:27:18 +0000 Subject: [PATCH 1/5] Implement prompt for confirmation --- internal/pkg/confirm/confirm.go | 40 +++++++ internal/pkg/confirm/confirm_test.go | 165 +++++++++++++++++++++++++++ 2 files changed, 205 insertions(+) create mode 100644 internal/pkg/confirm/confirm.go create mode 100644 internal/pkg/confirm/confirm_test.go diff --git a/internal/pkg/confirm/confirm.go b/internal/pkg/confirm/confirm.go new file mode 100644 index 00000000..b4595f92 --- /dev/null +++ b/internal/pkg/confirm/confirm.go @@ -0,0 +1,40 @@ +package confirm + +import ( + "bufio" + "errors" + "fmt" + "strings" + + "github.com/spf13/cobra" +) + +var ErrAborted = errAborted() + +func errAborted() error { + return errors.New("operation aborted") +} + +// Prompts the user for confirmation. +// +// Returns nil only if the user (explicitly) answers positive. +// Returns ErrAborted if the user answers negative. +func PromptForConfirmation(cmd *cobra.Command, prompt string) error { + question := fmt.Sprintf("%s [y/N] ", prompt) + reader := bufio.NewReader(cmd.InOrStdin()) + for i := 0; i < 3; i++ { + cmd.Print(question) + answer, err := reader.ReadString('\n') + if err != nil { + continue + } + answer = strings.ToLower(strings.TrimSpace(answer)) + if answer == "y" || answer == "yes" { + return nil + } + if answer == "" || answer == "n" || answer == "no" { + return ErrAborted + } + } + return fmt.Errorf("max number of wrong inputs") +} diff --git a/internal/pkg/confirm/confirm_test.go b/internal/pkg/confirm/confirm_test.go new file mode 100644 index 00000000..24d17af9 --- /dev/null +++ b/internal/pkg/confirm/confirm_test.go @@ -0,0 +1,165 @@ +package confirm + +import ( + "bytes" + "errors" + "io" + "testing" + + "github.com/spf13/cobra" +) + +func TestPromptForConfirmation(t *testing.T) { + tests := []struct { + description string + input string + isValid bool + isAborted bool + }{ + // Note: Some of these inputs have normal spaces, others have tabs + { + description: "yes - simple 1", + input: "y\n", + isValid: true, + }, + { + description: "yes - simple 2", + input: " Y \r\n", + isValid: true, + }, + { + description: "yes - simple 3", + input: " yes\n", + isValid: true, + }, + { + description: "yes - simple 4", + input: "YES\n", + isValid: true, + }, + { + description: "yes - retries 1", + input: "yrs\nyes\n", + isValid: true, + }, + { + description: "yes - retries 2", + input: "foo\nbar \n y\n", + isValid: true, + }, + { + description: "yes - retries 3", + input: "foo\r\nbar \nY \n", + isValid: true, + }, + { + description: "no - simple 1", + input: "n\n", + isValid: false, + isAborted: true, + }, + { + description: "no - simple 2", + input: " N \r\n", + isValid: false, + isAborted: true, + }, + { + description: "no - simple 3", + input: "no\n", + isValid: false, + isAborted: true, + }, + { + description: "no - simple 4", + input: " \n", + isValid: false, + isAborted: true, + }, + { + description: "no - simple 5", + input: " \r\n", + isValid: false, + isAborted: true, + }, + { + description: "no - retries 1", + input: "ni\n no \n", + isValid: false, + isAborted: true, + }, + { + description: "no - retries 2", + input: "foo\nbar\nn\n", + isValid: false, + isAborted: true, + }, + { + description: "no - retries 3", + input: "foo\r\nbar\nN\n", + isValid: false, + isAborted: true, + }, + { + description: "no - retries 4", + input: "m\n \n", + isValid: false, + isAborted: true, + }, + { + description: "no - retries 5", + input: "m\r\n \r\n", + isValid: false, + isAborted: true, + }, + { + description: "max retries 1", + input: "foo\nbar\nbaz\n", + isValid: false, + }, + { + description: "max retries 2", + input: "foo\r\nbar\r\nbaz\r\n", + isValid: false, + }, + { + description: "max retries 3", + input: "foo\nbar\nbaz\ny\n", + isValid: false, + }, + { + description: "no input", + input: "", + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + buffer := &bytes.Buffer{} + _, err := buffer.WriteString(tt.input) + if err != nil { + t.Fatalf("failed to initialize mock input: %v", err) + } + + cmd := &cobra.Command{} + cmd.SetOut(io.Discard) // Suppresses console prints + cmd.SetIn(buffer) + + err = PromptForConfirmation(cmd, "") + + if tt.isValid && err != nil { + t.Errorf("should not have failed: %v", err) + } + if !tt.isValid && err == nil { + t.Errorf("should have failed") + } + if tt.isAborted && !errors.Is(err, ErrAborted) { + t.Errorf("should have returned aborted error, instead returned: %v", err) + } + if !tt.isAborted && errors.Is(err, ErrAborted) { + t.Errorf("should not have returned aborted error") + } + }) + } +} From 70b901fb6f93199c0b7391e6b8e7ba326b1fcd9a Mon Sep 17 00:00:00 2001 From: Henrique Santos Date: Thu, 23 Nov 2023 16:51:01 +0000 Subject: [PATCH 2/5] Add `assume-yes` global flag --- internal/cmd/dns/record-set/create/create.go | 2 +- internal/cmd/dns/record-set/delete/delete.go | 2 +- internal/cmd/dns/record-set/describe/describe.go | 2 +- internal/cmd/dns/record-set/list/list.go | 2 +- internal/cmd/dns/record-set/update/update.go | 2 +- internal/cmd/dns/zone/create/create.go | 2 +- internal/cmd/dns/zone/delete/delete.go | 2 +- internal/cmd/dns/zone/describe/describe.go | 2 +- internal/cmd/dns/zone/list/list.go | 2 +- internal/cmd/dns/zone/update/update.go | 2 +- internal/cmd/postgresql/credential/create/create.go | 2 +- internal/cmd/postgresql/credential/delete/delete.go | 2 +- internal/cmd/postgresql/credential/describe/describe.go | 2 +- internal/cmd/postgresql/credential/list/list.go | 2 +- internal/cmd/postgresql/instance/create/create.go | 2 +- internal/cmd/postgresql/instance/delete/delete.go | 2 +- internal/cmd/postgresql/instance/describe/describe.go | 2 +- internal/cmd/postgresql/instance/list/list.go | 2 +- internal/cmd/postgresql/instance/update/update.go | 2 +- internal/cmd/postgresql/offering/list/list.go | 2 +- internal/cmd/ske/cluster/create/create.go | 2 +- internal/cmd/ske/cluster/delete/delete.go | 2 +- internal/cmd/ske/cluster/describe/describe.go | 2 +- internal/cmd/ske/cluster/list/list.go | 2 +- internal/cmd/ske/describe/describe.go | 6 +++--- internal/cmd/ske/describe/describe_test.go | 2 +- internal/cmd/ske/disable/disable.go | 6 +++--- internal/cmd/ske/disable/disable_test.go | 2 +- internal/cmd/ske/enable/enable.go | 6 +++--- internal/cmd/ske/enable/enable_test.go | 2 +- internal/pkg/globalflags/global_flags.go | 9 ++++++++- 31 files changed, 44 insertions(+), 37 deletions(-) diff --git a/internal/cmd/dns/record-set/create/create.go b/internal/cmd/dns/record-set/create/create.go index 8ac2c847..88958d79 100644 --- a/internal/cmd/dns/record-set/create/create.go +++ b/internal/cmd/dns/record-set/create/create.go @@ -89,7 +89,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/dns/record-set/delete/delete.go b/internal/cmd/dns/record-set/delete/delete.go index 9cfd12d2..ff6c0556 100644 --- a/internal/cmd/dns/record-set/delete/delete.go +++ b/internal/cmd/dns/record-set/delete/delete.go @@ -77,7 +77,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/dns/record-set/describe/describe.go b/internal/cmd/dns/record-set/describe/describe.go index 4d4e6f07..af1a4e6d 100644 --- a/internal/cmd/dns/record-set/describe/describe.go +++ b/internal/cmd/dns/record-set/describe/describe.go @@ -75,7 +75,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/dns/record-set/list/list.go b/internal/cmd/dns/record-set/list/list.go index 91ea112d..7c61584c 100644 --- a/internal/cmd/dns/record-set/list/list.go +++ b/internal/cmd/dns/record-set/list/list.go @@ -96,7 +96,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/dns/record-set/update/update.go b/internal/cmd/dns/record-set/update/update.go index b4c30081..64cf010c 100644 --- a/internal/cmd/dns/record-set/update/update.go +++ b/internal/cmd/dns/record-set/update/update.go @@ -86,7 +86,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/dns/zone/create/create.go b/internal/cmd/dns/zone/create/create.go index 2bcf2de6..82d67da1 100644 --- a/internal/cmd/dns/zone/create/create.go +++ b/internal/cmd/dns/zone/create/create.go @@ -107,7 +107,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/dns/zone/delete/delete.go b/internal/cmd/dns/zone/delete/delete.go index 3f40f76c..50d76c62 100644 --- a/internal/cmd/dns/zone/delete/delete.go +++ b/internal/cmd/dns/zone/delete/delete.go @@ -74,7 +74,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/dns/zone/describe/describe.go b/internal/cmd/dns/zone/describe/describe.go index 0f758db3..7fa4e508 100644 --- a/internal/cmd/dns/zone/describe/describe.go +++ b/internal/cmd/dns/zone/describe/describe.go @@ -71,7 +71,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/dns/zone/list/list.go b/internal/cmd/dns/zone/list/list.go index f8f7437d..ee9db05c 100644 --- a/internal/cmd/dns/zone/list/list.go +++ b/internal/cmd/dns/zone/list/list.go @@ -89,7 +89,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/dns/zone/update/update.go b/internal/cmd/dns/zone/update/update.go index 78fbad9e..cf45085c 100644 --- a/internal/cmd/dns/zone/update/update.go +++ b/internal/cmd/dns/zone/update/update.go @@ -104,7 +104,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/postgresql/credential/create/create.go b/internal/cmd/postgresql/credential/create/create.go index ea70fcef..127098f9 100644 --- a/internal/cmd/postgresql/credential/create/create.go +++ b/internal/cmd/postgresql/credential/create/create.go @@ -72,7 +72,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/postgresql/credential/delete/delete.go b/internal/cmd/postgresql/credential/delete/delete.go index fc956777..e9bf9e4d 100644 --- a/internal/cmd/postgresql/credential/delete/delete.go +++ b/internal/cmd/postgresql/credential/delete/delete.go @@ -69,7 +69,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/postgresql/credential/describe/describe.go b/internal/cmd/postgresql/credential/describe/describe.go index 2f852a74..e2cade35 100644 --- a/internal/cmd/postgresql/credential/describe/describe.go +++ b/internal/cmd/postgresql/credential/describe/describe.go @@ -76,7 +76,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/postgresql/credential/list/list.go b/internal/cmd/postgresql/credential/list/list.go index 24fbb5be..87306057 100644 --- a/internal/cmd/postgresql/credential/list/list.go +++ b/internal/cmd/postgresql/credential/list/list.go @@ -86,7 +86,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/postgresql/instance/create/create.go b/internal/cmd/postgresql/instance/create/create.go index 80f307bc..e0e13012 100644 --- a/internal/cmd/postgresql/instance/create/create.go +++ b/internal/cmd/postgresql/instance/create/create.go @@ -115,7 +115,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/postgresql/instance/delete/delete.go b/internal/cmd/postgresql/instance/delete/delete.go index 739207b1..285b7012 100644 --- a/internal/cmd/postgresql/instance/delete/delete.go +++ b/internal/cmd/postgresql/instance/delete/delete.go @@ -70,7 +70,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/postgresql/instance/describe/describe.go b/internal/cmd/postgresql/instance/describe/describe.go index fa8f3bfd..13807e0c 100644 --- a/internal/cmd/postgresql/instance/describe/describe.go +++ b/internal/cmd/postgresql/instance/describe/describe.go @@ -70,7 +70,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/postgresql/instance/list/list.go b/internal/cmd/postgresql/instance/list/list.go index a60e84ef..1c13c352 100644 --- a/internal/cmd/postgresql/instance/list/list.go +++ b/internal/cmd/postgresql/instance/list/list.go @@ -80,7 +80,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/postgresql/instance/update/update.go b/internal/cmd/postgresql/instance/update/update.go index d6b64329..977dfc67 100644 --- a/internal/cmd/postgresql/instance/update/update.go +++ b/internal/cmd/postgresql/instance/update/update.go @@ -116,7 +116,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/postgresql/offering/list/list.go b/internal/cmd/postgresql/offering/list/list.go index 2af19306..a59004c7 100644 --- a/internal/cmd/postgresql/offering/list/list.go +++ b/internal/cmd/postgresql/offering/list/list.go @@ -85,7 +85,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/ske/cluster/create/create.go b/internal/cmd/ske/cluster/create/create.go index 71e53209..2b92981e 100644 --- a/internal/cmd/ske/cluster/create/create.go +++ b/internal/cmd/ske/cluster/create/create.go @@ -92,7 +92,7 @@ func ConfigureFlags(cmd *cobra.Command) { type FileReaderFunc func(filename string) ([]byte, error) func ParseFlags(cmd *cobra.Command, fileReaderFunc FileReaderFunc) (*FlagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/ske/cluster/delete/delete.go b/internal/cmd/ske/cluster/delete/delete.go index eb67864f..ea0068b8 100644 --- a/internal/cmd/ske/cluster/delete/delete.go +++ b/internal/cmd/ske/cluster/delete/delete.go @@ -69,7 +69,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/ske/cluster/describe/describe.go b/internal/cmd/ske/cluster/describe/describe.go index 37247b23..518dc7e9 100644 --- a/internal/cmd/ske/cluster/describe/describe.go +++ b/internal/cmd/ske/cluster/describe/describe.go @@ -68,7 +68,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/ske/cluster/list/list.go b/internal/cmd/ske/cluster/list/list.go index adf2c439..714d57f6 100644 --- a/internal/cmd/ske/cluster/list/list.go +++ b/internal/cmd/ske/cluster/list/list.go @@ -80,7 +80,7 @@ func configureFlags(cmd *cobra.Command) { } func parseFlags(cmd *cobra.Command) (*flagModel, error) { - globalFlags := globalflags.Parse() + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/ske/describe/describe.go b/internal/cmd/ske/describe/describe.go index 0c0825a8..74349296 100644 --- a/internal/cmd/ske/describe/describe.go +++ b/internal/cmd/ske/describe/describe.go @@ -24,7 +24,7 @@ func NewCmd() *cobra.Command { Example: `$ stackit ske describe --project-id xxx`, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseFlags() + model, err := parseFlags(cmd) if err != nil { return err } @@ -54,8 +54,8 @@ func NewCmd() *cobra.Command { return cmd } -func parseFlags() (*flagModel, error) { - globalFlags := globalflags.Parse() +func parseFlags(cmd *cobra.Command) (*flagModel, error) { + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/ske/describe/describe_test.go b/internal/cmd/ske/describe/describe_test.go index 67fdaed3..f5cb6b94 100644 --- a/internal/cmd/ske/describe/describe_test.go +++ b/internal/cmd/ske/describe/describe_test.go @@ -118,7 +118,7 @@ func TestParseFlags(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - model, err := parseFlags() + model, err := parseFlags(cmd) if err != nil { if !tt.isValid { return diff --git a/internal/cmd/ske/disable/disable.go b/internal/cmd/ske/disable/disable.go index b45ec38d..f2a43866 100644 --- a/internal/cmd/ske/disable/disable.go +++ b/internal/cmd/ske/disable/disable.go @@ -24,7 +24,7 @@ func NewCmd() *cobra.Command { Example: `$ stackit ske disable --project-id xxx`, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseFlags() + model, err := parseFlags(cmd) if err != nil { return err } @@ -55,8 +55,8 @@ func NewCmd() *cobra.Command { return cmd } -func parseFlags() (*FlagModel, error) { - globalFlags := globalflags.Parse() +func parseFlags(cmd *cobra.Command) (*FlagModel, error) { + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/ske/disable/disable_test.go b/internal/cmd/ske/disable/disable_test.go index 93c59db4..df3ae680 100644 --- a/internal/cmd/ske/disable/disable_test.go +++ b/internal/cmd/ske/disable/disable_test.go @@ -118,7 +118,7 @@ func TestParseFlags(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - model, err := parseFlags() + model, err := parseFlags(cmd) if err != nil { if !tt.isValid { return diff --git a/internal/cmd/ske/enable/enable.go b/internal/cmd/ske/enable/enable.go index 88756792..91632e7d 100644 --- a/internal/cmd/ske/enable/enable.go +++ b/internal/cmd/ske/enable/enable.go @@ -24,7 +24,7 @@ func NewCmd() *cobra.Command { Example: `$ stackit ske enable --project-id xxx`, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() - model, err := parseFlags() + model, err := parseFlags(cmd) if err != nil { return err } @@ -55,8 +55,8 @@ func NewCmd() *cobra.Command { return cmd } -func parseFlags() (*FlagModel, error) { - globalFlags := globalflags.Parse() +func parseFlags(cmd *cobra.Command) (*FlagModel, error) { + globalFlags := globalflags.Parse(cmd) if globalFlags.ProjectId == "" { return nil, fmt.Errorf("project ID not set") } diff --git a/internal/cmd/ske/enable/enable_test.go b/internal/cmd/ske/enable/enable_test.go index f6f5719f..ce7e4368 100644 --- a/internal/cmd/ske/enable/enable_test.go +++ b/internal/cmd/ske/enable/enable_test.go @@ -118,7 +118,7 @@ func TestParseFlags(t *testing.T) { t.Fatalf("error validating flags: %v", err) } - model, err := parseFlags() + model, err := parseFlags(cmd) if err != nil { if !tt.isValid { return diff --git a/internal/pkg/globalflags/global_flags.go b/internal/pkg/globalflags/global_flags.go index 55be7000..f9d67e17 100644 --- a/internal/pkg/globalflags/global_flags.go +++ b/internal/pkg/globalflags/global_flags.go @@ -3,15 +3,18 @@ package globalflags import ( "fmt" + "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/spf13/viper" "github.com/stackitcloud/stackit-cli/internal/pkg/config" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" ) const ( ProjectIdFlag = "project-id" OutputFormatFlag = "output-format" + AssumeYesFlag = "assume-yes" ) var outputFormatFlagOptions = []string{"default", "json", "table"} @@ -19,6 +22,7 @@ var outputFormatFlagOptions = []string{"default", "json", "table"} type GlobalFlagModel struct { ProjectId string OutputFormat string + AssumeYes bool } func Configure(flagSet *pflag.FlagSet) error { @@ -33,12 +37,15 @@ func Configure(flagSet *pflag.FlagSet) error { if err != nil { return fmt.Errorf("bind --%s flag to config: %w", OutputFormatFlag, err) } + + flagSet.BoolP(AssumeYesFlag, "y", false, "If set, skips all confirmation prompts") return nil } -func Parse() *GlobalFlagModel { +func Parse(cmd *cobra.Command) *GlobalFlagModel { return &GlobalFlagModel{ ProjectId: viper.GetString(config.ProjectIdKey), OutputFormat: viper.GetString(config.OutputFormatKey), + AssumeYes: utils.FlagToBoolValue(cmd, AssumeYesFlag), } } From 8d7e5c5050d63484b64c816b0d66f3ac7ca91e14 Mon Sep 17 00:00:00 2001 From: Henrique Santos Date: Fri, 24 Nov 2023 12:41:36 +0000 Subject: [PATCH 3/5] Add confirmation prompts in commands --- internal/cmd/dns/record-set/create/create.go | 9 +++++++++ internal/cmd/dns/record-set/delete/delete.go | 9 +++++++++ internal/cmd/dns/record-set/update/update.go | 9 +++++++++ internal/cmd/dns/zone/create/create.go | 11 +++++++++++ internal/cmd/dns/zone/delete/delete.go | 9 +++++++++ internal/cmd/dns/zone/update/update.go | 9 +++++++++ internal/cmd/postgresql/credential/create/create.go | 9 +++++++++ internal/cmd/postgresql/credential/delete/delete.go | 9 +++++++++ internal/cmd/postgresql/instance/create/create.go | 9 +++++++++ internal/cmd/postgresql/instance/delete/delete.go | 10 ++++++++++ internal/cmd/postgresql/instance/update/update.go | 9 +++++++++ internal/cmd/ske/cluster/create/create.go | 9 +++++++++ internal/cmd/ske/cluster/delete/delete.go | 10 ++++++++++ internal/cmd/ske/cluster/update/update.go | 9 +++++++++ internal/cmd/ske/disable/disable.go | 9 +++++++++ internal/cmd/ske/enable/enable.go | 9 +++++++++ 16 files changed, 148 insertions(+) diff --git a/internal/cmd/dns/record-set/create/create.go b/internal/cmd/dns/record-set/create/create.go index 88958d79..6e6a68a0 100644 --- a/internal/cmd/dns/record-set/create/create.go +++ b/internal/cmd/dns/record-set/create/create.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/dns/client" @@ -46,6 +47,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := "Do you want to create a record-set?" + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/dns/record-set/delete/delete.go b/internal/cmd/dns/record-set/delete/delete.go index ff6c0556..3b8acc56 100644 --- a/internal/cmd/dns/record-set/delete/delete.go +++ b/internal/cmd/dns/record-set/delete/delete.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/dns/client" @@ -38,6 +39,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to delete record-set %s? (This cannot be undone)", model.RecordSetId) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/dns/record-set/update/update.go b/internal/cmd/dns/record-set/update/update.go index 64cf010c..d3aecf6c 100644 --- a/internal/cmd/dns/record-set/update/update.go +++ b/internal/cmd/dns/record-set/update/update.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/dns/client" @@ -46,6 +47,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to update record-set %s?", model.RecordSetId) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/dns/zone/create/create.go b/internal/cmd/dns/zone/create/create.go index 82d67da1..9c3157df 100644 --- a/internal/cmd/dns/zone/create/create.go +++ b/internal/cmd/dns/zone/create/create.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/dns/client" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" @@ -59,6 +60,16 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := "Do you want to create a zone?" + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + + cmd.OutOrStdout() + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/dns/zone/delete/delete.go b/internal/cmd/dns/zone/delete/delete.go index 50d76c62..d7cc3b16 100644 --- a/internal/cmd/dns/zone/delete/delete.go +++ b/internal/cmd/dns/zone/delete/delete.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/dns/client" @@ -36,6 +37,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to delete zone %s? (This cannot be undone)", model.ZoneId) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/dns/zone/update/update.go b/internal/cmd/dns/zone/update/update.go index cf45085c..22c48b8c 100644 --- a/internal/cmd/dns/zone/update/update.go +++ b/internal/cmd/dns/zone/update/update.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/dns/client" @@ -56,6 +57,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to update zone %s?", model.ZoneId) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/postgresql/credential/create/create.go b/internal/cmd/postgresql/credential/create/create.go index 127098f9..f8fada69 100644 --- a/internal/cmd/postgresql/credential/create/create.go +++ b/internal/cmd/postgresql/credential/create/create.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/postgresql/client" @@ -37,6 +38,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := "Do you want to create a credential?" + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/postgresql/credential/delete/delete.go b/internal/cmd/postgresql/credential/delete/delete.go index e9bf9e4d..8e75b3bb 100644 --- a/internal/cmd/postgresql/credential/delete/delete.go +++ b/internal/cmd/postgresql/credential/delete/delete.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/postgresql/client" @@ -37,6 +38,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to delete credential %s? (This cannot be undone)", model.CredentialId) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/postgresql/instance/create/create.go b/internal/cmd/postgresql/instance/create/create.go index e0e13012..d3f45814 100644 --- a/internal/cmd/postgresql/instance/create/create.go +++ b/internal/cmd/postgresql/instance/create/create.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/postgresql/client" @@ -61,6 +62,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := "Do you want to create an instance?" + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/postgresql/instance/delete/delete.go b/internal/cmd/postgresql/instance/delete/delete.go index 285b7012..5ad44361 100644 --- a/internal/cmd/postgresql/instance/delete/delete.go +++ b/internal/cmd/postgresql/instance/delete/delete.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/postgresql/client" @@ -35,6 +36,15 @@ func NewCmd() *cobra.Command { if err != nil { return err } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to delete instance %s? (This cannot be undone)", model.InstanceId) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/postgresql/instance/update/update.go b/internal/cmd/postgresql/instance/update/update.go index 977dfc67..67d5ba23 100644 --- a/internal/cmd/postgresql/instance/update/update.go +++ b/internal/cmd/postgresql/instance/update/update.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/postgresql/client" @@ -62,6 +63,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to update instance %s?", model.InstanceId) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/ske/cluster/create/create.go b/internal/cmd/ske/cluster/create/create.go index 2b92981e..1b0896c2 100644 --- a/internal/cmd/ske/cluster/create/create.go +++ b/internal/cmd/ske/cluster/create/create.go @@ -7,6 +7,7 @@ import ( "os" "strings" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/ske/client" skeUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/ske/utils" @@ -41,6 +42,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := "Do you want to create a cluster?" + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/ske/cluster/delete/delete.go b/internal/cmd/ske/cluster/delete/delete.go index ea0068b8..4226f063 100644 --- a/internal/cmd/ske/cluster/delete/delete.go +++ b/internal/cmd/ske/cluster/delete/delete.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/ske/client" "github.com/stackitcloud/stackit-cli/internal/pkg/utils" @@ -34,6 +35,15 @@ func NewCmd() *cobra.Command { if err != nil { return err } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to delete cluster %s? (This cannot be undone)", model.ClusterName) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/ske/cluster/update/update.go b/internal/cmd/ske/cluster/update/update.go index 115bb522..54ec4123 100644 --- a/internal/cmd/ske/cluster/update/update.go +++ b/internal/cmd/ske/cluster/update/update.go @@ -6,6 +6,7 @@ import ( "os" "github.com/stackitcloud/stackit-cli/internal/cmd/ske/cluster/create" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/services/ske/client" "github.com/stackitcloud/stackit-cli/internal/pkg/services/ske/utils" @@ -26,6 +27,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to update cluster %s?", model.Name) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/ske/disable/disable.go b/internal/cmd/ske/disable/disable.go index f2a43866..ec372a1c 100644 --- a/internal/cmd/ske/disable/disable.go +++ b/internal/cmd/ske/disable/disable.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/ske/client" @@ -29,6 +30,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to disable SKE for project %s? (This will delete all associated clusters)", model.ProjectId) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { diff --git a/internal/cmd/ske/enable/enable.go b/internal/cmd/ske/enable/enable.go index 91632e7d..24bee679 100644 --- a/internal/cmd/ske/enable/enable.go +++ b/internal/cmd/ske/enable/enable.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/stackitcloud/stackit-cli/internal/pkg/confirm" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/services/ske/client" @@ -29,6 +30,14 @@ func NewCmd() *cobra.Command { return err } + if !model.AssumeYes { + prompt := fmt.Sprintf("Do you want to enable SKE for project %s?", model.ProjectId) + err = confirm.PromptForConfirmation(cmd, prompt) + if err != nil { + return err + } + } + // Configure API client apiClient, err := client.ConfigureClient(cmd) if err != nil { From 7268afb0e010c03af8db5d98c9fc9ca77c2db1d8 Mon Sep 17 00:00:00 2001 From: Henrique Santos Date: Fri, 24 Nov 2023 15:48:25 +0000 Subject: [PATCH 4/5] Change confirmation prompt message --- internal/cmd/dns/record-set/create/create.go | 2 +- internal/cmd/dns/record-set/delete/delete.go | 2 +- internal/cmd/dns/record-set/update/update.go | 2 +- internal/cmd/dns/zone/create/create.go | 2 +- internal/cmd/dns/zone/delete/delete.go | 2 +- internal/cmd/dns/zone/update/update.go | 2 +- internal/cmd/postgresql/credential/create/create.go | 2 +- internal/cmd/postgresql/credential/delete/delete.go | 2 +- internal/cmd/postgresql/instance/create/create.go | 2 +- internal/cmd/postgresql/instance/delete/delete.go | 2 +- internal/cmd/postgresql/instance/update/update.go | 2 +- internal/cmd/ske/cluster/create/create.go | 2 +- internal/cmd/ske/cluster/delete/delete.go | 2 +- internal/cmd/ske/cluster/update/update.go | 2 +- internal/cmd/ske/disable/disable.go | 2 +- internal/cmd/ske/enable/enable.go | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/internal/cmd/dns/record-set/create/create.go b/internal/cmd/dns/record-set/create/create.go index 6e6a68a0..977b195f 100644 --- a/internal/cmd/dns/record-set/create/create.go +++ b/internal/cmd/dns/record-set/create/create.go @@ -48,7 +48,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := "Do you want to create a record-set?" + prompt := "Are you sure you want to create a record-set?" err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/dns/record-set/delete/delete.go b/internal/cmd/dns/record-set/delete/delete.go index 3b8acc56..f808eda5 100644 --- a/internal/cmd/dns/record-set/delete/delete.go +++ b/internal/cmd/dns/record-set/delete/delete.go @@ -40,7 +40,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to delete record-set %s? (This cannot be undone)", model.RecordSetId) + prompt := fmt.Sprintf("Are you sure you want to delete record-set %s? (This cannot be undone)", model.RecordSetId) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/dns/record-set/update/update.go b/internal/cmd/dns/record-set/update/update.go index d3aecf6c..de0e3440 100644 --- a/internal/cmd/dns/record-set/update/update.go +++ b/internal/cmd/dns/record-set/update/update.go @@ -48,7 +48,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to update record-set %s?", model.RecordSetId) + prompt := fmt.Sprintf("Are you sure you want to update record-set %s?", model.RecordSetId) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/dns/zone/create/create.go b/internal/cmd/dns/zone/create/create.go index 9c3157df..e2b0e603 100644 --- a/internal/cmd/dns/zone/create/create.go +++ b/internal/cmd/dns/zone/create/create.go @@ -61,7 +61,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := "Do you want to create a zone?" + prompt := "Are you sure you want to create a zone?" err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/dns/zone/delete/delete.go b/internal/cmd/dns/zone/delete/delete.go index d7cc3b16..75bb7c68 100644 --- a/internal/cmd/dns/zone/delete/delete.go +++ b/internal/cmd/dns/zone/delete/delete.go @@ -38,7 +38,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to delete zone %s? (This cannot be undone)", model.ZoneId) + prompt := fmt.Sprintf("Are you sure you want to delete zone %s? (This cannot be undone)", model.ZoneId) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/dns/zone/update/update.go b/internal/cmd/dns/zone/update/update.go index 22c48b8c..d42dd1b0 100644 --- a/internal/cmd/dns/zone/update/update.go +++ b/internal/cmd/dns/zone/update/update.go @@ -58,7 +58,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to update zone %s?", model.ZoneId) + prompt := fmt.Sprintf("Are you sure you want to update zone %s?", model.ZoneId) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/postgresql/credential/create/create.go b/internal/cmd/postgresql/credential/create/create.go index f8fada69..9e656908 100644 --- a/internal/cmd/postgresql/credential/create/create.go +++ b/internal/cmd/postgresql/credential/create/create.go @@ -39,7 +39,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := "Do you want to create a credential?" + prompt := "Are you sure you want to create a credential?" err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/postgresql/credential/delete/delete.go b/internal/cmd/postgresql/credential/delete/delete.go index 8e75b3bb..8973d69a 100644 --- a/internal/cmd/postgresql/credential/delete/delete.go +++ b/internal/cmd/postgresql/credential/delete/delete.go @@ -39,7 +39,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to delete credential %s? (This cannot be undone)", model.CredentialId) + prompt := fmt.Sprintf("Are you sure you want to delete credential %s? (This cannot be undone)", model.CredentialId) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/postgresql/instance/create/create.go b/internal/cmd/postgresql/instance/create/create.go index d3f45814..e7d347db 100644 --- a/internal/cmd/postgresql/instance/create/create.go +++ b/internal/cmd/postgresql/instance/create/create.go @@ -63,7 +63,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := "Do you want to create an instance?" + prompt := "Are you sure you want to create an instance?" err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/postgresql/instance/delete/delete.go b/internal/cmd/postgresql/instance/delete/delete.go index 5ad44361..aadb9755 100644 --- a/internal/cmd/postgresql/instance/delete/delete.go +++ b/internal/cmd/postgresql/instance/delete/delete.go @@ -38,7 +38,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to delete instance %s? (This cannot be undone)", model.InstanceId) + prompt := fmt.Sprintf("Are you sure you want to delete instance %s? (This cannot be undone)", model.InstanceId) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/postgresql/instance/update/update.go b/internal/cmd/postgresql/instance/update/update.go index 67d5ba23..f3508649 100644 --- a/internal/cmd/postgresql/instance/update/update.go +++ b/internal/cmd/postgresql/instance/update/update.go @@ -64,7 +64,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to update instance %s?", model.InstanceId) + prompt := fmt.Sprintf("Are you sure you want to update instance %s?", model.InstanceId) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/ske/cluster/create/create.go b/internal/cmd/ske/cluster/create/create.go index 1b0896c2..6e2beb3b 100644 --- a/internal/cmd/ske/cluster/create/create.go +++ b/internal/cmd/ske/cluster/create/create.go @@ -43,7 +43,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := "Do you want to create a cluster?" + prompt := "Are you sure you want to create a cluster?" err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/ske/cluster/delete/delete.go b/internal/cmd/ske/cluster/delete/delete.go index 4226f063..36a8311d 100644 --- a/internal/cmd/ske/cluster/delete/delete.go +++ b/internal/cmd/ske/cluster/delete/delete.go @@ -37,7 +37,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to delete cluster %s? (This cannot be undone)", model.ClusterName) + prompt := fmt.Sprintf("Are you sure you want to delete cluster %s? (This cannot be undone)", model.ClusterName) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/ske/cluster/update/update.go b/internal/cmd/ske/cluster/update/update.go index 54ec4123..616696c0 100644 --- a/internal/cmd/ske/cluster/update/update.go +++ b/internal/cmd/ske/cluster/update/update.go @@ -28,7 +28,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to update cluster %s?", model.Name) + prompt := fmt.Sprintf("Are you sure you want to update cluster %s?", model.Name) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/ske/disable/disable.go b/internal/cmd/ske/disable/disable.go index ec372a1c..a82ac61c 100644 --- a/internal/cmd/ske/disable/disable.go +++ b/internal/cmd/ske/disable/disable.go @@ -31,7 +31,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to disable SKE for project %s? (This will delete all associated clusters)", model.ProjectId) + prompt := fmt.Sprintf("Are you sure you want to disable SKE for project %s? (This will delete all associated clusters)", model.ProjectId) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err diff --git a/internal/cmd/ske/enable/enable.go b/internal/cmd/ske/enable/enable.go index 24bee679..b13adb96 100644 --- a/internal/cmd/ske/enable/enable.go +++ b/internal/cmd/ske/enable/enable.go @@ -31,7 +31,7 @@ func NewCmd() *cobra.Command { } if !model.AssumeYes { - prompt := fmt.Sprintf("Do you want to enable SKE for project %s?", model.ProjectId) + prompt := fmt.Sprintf("Are you sure you want to enable SKE for project %s?", model.ProjectId) err = confirm.PromptForConfirmation(cmd, prompt) if err != nil { return err From 9cda3f07a78bf5161b9d64981276d8b131cd7b06 Mon Sep 17 00:00:00 2001 From: Henrique Santos Date: Fri, 24 Nov 2023 16:12:18 +0000 Subject: [PATCH 5/5] Simplify error creation --- internal/pkg/confirm/confirm.go | 8 ++------ internal/pkg/confirm/confirm_test.go | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/internal/pkg/confirm/confirm.go b/internal/pkg/confirm/confirm.go index b4595f92..99a2f2f9 100644 --- a/internal/pkg/confirm/confirm.go +++ b/internal/pkg/confirm/confirm.go @@ -9,11 +9,7 @@ import ( "github.com/spf13/cobra" ) -var ErrAborted = errAborted() - -func errAborted() error { - return errors.New("operation aborted") -} +var errAborted = errors.New("operation aborted") // Prompts the user for confirmation. // @@ -33,7 +29,7 @@ func PromptForConfirmation(cmd *cobra.Command, prompt string) error { return nil } if answer == "" || answer == "n" || answer == "no" { - return ErrAborted + return errAborted } } return fmt.Errorf("max number of wrong inputs") diff --git a/internal/pkg/confirm/confirm_test.go b/internal/pkg/confirm/confirm_test.go index 24d17af9..84f79295 100644 --- a/internal/pkg/confirm/confirm_test.go +++ b/internal/pkg/confirm/confirm_test.go @@ -154,10 +154,10 @@ func TestPromptForConfirmation(t *testing.T) { if !tt.isValid && err == nil { t.Errorf("should have failed") } - if tt.isAborted && !errors.Is(err, ErrAborted) { + if tt.isAborted && !errors.Is(err, errAborted) { t.Errorf("should have returned aborted error, instead returned: %v", err) } - if !tt.isAborted && errors.Is(err, ErrAborted) { + if !tt.isAborted && errors.Is(err, errAborted) { t.Errorf("should not have returned aborted error") } })