diff --git a/agent/kubviz/k8smetrics_agent.go b/agent/kubviz/k8smetrics_agent.go index 49230271..c3e96693 100644 --- a/agent/kubviz/k8smetrics_agent.go +++ b/agent/kubviz/k8smetrics_agent.go @@ -127,7 +127,7 @@ func main() { LogErr(err) err = RakeesOutput(config, js) LogErr(err) - //getK8sEvents(clientset) + // //getK8sEvents(clientset) err = runTrivyScans(config, js) LogErr(err) err = RunKubeScore(clientset, js) diff --git a/agent/kubviz/kube_score.go b/agent/kubviz/kube_score.go index 437a0850..57ea8cb8 100644 --- a/agent/kubviz/kube_score.go +++ b/agent/kubviz/kube_score.go @@ -10,6 +10,7 @@ import ( "github.com/intelops/kubviz/constants" "github.com/intelops/kubviz/model" "github.com/nats-io/nats.go" + "github.com/zegl/kube-score/renderer/json_v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) @@ -32,34 +33,42 @@ func RunKubeScore(clientset *kubernetes.Clientset, js nats.JetStreamContext) err } func publish(ns string, js nats.JetStreamContext) error { - cmd := "kubectl api-resources --verbs=list --namespaced -o name | xargs -n1 -I{} sh -c \"kubectl get {} -n " + ns + " -oyaml && echo ---\" | kube-score score - " + var report []json_v2.ScoredObject + cmd := "kubectl api-resources --verbs=list --namespaced -o name | xargs -n1 -I{} sh -c \"kubectl get {} -n " + ns + " -oyaml && echo ---\" | kube-score score - -o json" log.Printf("Command: %#v,", cmd) out, err := executeCommand(cmd) if err != nil { log.Println("Error occurred while running kube-score: ", err) return err } - err = publishKubescoreMetrics(uuid.New().String(), ns, out, js) + // // Continue with the rest of the code... + err = json.Unmarshal([]byte(out), &report) + if err != nil { + log.Printf("Error occurred while Unmarshalling json: %v", err) + return err + } + + publishKubescoreMetrics(report, js) + //err = publishKubescoreMetrics(uuid.New().String(), ns, out, js) if err != nil { return err } return nil } -func publishKubescoreMetrics(id string, ns string, recommendations string, js nats.JetStreamContext) error { +func publishKubescoreMetrics(report []json_v2.ScoredObject, js nats.JetStreamContext) error { metrics := model.KubeScoreRecommendations{ - ID: id, - Namespace: ns, - Recommendations: recommendations, - ClusterName: ClusterName, + ID: uuid.New().String(), + ClusterName: ClusterName, + Report: report, } metricsJson, _ := json.Marshal(metrics) _, err := js.Publish(constants.KUBESCORE_SUBJECT, metricsJson) if err != nil { return err } - log.Printf("Recommendations with ID:%s has been published\n", id) - log.Printf("Recommendations :%#v", recommendations) + //log.Printf("Recommendations with ID:%s has been published\n", id) + log.Printf("Recommendations :%#v", report) return nil } diff --git a/client/pkg/clickhouse/db_client.go b/client/pkg/clickhouse/db_client.go index 82fd4359..ab8f3bc9 100644 --- a/client/pkg/clickhouse/db_client.go +++ b/client/pkg/clickhouse/db_client.go @@ -523,6 +523,7 @@ func (c *DBClient) InsertKubeScoreMetrics(metrics model.KubeScoreRecommendations if err != nil { log.Fatalf("error beginning transaction, clickhouse connection not available: %v", err) } + defer tx.Rollback() stmt, err := tx.Prepare(InsertKubeScore) if err != nil { log.Fatalf("error preparing statement: %v", err) @@ -531,14 +532,31 @@ func (c *DBClient) InsertKubeScoreMetrics(metrics model.KubeScoreRecommendations currentTime := time.Now().UTC() - if _, err := stmt.Exec( - metrics.ID, - metrics.Namespace, - metrics.ClusterName, - metrics.Recommendations, - currentTime, - ); err != nil { - log.Fatal(err) + for _, result := range metrics.Report { + for _, check := range result.Checks { + for _, comments := range check.Comments { + + if _, err := stmt.Exec( + metrics.ID, + metrics.ClusterName, + result.ObjectName, + result.TypeMeta.Kind, + result.TypeMeta.APIVersion, + result.ObjectMeta.Name, + result.ObjectMeta.Namespace, + check.Check.TargetType, + comments.Description, + comments.Path, + comments.Summary, + result.FileName, + int64(result.FileRow), + currentTime, + ); err != nil { + log.Println("Error while inserting KubeScore metrics:", err) + } + } + + } } if err := tx.Commit(); err != nil { log.Fatal(err) diff --git a/client/pkg/clickhouse/statements.go b/client/pkg/clickhouse/statements.go index e1abea47..3185fb53 100644 --- a/client/pkg/clickhouse/statements.go +++ b/client/pkg/clickhouse/statements.go @@ -237,7 +237,7 @@ const InsertDeletedApi DBStatement = "INSERT INTO DeletedAPIs (ClusterName, Obje const InsertKubvizEvent DBStatement = "INSERT INTO events (ClusterName, Id, EventTime, OpType, Name, Namespace, Kind, Message, Reason, Host, Event, FirstTime, LastTime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" const clickhouseExperimental DBStatement = `SET allow_experimental_object_type=1;` const containerGithubTable DBStatement = `CREATE table IF NOT EXISTS container_github(event JSON) ENGINE = MergeTree ORDER BY tuple();` -const InsertKubeScore string = "INSERT INTO kubescore (id, namespace, cluster_name, recommendations, EventTime) VALUES (?, ?, ?, ?, ?)" +const InsertKubeScore string = "INSERT INTO kubescore(id,clustername,object_name,kind,apiVersion,name,namespace,target_type,description,path,summary,file_name,file_row,EventTime) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)" const InsertTrivyVul string = "INSERT INTO trivy_vul (id, cluster_name, namespace, kind, name, vul_id, vul_vendor_ids, vul_pkg_id, vul_pkg_name, vul_pkg_path, vul_installed_version, vul_fixed_version, vul_title, vul_severity, vul_published_date, vul_last_modified_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?. ?)" const InsertTrivyImage string = "INSERT INTO trivyimage (id, cluster_name, artifact_name, vul_id, vul_pkg_id, vul_pkg_name, vul_installed_version, vul_fixed_version, vul_title, vul_severity, vul_published_date, vul_last_modified_date) VALUES ( ?, ?,?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" const InsertTrivyMisconfig string = "INSERT INTO trivy_misconfig (id, cluster_name, namespace, kind, name, misconfig_id, misconfig_avdid, misconfig_type, misconfig_title, misconfig_desc, misconfig_msg, misconfig_query, misconfig_resolution, misconfig_severity, misconfig_status, EventTime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" diff --git a/go.mod b/go.mod index df47ddff..48f274bd 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.7.0 + github.com/zegl/kube-score v1.17.0 golang.org/x/term v0.11.0 k8s.io/api v0.27.3 k8s.io/apimachinery v0.27.3 @@ -53,7 +54,7 @@ require ( github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect - github.com/fatih/color v1.14.1 // indirect + github.com/fatih/color v1.15.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-errors/errors v1.4.2 // indirect diff --git a/go.sum b/go.sum index b8b6d6ff..ce5d958d 100644 --- a/go.sum +++ b/go.sum @@ -124,8 +124,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= -github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= -github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= +github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e/go.mod h1:2H9hjfbpSMHwY503FclkV/lZTBh2YlOmLLSda12uL8c= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= @@ -472,6 +472,8 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0= github.com/zclconf/go-cty-yaml v1.0.2 h1:dNyg4QLTrv2IfJpm7Wtxi55ed5gLGOlPrZ6kMd51hY0= +github.com/zegl/kube-score v1.17.0 h1:vedzK0pm5yOb1ocm5gybMNYsJRG8iTAatbo3LFIWbUc= +github.com/zegl/kube-score v1.17.0/go.mod h1:0pt4Lt36uTKPiCQbXQFow29eaAbgMLI9RoESjBoGSq0= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.mongodb.org/mongo-driver v1.11.1/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= diff --git a/model/kubescore.go b/model/kubescore.go index 918ada85..fb63f747 100644 --- a/model/kubescore.go +++ b/model/kubescore.go @@ -1,8 +1,9 @@ package model +import "github.com/zegl/kube-score/renderer/json_v2" + type KubeScoreRecommendations struct { - ID string - Namespace string - Recommendations string - ClusterName string + ID string + ClusterName string + Report []json_v2.ScoredObject } diff --git a/sql/000008_kubescore.up.sql b/sql/000008_kubescore.up.sql index 662fab9b..b6ee3e3f 100644 --- a/sql/000008_kubescore.up.sql +++ b/sql/000008_kubescore.up.sql @@ -1,8 +1,17 @@ CREATE TABLE IF NOT EXISTS kubescore ( - id UUID, - namespace String, - cluster_name String, - recommendations String, + id UUID, + clustername String, + object_name String, + kind String, + apiVersion String, + name String, + namespace String, + target_type String, + description String, + path String, + summary String, + file_name String, + file_row BIGINT, EventTime DateTime('UTC'), ExpiryDate DateTime DEFAULT now() + INTERVAL {{.TTLValue}} {{.TTLUnit}} ) ENGINE = MergeTree()