Prompt before termination

This commit is contained in:
Nils Hanke 2022-10-31 16:58:15 +01:00 committed by Nils Hanke
parent c922136cd4
commit ad871d1993
2 changed files with 72 additions and 6 deletions

View File

@ -29,6 +29,7 @@ func NewTerminateCmd() *cobra.Command {
Args: cobra.NoArgs,
RunE: runTerminate,
}
cmd.Flags().BoolP("yes", "y", false, "terminate the cluster without further confirmation")
return cmd
}
@ -44,8 +45,28 @@ func runTerminate(cmd *cobra.Command, args []string) error {
func terminate(cmd *cobra.Command, terminator cloudTerminator, fileHandler file.Handler, spinner spinnerInterf,
) error {
flags, err := parseTerminateFlags(cmd)
if err != nil {
return err
}
if !flags.yes {
cmd.Println("You are about to terminate a Constellation cluster.")
cmd.Println("All of its associated resources will be DESTROYED.")
cmd.Println("This includes any other Terraform workspace in the current directory.")
cmd.Println("This action is irreversible and ALL DATA WILL BE LOST.")
ok, err := askToConfirm(cmd, "Do you want to continue?")
if err != nil {
return err
}
if !ok {
cmd.Println("The termination of the cluster was aborted.")
return nil
}
}
spinner.Start("Terminating", false)
err := terminator.Terminate(cmd.Context())
err = terminator.Terminate(cmd.Context())
spinner.Stop()
if err != nil {
return fmt.Errorf("terminating Constellation cluster: %w", err)
@ -64,3 +85,18 @@ func terminate(cmd *cobra.Command, terminator cloudTerminator, fileHandler file.
return retErr
}
type terminateFlags struct {
yes bool
}
func parseTerminateFlags(cmd *cobra.Command) (terminateFlags, error) {
yes, err := cmd.Flags().GetBool("yes")
if err != nil {
return terminateFlags{}, err
}
return terminateFlags{
yes: yes,
}, nil
}

View File

@ -58,14 +58,31 @@ func TestTerminate(t *testing.T) {
testCases := map[string]struct {
idFile clusterid.File
yesFlag bool
stdin string
setupFs func(*require.Assertions, clusterid.File) afero.Fs
terminator spyCloudTerminator
wantErr bool
wantAbort bool
}{
"success": {
idFile: clusterid.File{CloudProvider: cloudprovider.GCP},
setupFs: setupFs,
terminator: &stubCloudTerminator{},
yesFlag: true,
},
"interactive": {
idFile: clusterid.File{CloudProvider: cloudprovider.GCP},
setupFs: setupFs,
terminator: &stubCloudTerminator{},
stdin: "yes\n",
},
"interactive abort": {
idFile: clusterid.File{CloudProvider: cloudprovider.GCP},
setupFs: setupFs,
terminator: &stubCloudTerminator{},
stdin: "no\n",
wantAbort: true,
},
"files to remove do not exist": {
idFile: clusterid.File{CloudProvider: cloudprovider.GCP},
@ -76,11 +93,13 @@ func TestTerminate(t *testing.T) {
return fs
},
terminator: &stubCloudTerminator{},
yesFlag: true,
},
"terminate error": {
idFile: clusterid.File{CloudProvider: cloudprovider.GCP},
setupFs: setupFs,
terminator: &stubCloudTerminator{terminateErr: someErr},
yesFlag: true,
wantErr: true,
},
"missing id file does not error": {
@ -92,6 +111,7 @@ func TestTerminate(t *testing.T) {
return fs
},
terminator: &stubCloudTerminator{},
yesFlag: true,
},
"remove file fails": {
idFile: clusterid.File{CloudProvider: cloudprovider.GCP},
@ -100,6 +120,7 @@ func TestTerminate(t *testing.T) {
return afero.NewReadOnlyFs(fs)
},
terminator: &stubCloudTerminator{},
yesFlag: true,
wantErr: true,
},
}
@ -112,22 +133,31 @@ func TestTerminate(t *testing.T) {
cmd := NewTerminateCmd()
cmd.SetOut(&bytes.Buffer{})
cmd.SetErr(&bytes.Buffer{})
cmd.SetIn(bytes.NewBufferString(tc.stdin))
require.NotNil(tc.setupFs)
fileHandler := file.NewHandler(tc.setupFs(require, tc.idFile))
if tc.yesFlag {
require.NoError(cmd.Flags().Set("yes", "true"))
}
err := terminate(cmd, tc.terminator, fileHandler, nopSpinner{})
if tc.wantErr {
assert.Error(err)
} else {
assert.NoError(err)
if tc.wantAbort {
assert.False(tc.terminator.Called())
} else {
assert.True(tc.terminator.Called())
_, err = fileHandler.Stat(constants.AdminConfFilename)
assert.Error(err)
_, err = fileHandler.Stat(constants.ClusterIDsFileName)
assert.Error(err)
}
}
})
}
}