Skip to content

Commit

Permalink
fix(delete): Refactor input handling & output display on resource del…
Browse files Browse the repository at this point in the history
…etion (#323)

* fix: Remove newline char from input buffer

* refactor: Reorder deletion logic before grouping to fix output issue

* refactor: Update DeleteResource() logic and rename

* test: Update DeleteResourceTest() with []ResourceInfo objectes
  • Loading branch information
doronkg committed Jun 24, 2024
1 parent 048a872 commit bc2cca8
Show file tree
Hide file tree
Showing 22 changed files with 123 additions and 163 deletions.
10 changes: 5 additions & 5 deletions pkg/kor/clusterroles.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,18 +191,18 @@ func GetUnusedClusterRoles(filterOpts *filters.Options, clientset kubernetes.Int
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to process cluster role : %v\n", err)
}
if opts.DeleteFlag {
if diff, err = DeleteResource(diff, clientset, "", "ClusterRole", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete clusterRole %s : %v\n", diff, err)
}
}
switch opts.GroupBy {
case "namespace":
resources[""] = make(map[string][]ResourceInfo)
resources[""]["ClusterRole"] = diff
case "resource":
appendResources(resources, "ClusterRole", "", diff)
}
if opts.DeleteFlag {
if diff, err = DeleteResource2(diff, clientset, "", "ClusterRole", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete clusterRole %s : %v\n", diff, err)
}
}

var outputBuffer bytes.Buffer
var jsonResponse []byte
Expand Down
10 changes: 5 additions & 5 deletions pkg/kor/configmaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,18 +166,18 @@ func GetUnusedConfigmaps(filterOpts *filters.Options, clientset kubernetes.Inter
fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err)
continue
}
if opts.DeleteFlag {
if diff, err = DeleteResource(diff, clientset, namespace, "ConfigMap", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete ConfigMap %s in namespace %s: %v\n", diff, namespace, err)
}
}
switch opts.GroupBy {
case "namespace":
resources[namespace] = make(map[string][]ResourceInfo)
resources[namespace]["ConfigMap"] = diff
case "resource":
appendResources(resources, "ConfigMap", namespace, diff)
}
if opts.DeleteFlag {
if diff, err = DeleteResource2(diff, clientset, namespace, "ConfigMap", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete ConfigMap %s in namespace %s: %v\n", diff, namespace, err)
}
}
}

var outputBuffer bytes.Buffer
Expand Down
10 changes: 5 additions & 5 deletions pkg/kor/daemonsets.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,18 @@ func GetUnusedDaemonSets(filterOpts *filters.Options, clientset kubernetes.Inter
fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err)
continue
}
if opts.DeleteFlag {
if diff, err = DeleteResource(diff, clientset, namespace, "DaemonSet", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete DaemonSet %s in namespace %s: %v\n", diff, namespace, err)
}
}
switch opts.GroupBy {
case "namespace":
resources[namespace] = make(map[string][]ResourceInfo)
resources[namespace]["DaemonSet"] = diff
case "resource":
appendResources(resources, "DaemonSet", namespace, diff)
}
if opts.DeleteFlag {
if diff, err = DeleteResource2(diff, clientset, namespace, "DaemonSet", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete DaemonSet %s in namespace %s: %v\n", diff, namespace, err)
}
}
}

var outputBuffer bytes.Buffer
Expand Down
57 changes: 3 additions & 54 deletions pkg/kor/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,58 +270,7 @@ func DeleteResourceWithFinalizer(resources []ResourceInfo, dynamicClient dynamic
return remainingResources, nil
}

