From 5a8c70ccd646945058c5b89bfa75a83ca6e50277 Mon Sep 17 00:00:00 2001 From: Ahmed Samir Date: Mon, 9 Oct 2023 16:49:28 +0300 Subject: [PATCH 1/4] feat: support k8s daemonsets --- providers/k8s/core/daemonsets.go | 77 ++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 providers/k8s/core/daemonsets.go diff --git a/providers/k8s/core/daemonsets.go b/providers/k8s/core/daemonsets.go new file mode 100644 index 000000000..9c25372bd --- /dev/null +++ b/providers/k8s/core/daemonsets.go @@ -0,0 +1,77 @@ +package core + +import ( + "context" + "time" + + log "github.com/sirupsen/logrus" + + "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/providers" + oc "github.com/tailwarden/komiser/providers/k8s/opencost" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func DaemonSets(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) { + resources := make([]models.Resource, 0) + + var config metav1.ListOptions + + opencostEnabled := true + daemonsetsCost, err := oc.GetOpencostInfo(client.K8sClient.OpencostBaseUrl, "daemonset") + if err != nil { + log.Errorf("ERROR: Couldn't get daemonsets info from OpenCost: %v", err) + log.Warn("Opencost disabled") + opencostEnabled = false + } + + for { + res, err := client.K8sClient.Client.AppsV1().DaemonSets("").List(ctx, config) + if err != nil { + return nil, err + } + + for _, daemonset := range res.Items { + tags := make([]models.Tag, 0) + + for key, value := range daemonset.Labels { + tags = append(tags, models.Tag{ + Key: key, + Value: value, + }) + } + + cost := 0.0 + if opencostEnabled { + cost = daemonsetsCost[daemonset.Name].TotalCost + } + + resources = append(resources, models.Resource{ + Provider: "Kubernetes", + Account: client.Name, + Service: "Daemonset", + ResourceId: string(daemonset.UID), + Name: daemonset.Name, + Region: daemonset.Namespace, + Cost: cost, + CreatedAt: daemonset.CreationTimestamp.Time, + FetchedAt: time.Now(), + Tags: tags, + }) + } + + if res.GetContinue() == "" { + break + } + + config.Continue = res.GetContinue() + } + + log.WithFields(log.Fields{ + "provider": "Kubernetes", + "account": client.Name, + "service": "Daemonset", + "resources": len(resources), + }).Info("Fetched resources") + return resources, nil +} From ce6ea10ba9feb3f9f5fb5302476e2fe95b541425 Mon Sep 17 00:00:00 2001 From: Ahmed Samir Date: Mon, 9 Oct 2023 16:57:04 +0300 Subject: [PATCH 2/4] feat: support k8s statefulsets Signed-off-by: Ahmed Samir --- providers/k8s/core/daemonsets.go | 4 +- providers/k8s/core/statefulsets.go | 77 ++++++++++++++++++++++++++++++ providers/k8s/k8s.go | 2 + 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 providers/k8s/core/statefulsets.go diff --git a/providers/k8s/core/daemonsets.go b/providers/k8s/core/daemonsets.go index 9c25372bd..0cff39cb7 100644 --- a/providers/k8s/core/daemonsets.go +++ b/providers/k8s/core/daemonsets.go @@ -49,7 +49,7 @@ func DaemonSets(ctx context.Context, client providers.ProviderClient) ([]models. resources = append(resources, models.Resource{ Provider: "Kubernetes", Account: client.Name, - Service: "Daemonset", + Service: "DaemonSet", ResourceId: string(daemonset.UID), Name: daemonset.Name, Region: daemonset.Namespace, @@ -70,7 +70,7 @@ func DaemonSets(ctx context.Context, client providers.ProviderClient) ([]models. log.WithFields(log.Fields{ "provider": "Kubernetes", "account": client.Name, - "service": "Daemonset", + "service": "DaemonSet", "resources": len(resources), }).Info("Fetched resources") return resources, nil diff --git a/providers/k8s/core/statefulsets.go b/providers/k8s/core/statefulsets.go new file mode 100644 index 000000000..3d0bb3bef --- /dev/null +++ b/providers/k8s/core/statefulsets.go @@ -0,0 +1,77 @@ +package core + +import ( + "context" + "time" + + log "github.com/sirupsen/logrus" + + "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/providers" + oc "github.com/tailwarden/komiser/providers/k8s/opencost" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func StatefulSets(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) { + resources := make([]models.Resource, 0) + + var config metav1.ListOptions + + opencostEnabled := true + statefulsetsCost, err := oc.GetOpencostInfo(client.K8sClient.OpencostBaseUrl, "statefulset") + if err != nil { + log.Errorf("ERROR: Couldn't get statefulsets info from OpenCost: %v", err) + log.Warn("Opencost disabled") + opencostEnabled = false + } + + for { + res, err := client.K8sClient.Client.AppsV1().StatefulSets("").List(ctx, config) + if err != nil { + return nil, err + } + + for _, statefulset := range res.Items { + tags := make([]models.Tag, 0) + + for key, value := range statefulset.Labels { + tags = append(tags, models.Tag{ + Key: key, + Value: value, + }) + } + + cost := 0.0 + if opencostEnabled { + cost = statefulsetsCost[statefulset.Name].TotalCost + } + + resources = append(resources, models.Resource{ + Provider: "Kubernetes", + Account: client.Name, + Service: "StatefulSet", + ResourceId: string(statefulset.UID), + Name: statefulset.Name, + Region: statefulset.Namespace, + Cost: cost, + CreatedAt: statefulset.CreationTimestamp.Time, + FetchedAt: time.Now(), + Tags: tags, + }) + } + + if res.GetContinue() == "" { + break + } + + config.Continue = res.GetContinue() + } + + log.WithFields(log.Fields{ + "provider": "Kubernetes", + "account": client.Name, + "service": "StatefulSet", + "resources": len(resources), + }).Info("Fetched resources") + return resources, nil +} diff --git a/providers/k8s/k8s.go b/providers/k8s/k8s.go index 3b52335b7..a5a87508d 100644 --- a/providers/k8s/k8s.go +++ b/providers/k8s/k8s.go @@ -22,6 +22,8 @@ func listOfSupportedServices() []providers.FetchDataFunction { core.ServiceAccounts, core.Nodes, core.Namespaces, + core.DaemonSets, + core.StatefulSets, } } From b15fafcf0686b471d7e3efa96307f47f3972d863 Mon Sep 17 00:00:00 2001 From: Ahmed Samir Date: Mon, 9 Oct 2023 16:59:14 +0300 Subject: [PATCH 3/4] feat: support k8s jobs Signed-off-by: Ahmed Samir --- providers/k8s/core/jobs.go | 77 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 providers/k8s/core/jobs.go diff --git a/providers/k8s/core/jobs.go b/providers/k8s/core/jobs.go new file mode 100644 index 000000000..5303f4d53 --- /dev/null +++ b/providers/k8s/core/jobs.go @@ -0,0 +1,77 @@ +package core + +import ( + "context" + "time" + + log "github.com/sirupsen/logrus" + + "github.com/tailwarden/komiser/models" + "github.com/tailwarden/komiser/providers" + oc "github.com/tailwarden/komiser/providers/k8s/opencost" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func Jobs(ctx context.Context, client providers.ProviderClient) ([]models.Resource, error) { + resources := make([]models.Resource, 0) + + var config metav1.ListOptions + + opencostEnabled := true + jobsCost, err := oc.GetOpencostInfo(client.K8sClient.OpencostBaseUrl, "job") + if err != nil { + log.Errorf("ERROR: Couldn't get jobs info from OpenCost: %v", err) + log.Warn("Opencost disabled") + opencostEnabled = false + } + + for { + res, err := client.K8sClient.Client.BatchV1().Jobs("").List(ctx, config) + if err != nil { + return nil, err + } + + for _, job := range res.Items { + tags := make([]models.Tag, 0) + + for key, value := range job.Labels { + tags = append(tags, models.Tag{ + Key: key, + Value: value, + }) + } + + cost := 0.0 + if opencostEnabled { + cost = jobsCost[job.Name].TotalCost + } + + resources = append(resources, models.Resource{ + Provider: "Kubernetes", + Account: client.Name, + Service: "Job", + ResourceId: string(job.UID), + Name: job.Name, + Region: job.Namespace, + Cost: cost, + CreatedAt: job.CreationTimestamp.Time, + FetchedAt: time.Now(), + Tags: tags, + }) + } + + if res.GetContinue() == "" { + break + } + + config.Continue = res.GetContinue() + } + + log.WithFields(log.Fields{ + "provider": "Kubernetes", + "account": client.Name, + "service": "DaemonSet", + "resources": len(resources), + }).Info("Fetched resources") + return resources, nil +} From 879122ee235b398e3d50de9d866a98822653d37d Mon Sep 17 00:00:00 2001 From: Ahmed Samir Date: Mon, 9 Oct 2023 17:00:17 +0300 Subject: [PATCH 4/4] feat: add jobs to supported list Signed-off-by: Ahmed Samir --- providers/k8s/k8s.go | 1 + 1 file changed, 1 insertion(+) diff --git a/providers/k8s/k8s.go b/providers/k8s/k8s.go index a5a87508d..60226960b 100644 --- a/providers/k8s/k8s.go +++ b/providers/k8s/k8s.go @@ -24,6 +24,7 @@ func listOfSupportedServices() []providers.FetchDataFunction { core.Namespaces, core.DaemonSets, core.StatefulSets, + core.Jobs, } }