diff --git a/cmd/kor/all.go b/cmd/kor/all.go index 3aaf7e51..402495d0 100644 --- a/cmd/kor/all.go +++ b/cmd/kor/all.go @@ -13,16 +13,12 @@ var allCmd = &cobra.Command{ Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedAllStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + + if response, err := kor.GetUnusedAll(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedAll(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } - }, } diff --git a/cmd/kor/configmaps.go b/cmd/kor/configmaps.go index 4d52e884..3e40fd8e 100644 --- a/cmd/kor/configmaps.go +++ b/cmd/kor/configmaps.go @@ -14,16 +14,11 @@ var configmapCmd = &cobra.Command{ Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedConfigmapsStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + if response, err := kor.GetUnusedConfigmaps(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedConfigmaps(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } - }, } diff --git a/cmd/kor/deployments.go b/cmd/kor/deployments.go index e56c01b7..35fd392e 100644 --- a/cmd/kor/deployments.go +++ b/cmd/kor/deployments.go @@ -14,16 +14,11 @@ var deployCmd = &cobra.Command{ Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedDeploymentsStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + if response, err := kor.GetUnusedDeployments(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedDeployments(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } - }, } diff --git a/cmd/kor/exporter.go b/cmd/kor/exporter.go index 5f8a8003..cd492263 100644 --- a/cmd/kor/exporter.go +++ b/cmd/kor/exporter.go @@ -11,7 +11,7 @@ var exporterCmd = &cobra.Command{ Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - kor.Exporter(includeExcludeLists, clientset, "json") + kor.Exporter(includeExcludeLists, clientset, "json", slackOpts) }, } diff --git a/cmd/kor/hpas.go b/cmd/kor/hpas.go index 35f074e3..0ab13a7d 100644 --- a/cmd/kor/hpas.go +++ b/cmd/kor/hpas.go @@ -14,15 +14,13 @@ var hpaCmd = &cobra.Command{ Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedHpasStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + + if response, err := kor.GetUnusedHpas(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedHpas(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } + }, } diff --git a/cmd/kor/ingresses.go b/cmd/kor/ingresses.go index f48c2cce..818119ec 100644 --- a/cmd/kor/ingresses.go +++ b/cmd/kor/ingresses.go @@ -14,14 +14,11 @@ var ingressCmd = &cobra.Command{ Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedIngressesStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + + if response, err := kor.GetUnusedIngresses(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedIngresses(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } }, } diff --git a/cmd/kor/pdbs.go b/cmd/kor/pdbs.go index 2b060495..956eb43a 100644 --- a/cmd/kor/pdbs.go +++ b/cmd/kor/pdbs.go @@ -14,16 +14,12 @@ var pdbCmd = &cobra.Command{ Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedPdbsStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + + if response, err := kor.GetUnusedPdbs(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedPdbs(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } - }, } diff --git a/cmd/kor/pvc.go b/cmd/kor/pvc.go index 2b4cfba1..acb3f32f 100644 --- a/cmd/kor/pvc.go +++ b/cmd/kor/pvc.go @@ -14,15 +14,13 @@ var pvcCmd = &cobra.Command{ Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedPvcsStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + + if response, err := kor.GetUnusedPvcs(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedPvcs(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } + }, } diff --git a/cmd/kor/roles.go b/cmd/kor/roles.go index 65087fe5..b260a784 100644 --- a/cmd/kor/roles.go +++ b/cmd/kor/roles.go @@ -14,16 +14,12 @@ var roleCmd = &cobra.Command{ Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedRolesStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + + if response, err := kor.GetUnusedRoles(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedRoles(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } - }, } diff --git a/cmd/kor/root.go b/cmd/kor/root.go index e26a76b8..80fa6303 100644 --- a/cmd/kor/root.go +++ b/cmd/kor/root.go @@ -48,7 +48,7 @@ func Execute() { rootCmd.PersistentFlags().StringVarP(&kubeconfig, "kubeconfig", "k", "", "Path to kubeconfig file (optional)") rootCmd.PersistentFlags().StringVarP(&includeExcludeLists.IncludeListStr, "include-namespaces", "n", "", "Namespaces to run on, splited by comma. Example: --include-namespace ns1,ns2,ns3. ") rootCmd.PersistentFlags().StringVarP(&includeExcludeLists.ExcludeListStr, "exclude-namespaces", "e", "", "Namespaces to be excluded, splited by comma. Example: --exclude-namespace ns1,ns2,ns3. If --include-namespace is set, --exclude-namespaces will be ignored.") - rootCmd.PersistentFlags().StringVar(&outputFormat, "output", "table", "Output format (table or json)") + rootCmd.PersistentFlags().StringVar(&outputFormat, "output", "table", "Output format (table, json or yaml)") rootCmd.PersistentFlags().StringVar(&slackOpts.WebhookURL, "slack-webhook-url", "", "Slack webhook URL to send notifications to") rootCmd.PersistentFlags().StringVar(&slackOpts.Channel, "slack-channel", "", "Slack channel to send notifications to. --slack-channel requires --slack-auth-token to be set.") rootCmd.PersistentFlags().StringVar(&slackOpts.Token, "slack-auth-token", "", "Slack auth token to send notifications to. --slack-auth-token requires --slack-channel to be set.") diff --git a/cmd/kor/secrets.go b/cmd/kor/secrets.go index 71397288..67efada7 100644 --- a/cmd/kor/secrets.go +++ b/cmd/kor/secrets.go @@ -14,16 +14,12 @@ var secretCmd = &cobra.Command{ Args: cobra.NoArgs, Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedSecretsStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + + if response, err := kor.GetUnusedSecrets(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedSecrets(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } - }, } diff --git a/cmd/kor/serviceaccounts.go b/cmd/kor/serviceaccounts.go index bdeca3db..4d706746 100644 --- a/cmd/kor/serviceaccounts.go +++ b/cmd/kor/serviceaccounts.go @@ -14,16 +14,12 @@ var serviceAccountCmd = &cobra.Command{ Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedServiceAccountsStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + + if response, err := kor.GetUnusedServiceAccounts(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedServiceAccounts(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } - }, } diff --git a/cmd/kor/services.go b/cmd/kor/services.go index d04ba6ba..b17e27d2 100644 --- a/cmd/kor/services.go +++ b/cmd/kor/services.go @@ -14,16 +14,12 @@ var serviceCmd = &cobra.Command{ Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedServicesStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + + if response, err := kor.GetUnusedServices(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedServices(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } - }, } diff --git a/cmd/kor/statefulsets.go b/cmd/kor/statefulsets.go index e8ffb14f..0affe8f2 100644 --- a/cmd/kor/statefulsets.go +++ b/cmd/kor/statefulsets.go @@ -14,16 +14,12 @@ var stsCmd = &cobra.Command{ Args: cobra.ExactArgs(0), Run: func(cmd *cobra.Command, args []string) { clientset := kor.GetKubeClient(kubeconfig) - if outputFormat == "json" || outputFormat == "yaml" { - if response, err := kor.GetUnusedStatefulSetsStructured(includeExcludeLists, clientset, outputFormat); err != nil { - fmt.Println(err) - } else { - fmt.Println(response) - } + + if response, err := kor.GetUnusedStatefulSets(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { + fmt.Println(err) } else { - kor.GetUnusedStatefulSets(includeExcludeLists, clientset, slackOpts) + fmt.Println(response) } - }, } diff --git a/pkg/kor/all.go b/pkg/kor/all.go index abbd0842..d82a482b 100644 --- a/pkg/kor/all.go +++ b/pkg/kor/all.go @@ -7,7 +7,6 @@ import ( "os" "k8s.io/client-go/kubernetes" - "sigs.k8s.io/yaml" ) type GetUnusedResourceJSONResponse struct { @@ -119,11 +118,12 @@ func getUnusedPdbs(clientset kubernetes.Interface, namespace string) ResourceDif return namespacePdbDiff } -func GetUnusedAll(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedAll(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { var allDiffs []ResourceDiff namespaceCMDiff := getUnusedCMs(clientset, namespace) @@ -153,61 +153,7 @@ func GetUnusedAll(includeExcludeLists IncludeExcludeLists, clientset kubernetes. outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedAllStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - - // Create the JSON response object - response := make(map[string]map[string][]string) - for _, namespace := range namespaces { - var allDiffs []ResourceDiff - - namespaceCMDiff := getUnusedCMs(clientset, namespace) - allDiffs = append(allDiffs, namespaceCMDiff) - - namespaceSVCDiff := getUnusedSVCs(clientset, namespace) - allDiffs = append(allDiffs, namespaceSVCDiff) - - namespaceSecretDiff := getUnusedSecrets(clientset, namespace) - allDiffs = append(allDiffs, namespaceSecretDiff) - - namespaceSADiff := getUnusedServiceAccounts(clientset, namespace) - allDiffs = append(allDiffs, namespaceSADiff) - - namespaceDeploymentDiff := getUnusedDeployments(clientset, namespace) - allDiffs = append(allDiffs, namespaceDeploymentDiff) - - namespaceStatefulsetDiff := getUnusedStatefulSets(clientset, namespace) - allDiffs = append(allDiffs, namespaceStatefulsetDiff) - - namespaceRoleDiff := getUnusedRoles(clientset, namespace) - allDiffs = append(allDiffs, namespaceRoleDiff) - - namespaceHpaDiff := getUnusedHpas(clientset, namespace) - allDiffs = append(allDiffs, namespaceHpaDiff) - - namespacePvcDiff := getUnusedPvcs(clientset, namespace) - allDiffs = append(allDiffs, namespacePvcDiff) - - namespaceIngressDiff := getUnusedIngresses(clientset, namespace) - allDiffs = append(allDiffs, namespaceIngressDiff) - - namespacePdbDiff := getUnusedPdbs(clientset, namespace) - allDiffs = append(allDiffs, namespacePdbDiff) - - // Store the unused resources for each resource type in the JSON response resourceMap := make(map[string][]string) for _, diff := range allDiffs { resourceMap[diff.resourceType] = diff.diff @@ -215,19 +161,15 @@ func GetUnusedAllStructured(includeExcludeLists IncludeExcludeLists, clientset k response[namespace] = resourceMap } - // Convert the response object to JSON jsonResponse, err := json.MarshalIndent(response, "", " ") if err != nil { return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedAll, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedAll, nil } diff --git a/pkg/kor/configmaps_test.go b/pkg/kor/configmaps_test.go index 3141c429..9a353ec2 100644 --- a/pkg/kor/configmaps_test.go +++ b/pkg/kor/configmaps_test.go @@ -176,7 +176,13 @@ func TestGetUnusedConfigmapsStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedConfigmapsStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedConfigmaps(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedConfigmapsStructured: %v", err) } diff --git a/pkg/kor/confimgmaps.go b/pkg/kor/confimgmaps.go index 8125e3c1..9484cb67 100644 --- a/pkg/kor/confimgmaps.go +++ b/pkg/kor/confimgmaps.go @@ -10,7 +10,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" - "sigs.k8s.io/yaml" ) var exceptionconfigmaps = []ExceptionResource{ @@ -129,11 +128,12 @@ func processNamespaceCM(clientset kubernetes.Interface, namespace string) ([]str } -func GetUnusedConfigmaps(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedConfigmaps(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := processNamespaceCM(clientset, namespace) if err != nil { @@ -144,28 +144,7 @@ func GetUnusedConfigmaps(includeExcludeLists IncludeExcludeLists, clientset kube outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedConfigmapsStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - for _, namespace := range namespaces { - diff, err := processNamespaceCM(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } resourceMap := make(map[string][]string) resourceMap["ConfigMap"] = diff response[namespace] = resourceMap @@ -176,14 +155,10 @@ func GetUnusedConfigmapsStructured(includeExcludeLists IncludeExcludeLists, clie return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedCMs, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + return unusedCMs, nil } diff --git a/pkg/kor/deployments.go b/pkg/kor/deployments.go index c5d84f22..2f0f3387 100644 --- a/pkg/kor/deployments.go +++ b/pkg/kor/deployments.go @@ -9,7 +9,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "sigs.k8s.io/yaml" ) func ProcessNamespaceDeployments(clientset kubernetes.Interface, namespace string) ([]string, error) { @@ -33,11 +32,12 @@ func ProcessNamespaceDeployments(clientset kubernetes.Interface, namespace strin return deploymentsWithoutReplicas, nil } -func GetUnusedDeployments(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedDeployments(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := ProcessNamespaceDeployments(clientset, namespace) if err != nil { @@ -48,28 +48,7 @@ func GetUnusedDeployments(includeExcludeLists IncludeExcludeLists, clientset kub outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedDeploymentsStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - - for _, namespace := range namespaces { - diff, err := ProcessNamespaceDeployments(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } resourceMap := make(map[string][]string) resourceMap["Deployments"] = diff response[namespace] = resourceMap @@ -80,13 +59,10 @@ func GetUnusedDeploymentsStructured(includeExcludeLists IncludeExcludeLists, cli return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedDeployments, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedDeployments, nil } diff --git a/pkg/kor/deployments_test.go b/pkg/kor/deployments_test.go index bed7ec90..7f3616e0 100644 --- a/pkg/kor/deployments_test.go +++ b/pkg/kor/deployments_test.go @@ -67,7 +67,13 @@ func TestGetUnusedDeploymentsStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedDeploymentsStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedDeployments(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedDeploymentsStructured: %v", err) } diff --git a/pkg/kor/exporter.go b/pkg/kor/exporter.go index e2180682..eed54098 100644 --- a/pkg/kor/exporter.go +++ b/pkg/kor/exporter.go @@ -28,16 +28,16 @@ func init() { } // TODO: add option to change port / url !? -func Exporter(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) { +func Exporter(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) { http.Handle("/metrics", promhttp.Handler()) fmt.Println("Server listening on :8080") - go exportMetrics(includeExcludeLists, clientset, outputFormat) // Start exporting metrics in the background + go exportMetrics(includeExcludeLists, clientset, outputFormat, slackOpts) // Start exporting metrics in the background if err := http.ListenAndServe(":8080", nil); err != nil { fmt.Println(err) } } -func exportMetrics(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) { +func exportMetrics(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) { exporterInterval := os.Getenv("EXPORTER_INTERVAL") if exporterInterval == "" { exporterInterval = "10" @@ -49,7 +49,7 @@ func exportMetrics(includeExcludeLists IncludeExcludeLists, clientset kubernetes } for { - if korOutput, err := GetUnusedAllStructured(includeExcludeLists, clientset, outputFormat); err != nil { + if korOutput, err := GetUnusedAll(includeExcludeLists, clientset, outputFormat, slackOpts); err != nil { fmt.Println(err) os.Exit(1) } else { diff --git a/pkg/kor/hpas.go b/pkg/kor/hpas.go index 7fc4bf17..5982d51d 100644 --- a/pkg/kor/hpas.go +++ b/pkg/kor/hpas.go @@ -11,7 +11,6 @@ import ( "k8s.io/client-go/kubernetes" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" "k8s.io/utils/strings/slices" - "sigs.k8s.io/yaml" ) func getDeploymentNames(clientset kubernetes.Interface, namespace string) ([]string, error) { @@ -80,11 +79,12 @@ func processNamespaceHpas(clientset kubernetes.Interface, namespace string) ([]s return unusedHpas, nil } -func GetUnusedHpas(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedHpas(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := processNamespaceHpas(clientset, namespace) if err != nil { @@ -95,34 +95,10 @@ func GetUnusedHpas(includeExcludeLists IncludeExcludeLists, clientset kubernetes outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedHpasStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - for _, namespace := range namespaces { - diff, err := processNamespaceHpas(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } - if len(diff) > 0 { - if response[namespace] == nil { - response[namespace] = make(map[string][]string) - } - response[namespace]["Hpa"] = diff - } + resourceMap := make(map[string][]string) + resourceMap["Hpa"] = diff + response[namespace] = resourceMap } jsonResponse, err := json.MarshalIndent(response, "", " ") @@ -130,13 +106,10 @@ func GetUnusedHpasStructured(includeExcludeLists IncludeExcludeLists, clientset return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedHpas, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedHpas, nil } diff --git a/pkg/kor/hpas_test.go b/pkg/kor/hpas_test.go index ab8a8bc7..00486f3b 100644 --- a/pkg/kor/hpas_test.go +++ b/pkg/kor/hpas_test.go @@ -75,7 +75,13 @@ func TestGetUnusedHpasStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedHpasStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedHpas(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedHpasStructured: %v", err) } diff --git a/pkg/kor/ingresses.go b/pkg/kor/ingresses.go index 22dbf8ab..1efe9fd5 100644 --- a/pkg/kor/ingresses.go +++ b/pkg/kor/ingresses.go @@ -11,7 +11,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" - "sigs.k8s.io/yaml" ) func validateServiceBackend(clientset kubernetes.Interface, namespace string, backend *v1.IngressBackend) bool { @@ -89,11 +88,12 @@ func processNamespaceIngresses(clientset kubernetes.Interface, namespace string) } -func GetUnusedIngresses(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedIngresses(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := processNamespaceIngresses(clientset, namespace) if err != nil { @@ -104,28 +104,7 @@ func GetUnusedIngresses(includeExcludeLists IncludeExcludeLists, clientset kuber outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedIngressesStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - - for _, namespace := range namespaces { - diff, err := processNamespaceIngresses(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } resourceMap := make(map[string][]string) resourceMap["Ingresses"] = diff response[namespace] = resourceMap @@ -136,13 +115,10 @@ func GetUnusedIngressesStructured(includeExcludeLists IncludeExcludeLists, clien return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedIngresses, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedIngresses, nil } diff --git a/pkg/kor/ingresses_test.go b/pkg/kor/ingresses_test.go index 7812098c..56827a77 100644 --- a/pkg/kor/ingresses_test.go +++ b/pkg/kor/ingresses_test.go @@ -79,7 +79,13 @@ func TestGetUnusedIngressesStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedIngressesStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedIngresses(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedIngressesStructured: %v", err) } diff --git a/pkg/kor/kor.go b/pkg/kor/kor.go index d2ebe91f..80f65749 100644 --- a/pkg/kor/kor.go +++ b/pkg/kor/kor.go @@ -15,6 +15,7 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/util/homedir" + "sigs.k8s.io/yaml" ) type ExceptionResource struct { @@ -125,7 +126,7 @@ func SetNamespaceList(namespaceLists IncludeExcludeLists, clientset kubernetes.I func FormatOutput(namespace string, resources []string, resourceType string) string { if len(resources) == 0 { - return fmt.Sprintf("No unused %s found in the namespace: %s", resourceType, namespace) + return fmt.Sprintf("No unused %s found in the namespace: %s \n", resourceType, namespace) } var buf bytes.Buffer @@ -189,3 +190,26 @@ func CalculateResourceDifference(usedResourceNames []string, allResourceNames [] } return difference } + +func unusedResourceFormatter(outputFormat string, outputBuffer bytes.Buffer, slackOpts SlackOpts, jsonResponse []byte) (string, error) { + if outputFormat == "table" { + + if slackOpts != (SlackOpts{}) { + if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { + fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) + os.Exit(1) + } + } else { + return outputBuffer.String(), nil + } + } else { + if outputFormat == "yaml" { + yamlResponse, err := yaml.JSONToYAML(jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) + } + return string(yamlResponse), nil + } + } + return string(jsonResponse), nil +} diff --git a/pkg/kor/pdbs.go b/pkg/kor/pdbs.go index 94075033..41c88191 100644 --- a/pkg/kor/pdbs.go +++ b/pkg/kor/pdbs.go @@ -10,7 +10,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" - "sigs.k8s.io/yaml" ) func processNamespacePdbs(clientset kubernetes.Interface, namespace string) ([]string, error) { @@ -49,11 +48,12 @@ func processNamespacePdbs(clientset kubernetes.Interface, namespace string) ([]s return unusedPdbs, nil } -func GetUnusedPdbs(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedPdbs(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := processNamespacePdbs(clientset, namespace) if err != nil { @@ -64,34 +64,10 @@ func GetUnusedPdbs(includeExcludeLists IncludeExcludeLists, clientset kubernetes outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedPdbsStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - - for _, namespace := range namespaces { - diff, err := processNamespacePdbs(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } - if len(diff) > 0 { - if response[namespace] == nil { - response[namespace] = make(map[string][]string) - } - response[namespace]["Pdb"] = diff - } + resourceMap := make(map[string][]string) + resourceMap["Pdb"] = diff + response[namespace] = resourceMap } jsonResponse, err := json.MarshalIndent(response, "", " ") @@ -99,13 +75,10 @@ func GetUnusedPdbsStructured(includeExcludeLists IncludeExcludeLists, clientset return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedPdbs, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedPdbs, nil } diff --git a/pkg/kor/pdbs_test.go b/pkg/kor/pdbs_test.go index cad29c2c..1a6d89d5 100644 --- a/pkg/kor/pdbs_test.go +++ b/pkg/kor/pdbs_test.go @@ -85,7 +85,13 @@ func TestGetUnusedPdbsStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedPdbsStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedPdbs(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedPdbsStructured: %v", err) } diff --git a/pkg/kor/pvc.go b/pkg/kor/pvc.go index b5a9b130..ca0c5f7f 100644 --- a/pkg/kor/pvc.go +++ b/pkg/kor/pvc.go @@ -10,7 +10,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" - "sigs.k8s.io/yaml" ) func retreiveUsedPvcs(clientset kubernetes.Interface, namespace string) ([]string, error) { @@ -54,11 +53,12 @@ func processNamespacePvcs(clientset kubernetes.Interface, namespace string) ([]s return diff, nil } -func GetUnusedPvcs(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedPvcs(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := processNamespacePvcs(clientset, namespace) if err != nil { @@ -69,34 +69,10 @@ func GetUnusedPvcs(includeExcludeLists IncludeExcludeLists, clientset kubernetes outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedPvcsStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - - for _, namespace := range namespaces { - diff, err := processNamespacePvcs(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } - if len(diff) > 0 { - if response[namespace] == nil { - response[namespace] = make(map[string][]string) - } - response[namespace]["Pvc"] = diff - } + resourceMap := make(map[string][]string) + resourceMap["Pvc"] = diff + response[namespace] = resourceMap } jsonResponse, err := json.MarshalIndent(response, "", " ") @@ -104,13 +80,10 @@ func GetUnusedPvcsStructured(includeExcludeLists IncludeExcludeLists, clientset return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedPvcs, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedPvcs, nil } diff --git a/pkg/kor/pvc_test.go b/pkg/kor/pvc_test.go index a0fd5cb5..b214fd1f 100644 --- a/pkg/kor/pvc_test.go +++ b/pkg/kor/pvc_test.go @@ -90,7 +90,13 @@ func TestGetUnusedPvcsStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedPvcsStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedPvcs(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedPvcsStructured: %v", err) } diff --git a/pkg/kor/roles.go b/pkg/kor/roles.go index 7bfb26db..5640af96 100644 --- a/pkg/kor/roles.go +++ b/pkg/kor/roles.go @@ -10,7 +10,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" - "sigs.k8s.io/yaml" ) func retrieveUsedRoles(clientset kubernetes.Interface, namespace string) ([]string, error) { @@ -67,11 +66,12 @@ func processNamespaceRoles(clientset kubernetes.Interface, namespace string) ([] } -func GetUnusedRoles(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedRoles(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := processNamespaceRoles(clientset, namespace) if err != nil { @@ -82,28 +82,7 @@ func GetUnusedRoles(includeExcludeLists IncludeExcludeLists, clientset kubernete outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedRolesStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - - for _, namespace := range namespaces { - diff, err := processNamespaceRoles(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } resourceMap := make(map[string][]string) resourceMap["Roles"] = diff response[namespace] = resourceMap @@ -114,13 +93,10 @@ func GetUnusedRolesStructured(includeExcludeLists IncludeExcludeLists, clientset return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedRoles, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedRoles, nil } diff --git a/pkg/kor/roles_test.go b/pkg/kor/roles_test.go index e4e61ae8..38636c5f 100644 --- a/pkg/kor/roles_test.go +++ b/pkg/kor/roles_test.go @@ -100,7 +100,13 @@ func TestGetUnusedRolesStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedRolesStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedRoles(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedRolesStructured: %v", err) } diff --git a/pkg/kor/secrets.go b/pkg/kor/secrets.go index e41a748c..fdef650f 100644 --- a/pkg/kor/secrets.go +++ b/pkg/kor/secrets.go @@ -11,7 +11,6 @@ import ( "k8s.io/client-go/kubernetes" _ "k8s.io/client-go/plugin/pkg/client/auth/oidc" "k8s.io/utils/strings/slices" - "sigs.k8s.io/yaml" ) var exceptionSecretTypes = []string{ @@ -141,11 +140,12 @@ func processNamespaceSecret(clientset kubernetes.Interface, namespace string) ([ } -func GetUnusedSecrets(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedSecrets(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := processNamespaceSecret(clientset, namespace) if err != nil { @@ -156,28 +156,7 @@ func GetUnusedSecrets(includeExcludeLists IncludeExcludeLists, clientset kuberne outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedSecretsStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - - for _, namespace := range namespaces { - diff, err := processNamespaceSecret(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } resourceMap := make(map[string][]string) resourceMap["Secrets"] = diff response[namespace] = resourceMap @@ -188,13 +167,10 @@ func GetUnusedSecretsStructured(includeExcludeLists IncludeExcludeLists, clients return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedSecrets, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedSecrets, nil } diff --git a/pkg/kor/secrets_test.go b/pkg/kor/secrets_test.go index 689218eb..b54acf88 100644 --- a/pkg/kor/secrets_test.go +++ b/pkg/kor/secrets_test.go @@ -244,7 +244,13 @@ func TestGetUnusedSecretsStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedSecretsStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedSecrets(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedSecretsStructured: %v", err) } diff --git a/pkg/kor/serviceaccounts.go b/pkg/kor/serviceaccounts.go index e0310255..31717a1a 100644 --- a/pkg/kor/serviceaccounts.go +++ b/pkg/kor/serviceaccounts.go @@ -9,7 +9,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "sigs.k8s.io/yaml" ) var exceptionServiceAccounts = []ExceptionResource{ @@ -140,11 +139,12 @@ func processNamespaceSA(clientset kubernetes.Interface, namespace string) ([]str } -func GetUnusedServiceAccounts(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedServiceAccounts(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := processNamespaceSA(clientset, namespace) if err != nil { @@ -155,28 +155,7 @@ func GetUnusedServiceAccounts(includeExcludeLists IncludeExcludeLists, clientset outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedServiceAccountsStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - - for _, namespace := range namespaces { - diff, err := processNamespaceSA(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } resourceMap := make(map[string][]string) resourceMap["ServiceAccounts"] = diff response[namespace] = resourceMap @@ -187,13 +166,10 @@ func GetUnusedServiceAccountsStructured(includeExcludeLists IncludeExcludeLists, return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedServiceAccounts, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedServiceAccounts, nil } diff --git a/pkg/kor/serviceaccounts_test.go b/pkg/kor/serviceaccounts_test.go index a7e00887..b03956b3 100644 --- a/pkg/kor/serviceaccounts_test.go +++ b/pkg/kor/serviceaccounts_test.go @@ -175,7 +175,13 @@ func TestGetUnusedServiceAccountsStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedServiceAccountsStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedServiceAccounts(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedServiceAccountsStructured: %v", err) } diff --git a/pkg/kor/services.go b/pkg/kor/services.go index ca0059aa..7124201f 100644 --- a/pkg/kor/services.go +++ b/pkg/kor/services.go @@ -9,7 +9,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "sigs.k8s.io/yaml" ) func ProcessNamespaceServices(clientset kubernetes.Interface, namespace string) ([]string, error) { @@ -33,11 +32,12 @@ func ProcessNamespaceServices(clientset kubernetes.Interface, namespace string) return endpointsWithoutSubsets, nil } -func GetUnusedServices(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedServices(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := ProcessNamespaceServices(clientset, namespace) if err != nil { @@ -48,28 +48,7 @@ func GetUnusedServices(includeExcludeLists IncludeExcludeLists, clientset kubern outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedServicesStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - - for _, namespace := range namespaces { - diff, err := ProcessNamespaceServices(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } resourceMap := make(map[string][]string) resourceMap["Services"] = diff response[namespace] = resourceMap @@ -80,13 +59,10 @@ func GetUnusedServicesStructured(includeExcludeLists IncludeExcludeLists, client return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedServices, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedServices, nil } diff --git a/pkg/kor/services_test.go b/pkg/kor/services_test.go index 4db5901e..9526b456 100644 --- a/pkg/kor/services_test.go +++ b/pkg/kor/services_test.go @@ -65,7 +65,13 @@ func TestGetUnusedServicesStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedServicesStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedServices(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedServicesStructured: %v", err) } diff --git a/pkg/kor/statefulsets.go b/pkg/kor/statefulsets.go index ead07c44..8eaaa105 100644 --- a/pkg/kor/statefulsets.go +++ b/pkg/kor/statefulsets.go @@ -9,7 +9,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "sigs.k8s.io/yaml" ) func ProcessNamespaceStatefulSets(clientset kubernetes.Interface, namespace string) ([]string, error) { @@ -29,11 +28,12 @@ func ProcessNamespaceStatefulSets(clientset kubernetes.Interface, namespace stri return statefulSetsWithoutReplicas, nil } -func GetUnusedStatefulSets(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackOpts SlackOpts) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - +func GetUnusedStatefulSets(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string, slackOpts SlackOpts) (string, error) { var outputBuffer bytes.Buffer + namespaces := SetNamespaceList(includeExcludeLists, clientset) + response := make(map[string]map[string][]string) + for _, namespace := range namespaces { diff, err := ProcessNamespaceStatefulSets(clientset, namespace) if err != nil { @@ -44,28 +44,7 @@ func GetUnusedStatefulSets(includeExcludeLists IncludeExcludeLists, clientset ku outputBuffer.WriteString(output) outputBuffer.WriteString("\n") - } - if slackOpts != (SlackOpts{}) { - if err := SendToSlack(SlackMessage{}, slackOpts, outputBuffer.String()); err != nil { - fmt.Fprintf(os.Stderr, "Failed to send message to slack: %v\n", err) - os.Exit(1) - } - } else { - fmt.Println(outputBuffer.String()) - } -} - -func GetUnusedStatefulSetsStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) { - namespaces := SetNamespaceList(includeExcludeLists, clientset) - response := make(map[string]map[string][]string) - - for _, namespace := range namespaces { - diff, err := ProcessNamespaceStatefulSets(clientset, namespace) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to process namespace %s: %v\n", namespace, err) - continue - } resourceMap := make(map[string][]string) resourceMap["Statefulsets"] = diff response[namespace] = resourceMap @@ -76,13 +55,10 @@ func GetUnusedStatefulSetsStructured(includeExcludeLists IncludeExcludeLists, cl return "", err } - if outputFormat == "yaml" { - yamlResponse, err := yaml.JSONToYAML(jsonResponse) - if err != nil { - fmt.Printf("err: %v\n", err) - } - return string(yamlResponse), nil - } else { - return string(jsonResponse), nil + unusedStatefulsets, err := unusedResourceFormatter(outputFormat, outputBuffer, slackOpts, jsonResponse) + if err != nil { + fmt.Printf("err: %v\n", err) } + + return unusedStatefulsets, nil } diff --git a/pkg/kor/statefulsets_test.go b/pkg/kor/statefulsets_test.go index 5fc3c915..ebed836e 100644 --- a/pkg/kor/statefulsets_test.go +++ b/pkg/kor/statefulsets_test.go @@ -67,7 +67,13 @@ func TestGetUnusedStatefulSetsStructured(t *testing.T) { ExcludeListStr: "", } - output, err := GetUnusedStatefulSetsStructured(includeExcludeLists, clientset, "json") + slackopts := SlackOpts{ + WebhookURL: "", + Channel: "", + Token: "", + } + + output, err := GetUnusedStatefulSets(includeExcludeLists, clientset, "json", slackopts) if err != nil { t.Fatalf("Error calling GetUnusedStatefulSetsStructured: %v", err) }