Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(delete): Refactor input handling & output display on resource deletion #323

Merged
merged 4 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading