Skip to content

Commit

Permalink
Add flags to skip prompting and more unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ndhanushkodi committed Sep 15, 2021
1 parent d72f6a2 commit 2a6b8ff
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 67 deletions.
50 changes: 34 additions & 16 deletions cli/cmd/uninstall/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ const (
FlagReleaseName = "name"
DefaultAnyReleaseName = ""

FlagWipeAllData = "wipe-all-data"
DefaultWipeAllData = false
//this is the auto-approve for wipe all data
// todo auto-approve to NOT wipe all data
FlagWipeData = "wipe-data"
DefaultWipeData = false

FlagSkipWipeData = "skip-wipe-data"
DefaultSkipWipeData = false
)

type Command struct {
Expand All @@ -40,10 +41,11 @@ type Command struct {

set *flag.Sets

flagNamespace string
flagReleaseName string
flagAutoApprove bool
flagWipeAllData bool
flagNamespace string
flagReleaseName string
flagAutoApprove bool
flagWipeData bool
flagSkipWipeData bool

flagKubeConfig string
flagKubeContext string
Expand All @@ -60,19 +62,29 @@ func (c *Command) init() {
Name: FlagAutoApprove,
Target: &c.flagAutoApprove,
Default: DefaultAutoApprove,
Usage: "Skip confirmation prompt.",
Usage: "Skip approval prompt for uninstalling Consul.",
})
// This is like the auto-approve to wipe all data without prompting for non-interactive environments that want
// to remove everything.
f.BoolVar(&flag.BoolVar{
Name: FlagWipeData,
Target: &c.flagWipeData,
Default: DefaultWipeData,
Usage: "Delete all PVCs, Secrets, and Service Accounts associated with Consul Helm installation without prompting for approval to delete. Only use this when persisted data from previous installations is no longer necessary.",
})
// This is like the auto-approve to NOT wipe all data without prompting for non-interactive environments that
// only want to remove the Consul Helm installation but keep the data.
f.BoolVar(&flag.BoolVar{
Name: FlagWipeAllData,
Target: &c.flagWipeAllData,
Default: DefaultWipeAllData,
Usage: "Will NOT prompt for approval before delete all PVCs, Secrets, and Service Accounts associated with Consul Helm installation. Only use this when persisted data from previous installations is no longer necessary.",
Name: FlagSkipWipeData,
Target: &c.flagSkipWipeData,
Default: DefaultSkipWipeData,
Usage: "Skip deleting all PVCs, Secrets, and Service Accounts associated with Consul Helm installation without prompting for approval to delete.",
})
f.StringVar(&flag.StringVar{
Name: FlagNamespace,
Target: &c.flagNamespace,
Default: DefaultAllNamespaces,
Usage: fmt.Sprintf("Namespace for the Consul installation. Defaults to \"%q\".", DefaultAllNamespaces),
Usage: "Namespace for the Consul installation.",
})
f.StringVar(&flag.StringVar{
Name: FlagReleaseName,
Expand Down Expand Up @@ -214,6 +226,11 @@ func (c *Command) Run(args []string) int {
}
}

if c.flagSkipWipeData {
c.UI.Output("Skipping deleting PVCs, secrets, and service accounts.", terminal.WithSuccessStyle())
return 0
}

// At this point, even if no Helm release was found and uninstalled, there could
// still be PVCs, Secrets, and Service Accounts left behind from a previous installation.
// If there isn't a foundReleaseName and foundReleaseNamespace, we'll use the values of the
Expand All @@ -228,8 +245,9 @@ func (c *Command) Run(args []string) int {
foundReleaseNamespace = c.flagNamespace
}

// Prompt with a warning for approval before deleting PVCs, Secrets and ServiceAccounts.
if !c.flagWipeAllData {
// Prompt with a warning for approval before deleting PVCs, Secrets and ServiceAccounts. If flagWipeData is true,
// then it will proceed to delete those without a prompt.
if !c.flagWipeData {
confirmation, err := c.UI.Input(&terminal.Input{
Prompt: "WARNING: Proceed with deleting PVCs, Secrets, and ServiceAccounts? \n Only approve if all data from previous installation can be deleted (y/n)",
Style: terminal.WarningStyle,
Expand Down
114 changes: 63 additions & 51 deletions cli/cmd/uninstall/uninstall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,6 @@ func getInitializedCommand(t *testing.T) *Command {
return c
}

// TestDebugger is used to play with install.go for ad-hoc testing.
//func TestDebugger(t *testing.T) {
// c := getInitializedCommand(t)
// c.Run([]string{"-auto-approve", "-f=../../config.yaml"})
//}

func TestDeletePVCs(t *testing.T) {
c := getInitializedCommand(t)
c.kubernetes = fake.NewSimpleClientset()
Expand All @@ -61,55 +55,73 @@ func TestDeletePVCs(t *testing.T) {
},
},
}
c.kubernetes.CoreV1().PersistentVolumeClaims("default").Create(context.TODO(), pvc, metav1.CreateOptions{})
c.kubernetes.CoreV1().PersistentVolumeClaims("default").Create(context.TODO(), pvc2, metav1.CreateOptions{})
err := c.deletePVCs("consul", "default")
_, err := c.kubernetes.CoreV1().PersistentVolumeClaims("default").Create(context.TODO(), pvc, metav1.CreateOptions{})
require.NoError(t, err)
_, err = c.kubernetes.CoreV1().PersistentVolumeClaims("default").Create(context.TODO(), pvc2, metav1.CreateOptions{})
require.NoError(t, err)
err = c.deletePVCs("consul", "default")
require.NoError(t, err)
pvcs, err := c.kubernetes.CoreV1().PersistentVolumeClaims("default").List(context.TODO(), metav1.ListOptions{})
require.NoError(t, err)
require.Len(t, pvcs.Items, 0)
}

// Clear out the client and make sure the check now passes.
//c.kubernetes = fake.NewSimpleClientset()
//err = c.checkForPreviousPVCs()
//require.NoError(t, err)

// Add a new irrelevant PVC and make sure the check continues to pass.
//pvc = &v1.PersistentVolumeClaim{
// ObjectMeta: metav1.ObjectMeta{
// Name: "irrelevant-pvc",
// },
//}
//c.kubernetes.CoreV1().PersistentVolumeClaims("default").Create(context.TODO(), pvc, metav1.CreateOptions{})
//err = c.checkForPreviousPVCs()
//require.NoError(t, err)
func TestDeleteSecrets(t *testing.T) {
c := getInitializedCommand(t)
c.kubernetes = fake.NewSimpleClientset()
secret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "consul-test-secret1",
Labels: map[string]string{
"release": "consul",
},
},
}
secret2 := &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: "consul-test-secret2",
Labels: map[string]string{
"release": "consul",
},
},
}
_, err := c.kubernetes.CoreV1().Secrets("default").Create(context.TODO(), secret, metav1.CreateOptions{})
require.NoError(t, err)
_, err = c.kubernetes.CoreV1().Secrets("default").Create(context.TODO(), secret2, metav1.CreateOptions{})
require.NoError(t, err)
err = c.deleteSecrets("consul", "default")
require.NoError(t, err)
secrets, err := c.kubernetes.CoreV1().Secrets("default").List(context.TODO(), metav1.ListOptions{})
require.NoError(t, err)
require.Len(t, secrets.Items, 0)
}