func DeleteResource(diff []string, clientset kubernetes.Interface, namespace, resourceType string, noInteractive bool) ([]string, error) {
deletedDiff := []string{}

for _, resourceName := range diff {
deleteFunc, exists := DeleteResourceCmd()[resourceType]
if !exists {
fmt.Printf("Resource type '%s' is not supported\n", resourceName)
continue
}

if !noInteractive {
fmt.Printf("Do you want to delete %s %s in namespace %s? (Y/N): ", resourceType, resourceName, namespace)
var confirmation string
_, err := fmt.Scanf("%s", &confirmation)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to read input: %v\n", err)
continue
}

if strings.ToLower(confirmation) != "y" && strings.ToLower(confirmation) != "yes" {
deletedDiff = append(deletedDiff, resourceName)

fmt.Printf("Do you want flag the resource %s %s in namespace %s as In Use? (Y/N): ", resourceType, resourceName, namespace)
var inUse string
_, err := fmt.Scanf("%s", &inUse)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to read input: %v\n", err)
continue
}

if strings.ToLower(inUse) == "y" || strings.ToLower(inUse) == "yes" {
if err := FlagResource(clientset, namespace, resourceType, resourceName); err != nil {
fmt.Fprintf(os.Stderr, "Failed to flag resource %s %s in namespace %s as In Use: %v\n", resourceType, resourceName, namespace, err)
}
continue
}
continue
}
}

fmt.Printf("Deleting %s %s in namespace %s\n", resourceType, resourceName, namespace)
if err := deleteFunc(clientset, namespace, resourceName); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete %s %s in namespace %s: %v\n", resourceType, resourceName, namespace, err)
continue
}
deletedDiff = append(deletedDiff, resourceName+"-DELETED")
}

return deletedDiff, nil
}

