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

feat: add send to slack support #77

Merged
merged 18 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from 15 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
4 changes: 4 additions & 0 deletions cmd/kor/all.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ var allCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedAll(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedAll(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedAll(includeExcludeLists, clientset)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/configmaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var configmapCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedConfigmaps(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedConfigmaps(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedConfigmaps(includeExcludeLists, clientset)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/deployments.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var deployCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedDeployments(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedDeployments(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedDeployments(includeExcludeLists, clientset)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/hpas.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var hpaCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedHpas(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedHpas(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedHpas(includeExcludeLists, clientset)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/ingresses.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var ingressCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedIngresses(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedIngresses(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedIngresses(includeExcludeLists, clientset)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/pdbs.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var pdbCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedPdbs(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedPdbs(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedPdbs(includeExcludeLists, clientset)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/pvc.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var pvcCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedPvcs(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedPvcs(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedPvcs(includeExcludeLists, clientset)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var roleCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedRoles(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedRoles(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedRoles(includeExcludeLists, clientset)
}
Expand Down
6 changes: 6 additions & 0 deletions cmd/kor/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ var rootCmd = &cobra.Command{
var (
outputFormat string
kubeconfig string
slackWebhookURL string
slackChannel string
slackAuthToken string
includeExcludeLists kor.IncludeExcludeLists
)

Expand All @@ -46,6 +49,9 @@ func Execute() {
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(&slackWebhookURL, "slack-webhook-url", "", "Slack webhook URL to send notifications to")
rootCmd.PersistentFlags().StringVar(&slackChannel, "slack-channel", "", "Slack channel to send notifications to")
rootCmd.PersistentFlags().StringVar(&slackAuthToken, "slack-auth-token", "", "Slack auth token to send notifications to")
if err := rootCmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "Error while executing your CLI '%s'", err)
os.Exit(1)
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var secretCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedSecrets(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedSecrets(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedSecrets(includeExcludeLists, clientset)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/serviceaccounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var serviceAccountCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedServiceAccounts(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedServiceAccounts(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedServiceAccounts(includeExcludeLists, clientset)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var serviceCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedServices(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedServices(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedServices(includeExcludeLists, clientset)
}
Expand Down
4 changes: 4 additions & 0 deletions cmd/kor/statefulsets.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ var stsCmd = &cobra.Command{
} else {
fmt.Println(response)
}
} else if slackWebhookURL != "" {
kor.GetUnusedStatefulSets(includeExcludeLists, clientset, slackWebhookURL)
} else if slackChannel != "" && slackAuthToken != "" {
kor.GetUnusedStatefulSets(includeExcludeLists, clientset, slackChannel, slackAuthToken)
} else {
kor.GetUnusedStatefulSets(includeExcludeLists, clientset)
}
Expand Down
26 changes: 23 additions & 3 deletions pkg/kor/all.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kor

import (
"bytes"
"encoding/json"
"fmt"
"os"
Expand Down Expand Up @@ -118,8 +119,11 @@ func getUnusedPdbs(clientset kubernetes.Interface, namespace string) ResourceDif
return namespacePdbDiff
}

func GetUnusedAll(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface) {
func GetUnusedAll(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackParams ...string) {
namespaces := SetNamespaceList(includeExcludeLists, clientset)

var outputBuffer bytes.Buffer

for _, namespace := range namespaces {
var allDiffs []ResourceDiff
namespaceCMDiff := getUnusedCMs(clientset, namespace)
Expand All @@ -144,9 +148,25 @@ func GetUnusedAll(includeExcludeLists IncludeExcludeLists, clientset kubernetes.
allDiffs = append(allDiffs, namespaceIngressDiff)
namespacePdbDiff := getUnusedPdbs(clientset, namespace)
allDiffs = append(allDiffs, namespacePdbDiff)

output := FormatOutputAll(namespace, allDiffs)
fmt.Println(output)
fmt.Println()

outputBuffer.WriteString(output)
outputBuffer.WriteString("\n")
}

if len(slackParams) == 1 {
patricktalmeida marked this conversation as resolved.
Show resolved Hide resolved
if err := SendToSlackWebhook(slackParams[0], outputBuffer.String()); err != nil {
fmt.Fprintf(os.Stderr, "Failed to send output to Slack: %v\n", err)
}
} else if len(slackParams) == 2 {
outputFilePath, _ := writeOutputToFile(outputBuffer)

if err := SendFileToSlack(outputFilePath, "Unused All", slackParams[0], slackParams[1]); err != nil {
fmt.Fprintf(os.Stderr, "Failed to send output to Slack: %v\n", err)
}
} else {
fmt.Println(outputBuffer.String())
}
}

Expand Down
24 changes: 21 additions & 3 deletions pkg/kor/confimgmaps.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kor

import (
"bytes"
"context"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -128,18 +129,35 @@ func processNamespaceCM(clientset kubernetes.Interface, namespace string) ([]str

}

func GetUnusedConfigmaps(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface) {
func GetUnusedConfigmaps(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackParams ...string) {
namespaces := SetNamespaceList(includeExcludeLists, clientset)

var outputBuffer bytes.Buffer

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
}
output := FormatOutput(namespace, diff, "Config Maps")
fmt.Println(output)
fmt.Println()

outputBuffer.WriteString(output)
outputBuffer.WriteString("\n")
}

if len(slackParams) == 1 {
if err := SendToSlackWebhook(slackParams[0], outputBuffer.String()); err != nil {
fmt.Fprintf(os.Stderr, "Failed to send output to Slack: %v\n", err)
}
} else if len(slackParams) == 2 {
outputFilePath, _ := writeOutputToFile(outputBuffer)

if err := SendFileToSlack(outputFilePath, "Unused Configmaps", slackParams[0], slackParams[1]); err != nil {
fmt.Fprintf(os.Stderr, "Failed to send output to Slack: %v\n", err)
}
} else {
fmt.Println(outputBuffer.String())
}
}

Expand Down
24 changes: 21 additions & 3 deletions pkg/kor/deployments.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kor

import (
"bytes"
"context"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -32,18 +33,35 @@ func ProcessNamespaceDeployments(clientset kubernetes.Interface, namespace strin
return deploymentsWithoutReplicas, nil
}

func GetUnusedDeployments(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface) {
func GetUnusedDeployments(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackParams ...string) {
namespaces := SetNamespaceList(includeExcludeLists, clientset)

var outputBuffer bytes.Buffer

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
}
output := FormatOutput(namespace, diff, "Deployments")
fmt.Println(output)
fmt.Println()

outputBuffer.WriteString(output)
outputBuffer.WriteString("\n")
}

if len(slackParams) == 1 {
if err := SendToSlackWebhook(slackParams[0], outputBuffer.String()); err != nil {
fmt.Fprintf(os.Stderr, "Failed to send output to Slack: %v\n", err)
}
} else if len(slackParams) == 2 {
outputFilePath, _ := writeOutputToFile(outputBuffer)

if err := SendFileToSlack(outputFilePath, "Unused Deployments", slackParams[0], slackParams[1]); err != nil {
fmt.Fprintf(os.Stderr, "Failed to send output to Slack: %v\n", err)
}
} else {
fmt.Println(outputBuffer.String())
}
}

Expand Down
23 changes: 20 additions & 3 deletions pkg/kor/hpas.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kor

import (
"bytes"
"context"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -79,20 +80,36 @@ func processNamespaceHpas(clientset kubernetes.Interface, namespace string) ([]s
return unusedHpas, nil
}

func GetUnusedHpas(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface) {
func GetUnusedHpas(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackParams ...string) {
namespaces := SetNamespaceList(includeExcludeLists, clientset)

var outputBuffer bytes.Buffer

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
}
output := FormatOutput(namespace, diff, "Hpas")
fmt.Println(output)
fmt.Println()

outputBuffer.WriteString(output)
outputBuffer.WriteString("\n")
}

if len(slackParams) == 1 {
if err := SendToSlackWebhook(slackParams[0], outputBuffer.String()); err != nil {
fmt.Fprintf(os.Stderr, "Failed to send output to Slack: %v\n", err)
}
} else if len(slackParams) == 2 {
outputFilePath, _ := writeOutputToFile(outputBuffer)

if err := SendFileToSlack(outputFilePath, "Unused HPAs", slackParams[0], slackParams[1]); err != nil {
fmt.Fprintf(os.Stderr, "Failed to send output to Slack: %v\n", err)
}
} else {
fmt.Println(outputBuffer.String())
}
}

func GetUnusedHpasStructured(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, outputFormat string) (string, error) {
Expand Down
24 changes: 21 additions & 3 deletions pkg/kor/ingresses.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package kor

import (
"bytes"
"context"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -88,18 +89,35 @@ func processNamespaceIngresses(clientset kubernetes.Interface, namespace string)

}

func GetUnusedIngresses(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface) {
func GetUnusedIngresses(includeExcludeLists IncludeExcludeLists, clientset kubernetes.Interface, slackParams ...string) {
namespaces := SetNamespaceList(includeExcludeLists, clientset)

var outputBuffer bytes.Buffer

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
}
output := FormatOutput(namespace, diff, "Ingresses")
fmt.Println(output)
fmt.Println()

outputBuffer.WriteString(output)
outputBuffer.WriteString("\n")
}

if len(slackParams) == 1 {
if err := SendToSlackWebhook(slackParams[0], outputBuffer.String()); err != nil {
fmt.Fprintf(os.Stderr, "Failed to send output to Slack: %v\n", err)
}
} else if len(slackParams) == 2 {
outputFilePath, _ := writeOutputToFile(outputBuffer)

if err := SendFileToSlack(outputFilePath, "Unused Ingresses", slackParams[0], slackParams[1]); err != nil {
fmt.Fprintf(os.Stderr, "Failed to send output to Slack: %v\n", err)
}
} else {
fmt.Println(outputBuffer.String())
}
}

Expand Down
Loading