Skip to content

Commit d5d3a25

Browse files
authored
chore(cmd/cli): Reduce cyclomatic complexity of uninstall command (openservicemesh#4825)
* chore(cmd/cli): Reduce cyclomatic complexity of uninstall command Separate code into functions to reduce the cyclomatic complexity And adds unit tests to functions created Helps unblock openservicemesh#4555 Signed-off-by: Shalier Xia <[email protected]>
1 parent 41139b9 commit d5d3a25

File tree

2 files changed

+289
-46
lines changed

2 files changed

+289
-46
lines changed

cmd/cli/uninstall_mesh.go

+76-46
Original file line numberDiff line numberDiff line change
@@ -74,18 +74,18 @@ func newUninstallMeshCmd(config *action.Configuration, in io.Reader, out io.Writ
7474
// get kubeconfig and initialize k8s client
7575
kubeconfig, err := settings.RESTClientGetter().ToRESTConfig()
7676
if err != nil {
77-
return errors.Errorf("Error fetching kubeconfig: %s", err)
77+
return fmt.Errorf("Error fetching kubeconfig: %s", err)
7878
}
7979
uninstall.config = kubeconfig
8080

8181
uninstall.clientSet, err = kubernetes.NewForConfig(kubeconfig)
8282
if err != nil {
83-
return errors.Errorf("Could not access Kubernetes cluster, check kubeconfig: %s", err)
83+
return fmt.Errorf("Could not access Kubernetes cluster, check kubeconfig: %s", err)
8484
}
8585

8686
uninstall.extensionsClientset, err = extensionsClientset.NewForConfig(kubeconfig)
8787
if err != nil {
88-
return errors.Errorf("Could not access extension client set: %s", err)
88+
return fmt.Errorf("Could not access extension client set: %s", err)
8989
}
9090

9191
uninstall.meshNamespace = settings.Namespace()
@@ -118,10 +118,10 @@ func (d *uninstallMeshCmd) run() error {
118118
fmt.Fprintf(d.out, "No OSM control planes found\n")
119119
return nil
120120
}
121-
// Searches for the mesh specified by the mesh-name flag if specified
122-
specifiedMeshFound := false
123-
if d.meshName != "" {
124-
specifiedMeshFound = d.findMesh(meshInfoList)
121+
122+
if d.meshSpecified() {
123+
// Searches for the mesh specified by the mesh-name flag if specified
124+
specifiedMeshFound := d.findSpecifiedMesh(meshInfoList)
125125
if !specifiedMeshFound {
126126
return nil
127127
}
@@ -143,19 +143,11 @@ func (d *uninstallMeshCmd) run() error {
143143
return err
144144
}
145145
// Prompts user on whether to uninstall each OSM mesh in the cluster
146-
for _, mesh := range meshInfoList {
147-
// Only prompt for specified mesh if `mesh-name` is specified
148-
if specifiedMeshFound && mesh.name != d.meshName {
149-
continue
150-
}
151-
confirm, err := confirm(d.in, d.out, fmt.Sprintf("\nUninstall OSM [mesh name: %s] in namespace [%s] and/or OSM resources?", mesh.name, mesh.namespace), 3)
152-
if err != nil {
153-
return err
154-
}
155-
if confirm {
156-
meshesToUninstall = append(meshesToUninstall, mesh)
157-
}
146+
uninstallMeshes, err := d.promptMeshUninstall(meshInfoList, meshesToUninstall)
147+
if err != nil {
148+
return err
158149
}
150+
meshesToUninstall = append(meshesToUninstall, uninstallMeshes...)
159151
}
160152

161153
for _, m := range meshesToUninstall {
@@ -175,22 +167,16 @@ func (d *uninstallMeshCmd) run() error {
175167
return err
176168
}
177169

178-
fmt.Fprintf(d.out, "Error %v when trying to uninstall mesh name [%s] in namespace [%s] - continuing to deleteClusterWideResources and/or deleteNamespace\n", err, m.name, m.namespace)
170+
fmt.Fprintf(d.out, "Could not uninstall mesh name [%s] in namespace [%s]- %v - continuing to deleteClusterWideResources and/or deleteNamespace\n", m.name, m.namespace, err)
179171
}
180172

181173
if err == nil {
182174
fmt.Fprintf(d.out, "OSM [mesh name: %s] in namespace [%s] uninstalled\n", m.name, m.namespace)
183175
}
184176

185-
if d.deleteNamespace {
186-
if err := d.clientSet.CoreV1().Namespaces().Delete(ctx, m.namespace, v1.DeleteOptions{}); err != nil {
187-
if k8sApiErrors.IsNotFound(err) {
188-
fmt.Fprintf(d.out, "OSM namespace [%s] not found\n", m.namespace)
189-
return nil
190-
}
191-
return errors.Errorf("Error occurred while deleting OSM namespace [%s] - %v", m.namespace, err)
192-
}
193-
fmt.Fprintf(d.out, "OSM namespace [%s] deleted successfully\n", m.namespace)
177+
err = d.deleteNs(ctx, m.namespace)
178+
if err != nil {
179+
return err
194180
}
195181
}
196182
} else {
@@ -199,6 +185,61 @@ func (d *uninstallMeshCmd) run() error {
199185
fmt.Fprintf(d.out, "OSM namespace CANNOT be deleted in a managed environment\n")
200186
}
201187
}
188+
189+
err := d.deleteClusterResources()
190+
return err
191+
}
192+
193+
func (d *uninstallMeshCmd) meshSpecified() bool {
194+
return d.meshName != ""
195+
}
196+
197+
func (d *uninstallMeshCmd) findSpecifiedMesh(meshInfoList []meshInfo) bool {
198+
specifiedMeshFound := d.findMesh(meshInfoList)
199+
if !specifiedMeshFound {
200+
fmt.Fprintf(d.out, "Did not find mesh [%s] in namespace [%s]\n", d.meshName, d.meshNamespace)
201+
// print a list of meshes within the cluster for a better user experience
202+
if err := d.printMeshes(); err != nil {
203+
fmt.Fprintf(d.out, "Unable to list meshes in the cluster - [%v]", err)
204+
}
205+
}
206+
207+
return specifiedMeshFound
208+
}
209+
210+
func (d *uninstallMeshCmd) promptMeshUninstall(meshInfoList, meshesToUninstall []meshInfo) ([]meshInfo, error) {
211+
for _, mesh := range meshInfoList {
212+
// Only prompt for specified mesh if `mesh-name` is specified
213+
if d.meshSpecified() && mesh.name != d.meshName {
214+
continue
215+
}
216+
confirm, err := confirm(d.in, d.out, fmt.Sprintf("\nUninstall OSM [mesh name: %s] in namespace [%s] and/or OSM resources?", mesh.name, mesh.namespace), 3)
217+
if err != nil {
218+
return nil, err
219+
}
220+
if confirm {
221+
meshesToUninstall = append(meshesToUninstall, mesh)
222+
}
223+
}
224+
return meshesToUninstall, nil
225+
}
226+
227+
func (d *uninstallMeshCmd) deleteNs(ctx context.Context, ns string) error {
228+
if !d.deleteNamespace {
229+
return nil
230+
}
231+
if err := d.clientSet.CoreV1().Namespaces().Delete(ctx, ns, v1.DeleteOptions{}); err != nil {
232+
if k8sApiErrors.IsNotFound(err) {
233+
fmt.Fprintf(d.out, "OSM namespace [%s] not found\n", ns)
234+
return nil
235+
}
236+
return fmt.Errorf("Could not delete OSM namespace [%s] - %v", ns, err)
237+
}
238+
fmt.Fprintf(d.out, "OSM namespace [%s] deleted successfully\n", ns)
239+
return nil
240+
}
241+
242+
func (d *uninstallMeshCmd) deleteClusterResources() error {
202243
if d.deleteClusterWideResources {
203244
meshInfoList, err := getMeshInfoList(d.config, d.clientSet)
204245
if err != nil {
@@ -213,10 +254,9 @@ func (d *uninstallMeshCmd) run() error {
213254

214255
failedDeletions := d.uninstallClusterResources()
215256
if len(failedDeletions) != 0 {
216-
return errors.Errorf("Failed to completely delete the following OSM resource types: %+v", failedDeletions)
257+
return fmt.Errorf("Failed to completely delete the following OSM resource types: %+v", failedDeletions)
217258
}
218259
}
219-
220260
return nil
221261
}
222262

@@ -278,7 +318,7 @@ func (d *uninstallMeshCmd) uninstallCustomResourceDefinitions() error {
278318
}
279319

280320
if len(failedDeletions) != 0 {
281-
return errors.Errorf("Failed to delete the following OSM CRDs: %+v", failedDeletions)
321+
return fmt.Errorf("Failed to delete the following OSM CRDs: %+v", failedDeletions)
282322
}
283323

284324
return nil
@@ -325,7 +365,7 @@ func (d *uninstallMeshCmd) uninstallMutatingWebhookConfigurations() error {
325365
}
326366

327367
if len(failedDeletions) != 0 {
328-
return errors.Errorf("Found but failed to delete the following OSM MutatingWebhookConfigurations: %+v", failedDeletions)
368+
return fmt.Errorf("Found but failed to delete the following OSM MutatingWebhookConfigurations: %+v", failedDeletions)
329369
}
330370

331371
return nil
@@ -373,7 +413,7 @@ func (d *uninstallMeshCmd) uninstallValidatingWebhookConfigurations() error {
373413
}
374414

375415
if len(failedDeletions) != 0 {
376-
return errors.Errorf("Found but failed to delete the following OSM ValidatingWebhookConfigurations: %+v", failedDeletions)
416+
return fmt.Errorf("Found but failed to delete the following OSM ValidatingWebhookConfigurations: %+v", failedDeletions)
377417
}
378418

379419
return nil
@@ -407,7 +447,7 @@ func (d *uninstallMeshCmd) uninstallSecrets() error {
407447
}
408448

409449
if len(failedDeletions) != 0 {
410-
return errors.Errorf("Found but failed to delete the following OSM secrets in namespace %s: %+v", d.meshNamespace, failedDeletions)
450+
return fmt.Errorf("Found but failed to delete the following OSM secrets in namespace %s: %+v", d.meshNamespace, failedDeletions)
411451
}
412452

413453
return nil
@@ -422,17 +462,7 @@ func (d *uninstallMeshCmd) findMesh(meshInfoList []meshInfo) bool {
422462
break
423463
}
424464
}
425-
if found {
426-
return true
427-
}
428-
429-
fmt.Fprintf(d.out, "Did not find mesh [%s] in namespace [%s]\n", d.meshName, d.meshNamespace)
430-
// print a list of meshes within the cluster for a better user experience
431-
err := d.printMeshes()
432-
if err != nil {
433-
fmt.Fprintf(d.out, "Unable to list meshes in the cluster - [%v]", err)
434-
}
435-
return false
465+
return found
436466
}
437467

438468
// printMeshes prints list of meshes within the cluster for a better user experience

0 commit comments

Comments
 (0)