//func TestCheckForPreviousSecrets(t *testing.T) {
// c := getInitializedCommand(t)
// c.kubernetes = fake.NewSimpleClientset()
// secret := &v1.Secret{
// ObjectMeta: metav1.ObjectMeta{
// Name: "test-consul-bootstrap-acl-token",
// },
// }
// c.kubernetes.CoreV1().Secrets("default").Create(context.TODO(), secret, metav1.CreateOptions{})
// err := c.checkForPreviousSecrets()
// require.Error(t, err)
// require.Contains(t, err.Error(), "found consul-acl-bootstrap-token secret from previous installations: \"test-consul-bootstrap-acl-token\" in namespace \"default\". To delete, run kubectl delete secret test-consul-bootstrap-acl-token --namespace default")
//
// // Clear out the client and make sure the check now passes.
// c.kubernetes = fake.NewSimpleClientset()
// err = c.checkForPreviousSecrets()
// require.NoError(t, err)
//
// // Add a new irrelevant secret and make sure the check continues to pass.
// secret = &v1.Secret{
// ObjectMeta: metav1.ObjectMeta{
// Name: "irrelevant-secret",
// },
// }
// c.kubernetes.CoreV1().Secrets("default").Create(context.TODO(), secret, metav1.CreateOptions{})
// err = c.checkForPreviousSecrets()
// require.NoError(t, err)
//}
func TestDeleteServiceAccounts(t *testing.T) {
c := getInitializedCommand(t)
c.kubernetes = fake.NewSimpleClientset()
sa := &v1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "consul-test-sa1",
Labels: map[string]string{
"release": "consul",
},
},
}
sa2 := &v1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: "consul-test-sa2",
Labels: map[string]string{
"release": "consul",
},
},
}
_, err := c.kubernetes.CoreV1().ServiceAccounts("default").Create(context.TODO(), sa, metav1.CreateOptions{})
require.NoError(t, err)
_, err = c.kubernetes.CoreV1().ServiceAccounts("default").Create(context.TODO(), sa2, metav1.CreateOptions{})
require.NoError(t, err)
err = c.deleteServiceAccounts("consul", "default")
require.NoError(t, err)
sas, err := c.kubernetes.CoreV1().ServiceAccounts("default").List(context.TODO(), metav1.ListOptions{})
require.NoError(t, err)
require.Len(t, sas.Items, 0)
}

0 comments on commit 2a6b8ff

Please sign in to comment.