func DeleteResource2(diff []ResourceInfo, clientset kubernetes.Interface, namespace, resourceType string, noInteractive bool) ([]ResourceInfo, error) {
func DeleteResource(diff []ResourceInfo, clientset kubernetes.Interface, namespace, resourceType string, noInteractive bool) ([]ResourceInfo, error) {
deletedDiff := []ResourceInfo{}

for _, resource := range diff {
Expand All @@ -334,7 +283,7 @@ func DeleteResource2(diff []ResourceInfo, clientset kubernetes.Interface, namesp
if !noInteractive {
fmt.Printf("Do you want to delete %s %s in namespace %s? (Y/N): ", resourceType, resource.Name, namespace)
var confirmation string
_, err := fmt.Scanf("%s", &confirmation)
_, err := fmt.Scanf("%s\n", &confirmation)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to read input: %v\n", err)
continue
Expand All @@ -345,7 +294,7 @@ func DeleteResource2(diff []ResourceInfo, clientset kubernetes.Interface, namesp

fmt.Printf("Do you want flag the resource %s %s in namespace %s as In Use? (Y/N): ", resourceType, resource.Name, namespace)
var inUse string
_, err := fmt.Scanf("%s", &inUse)
_, err := fmt.Scanf("%s\n", &inUse)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to read input: %v\n", err)
continue
Expand Down
32 changes: 24 additions & 8 deletions pkg/kor/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,42 @@ import (
func TestDeleteResource(t *testing.T) {
clientset := fake.NewSimpleClientset()

configmap1 := CreateTestConfigmap(testNamespace, "configmap-1", AppLabels)
_, err := clientset.CoreV1().ConfigMaps(testNamespace).Create(context.TODO(), configmap1, metav1.CreateOptions{})
if err != nil {
t.Fatalf("Error creating fake configmap: %v", err)
}
configmap2 := CreateTestConfigmap(testNamespace, "configmap-2", AppLabels)
_, err = clientset.CoreV1().ConfigMaps(testNamespace).Create(context.TODO(), configmap2, metav1.CreateOptions{})
if err != nil {
t.Fatalf("Error creating fake configmap: %v", err)
}

tests := []struct {
name string
diff []string
diff []ResourceInfo
resourceType string
expectedDiff []string
expectedDiff []ResourceInfo
expectedError bool
}{
{
name: "Test deletion confirmation",
diff: []string{"resource1", "resource2"},
resourceType: "ConfigMap",
expectedDiff: []string{"resource1-DELETED", "resource2"},
name: "Test deletion confirmation",
diff: []ResourceInfo{
{Name: configmap1.Name, Reason: "ConfigMap is not used in any pod or container"},
{Name: configmap2.Name, Reason: "Marked with unused label"},
},
resourceType: "ConfigMap",
expectedDiff: []ResourceInfo{
{Name: configmap1.Name + "-DELETED", Reason: "ConfigMap is not used in any pod or container"},
{Name: configmap2.Name + "-DELETED", Reason: "Marked with unused label"},
},
expectedError: false,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
deletedDiff, _ := DeleteResource(test.diff, clientset, "namespace", test.resourceType, true)

deletedDiff, _ := DeleteResource(test.diff, clientset, testNamespace, test.resourceType, true)
for i, deleted := range deletedDiff {
if deleted != test.expectedDiff[i] {
t.Errorf("Expected: %s, Got: %s", test.expectedDiff[i], deleted)
Expand Down
10 changes: 5 additions & 5 deletions pkg/kor/deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ func GetUnusedDeployments(filterOpts *filters.Options, clientset kubernetes.Inte
fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err)
continue
}
if opts.DeleteFlag {
if diff, err = DeleteResource(diff, clientset, namespace, "Deployment", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete Deployment %s in namespace %s: %v\n", diff, namespace, err)
}
}
switch opts.GroupBy {
case "namespace":
resources[namespace] = make(map[string][]ResourceInfo)
resources[namespace]["Deployment"] = diff
case "resource":
appendResources(resources, "Deployment", namespace, diff)
}
if opts.DeleteFlag {
if diff, err = DeleteResource2(diff, clientset, namespace, "Deployment", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete Deployment %s in namespace %s: %v\n", diff, namespace, err)
}
}
}

var outputBuffer bytes.Buffer
Expand Down
10 changes: 5 additions & 5 deletions pkg/kor/hpas.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,18 @@ func GetUnusedHpas(filterOpts *filters.Options, clientset kubernetes.Interface,
fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err)
continue
}
if opts.DeleteFlag {
if diff, err = DeleteResource(diff, clientset, namespace, "HPA", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete HPA %s in namespace %s: %v\n", diff, namespace, err)
}
}
switch opts.GroupBy {
case "namespace":
resources[namespace] = make(map[string][]ResourceInfo)
resources[namespace]["Hpa"] = diff
case "resource":
appendResources(resources, "Hpa", namespace, diff)
}
if opts.DeleteFlag {
if diff, err = DeleteResource2(diff, clientset, namespace, "HPA", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete HPA %s in namespace %s: %v\n", diff, namespace, err)
}
}
}

var outputBuffer bytes.Buffer
Expand Down
10 changes: 5 additions & 5 deletions pkg/kor/ingresses.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,18 @@ func GetUnusedIngresses(filterOpts *filters.Options, clientset kubernetes.Interf
fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err)
continue
}
if opts.DeleteFlag {
if diff, err = DeleteResource(diff, clientset, namespace, "Ingress", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete Ingress %s in namespace %s: %v\n", diff, namespace, err)
}
}
switch opts.GroupBy {
case "namespace":
resources[namespace] = make(map[string][]ResourceInfo)
resources[namespace]["Ingress"] = diff
case "resource":
appendResources(resources, "Ingress", namespace, diff)
}
if opts.DeleteFlag {
if diff, err = DeleteResource2(diff, clientset, namespace, "Ingress", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete Ingress %s in namespace %s: %v\n", diff, namespace, err)
}
}
}

var outputBuffer bytes.Buffer
Expand Down
10 changes: 5 additions & 5 deletions pkg/kor/jobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,18 @@ func GetUnusedJobs(filterOpts *filters.Options, clientset kubernetes.Interface,
fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err)
continue
}
if opts.DeleteFlag {
if diff, err = DeleteResource(diff, clientset, namespace, "Job", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete Job %s in namespace %s: %v\n", diff, namespace, err)
}
}
switch opts.GroupBy {
case "namespace":
resources[namespace] = make(map[string][]ResourceInfo)
resources[namespace]["Job"] = diff
case "resource":
appendResources(resources, "Job", namespace, diff)
}
if opts.DeleteFlag {
if diff, err = DeleteResource2(diff, clientset, namespace, "Job", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete Job %s in namespace %s: %v\n", diff, namespace, err)
}
}
}

var outputBuffer bytes.Buffer
Expand Down
2 changes: 1 addition & 1 deletion pkg/kor/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func GetUnusedMulti(resourceNames string, filterOpts *filters.Options, clientset

if opts.DeleteFlag {
for _, diff := range allDiffs {
if diff.diff, err = DeleteResource2(diff.diff, clientset, namespace, diff.resourceType, opts.NoInteractive); err != nil {
if diff.diff, err = DeleteResource(diff.diff, clientset, namespace, diff.resourceType, opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete %s %s in namespace %s: %v\n", diff.resourceType, diff.diff, namespace, err)
}
}
Expand Down
12 changes: 5 additions & 7 deletions pkg/kor/networkpolicies.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,18 @@ func GetUnusedNetworkPolicies(filterOpts *filters.Options, clientset kubernetes.
fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err)
continue
}

if opts.DeleteFlag {
if diff, err := DeleteResource(diff, clientset, namespace, "NetworkPolicy", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete NetworkPolicy %s in namespace %s: %v\n", diff, namespace, err)
}
}
switch opts.GroupBy {
case "namespace":
resources[namespace] = make(map[string][]ResourceInfo)
resources[namespace]["NetworkPolicy"] = diff
case "resource":
appendResources(resources, "NetworkPolicy", namespace, diff)
}

if opts.DeleteFlag {
if diff, err := DeleteResource2(diff, clientset, namespace, "NetworkPolicy", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete NetworkPolicy %s in namespace %s: %v\n", diff, namespace, err)
}
}
}

var outputBuffer bytes.Buffer
Expand Down
10 changes: 5 additions & 5 deletions pkg/kor/pdbs.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,18 @@ func GetUnusedPdbs(filterOpts *filters.Options, clientset kubernetes.Interface,
fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err)
continue
}
if opts.DeleteFlag {
if diff, err = DeleteResource(diff, clientset, namespace, "PDB", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete PDB %s in namespace %s: %v\n", diff, namespace, err)
}
}
switch opts.GroupBy {
case "namespace":
resources[namespace] = make(map[string][]ResourceInfo)
resources[namespace]["Pdb"] = diff
case "resource":
appendResources(resources, "Pdb", namespace, diff)
}
if opts.DeleteFlag {
if diff, err = DeleteResource2(diff, clientset, namespace, "PDB", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete PDB %s in namespace %s: %v\n", diff, namespace, err)
}
}
}

var outputBuffer bytes.Buffer
Expand Down
10 changes: 5 additions & 5 deletions pkg/kor/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,18 @@ func GetUnusedPods(filterOpts *filters.Options, clientset kubernetes.Interface,
fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err)
continue
}
if opts.DeleteFlag {
if diff, err = DeleteResource(diff, clientset, namespace, "Pod", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete Pod %s in namespace %s: %v\n", diff, namespace, err)
}
}
switch opts.GroupBy {
case "namespace":
resources[namespace] = make(map[string][]ResourceInfo)
resources[namespace]["Pod"] = diff
case "resource":
appendResources(resources, "Pod", namespace, diff)
}
if opts.DeleteFlag {
if diff, err = DeleteResource2(diff, clientset, namespace, "Pod", opts.NoInteractive); err != nil {
fmt.Fprintf(os.Stderr, "Failed to delete Pod %s in namespace %s: %v\n", diff, namespace, err)
}
}
}

var outputBuffer bytes.Buffer
Expand Down
Loading

0 comments on commit bc2cca8

Please sign in to comment.