diff --git a/client/pkg/clickhouse/db_client.go b/client/pkg/clickhouse/db_client.go index 84e3cceb..7f075177 100644 --- a/client/pkg/clickhouse/db_client.go +++ b/client/pkg/clickhouse/db_client.go @@ -945,54 +945,76 @@ func (c *DBClient) InsertTrivySbomMetrics(metrics model.Sbom) { } data := metrics.Report - bomComponents, ok := data["components"].([]interface{}) + bomFormat, _ := data["bomFormat"].(string) //CycloneDX + serialNumber, _ := data["serialNumber"].(string) // exmplvalue:urn:uuid:146625a5-531a-40fa-a205-174448c6c569 + + // fetching metadata + metadata, ok := data["metadata"].(map[string]interface{}) + if !ok { + log.Println("error: metadata not found or not in expected format") + return + } + // inside metadata + // taking component + component, ok := metadata["component"].(map[string]interface{}) + if !ok { + log.Println("error: component not found or not in expected format") + return + } + timestamp, _ := metadata["timestamp"].(time.Time) + + // inside metadata + // taking component + // inside component taking bomRef, componentType, componentName, packageURL + bomRef, _ := component["bom-ref"].(string) //pkg:oci/redis@sha256:873c49204b64258778a1f34d23a962de526021e9a63b09236d6d7c86e2dd13e9?repository_url=public.ecr.aws%2Fdocker%2Flibrary%2Fredis\u0026arch=amd64 + componentType, _ := component["type"].(string) //container + componentName, _ := component["name"].(string) //public.ecr.aws/docker/library/redis@sha256:873c49204b64258778a1f34d23a962de526021e9a63b09236d6d7c86e2dd13e9 + packageURL, _ := component["purl"].(string) //pkg:oci/redis@sha256:873c49204b64258778a1f34d23a962de526021e9a63b09236d6d7c86e2dd13e9?repository_url=public.ecr.aws%2Fdocker%2Flibrary%2Fredis\u0026arch=amd64 + // fetching other componets + Components, ok := data["components"].([]interface{}) if !ok { log.Println("error: components not found or not in expected format") } - var componentName, bomRef, serialNumber, bomFormat, purl, componentType string - var version int32 + var otherComponentName, otherComponentbomref, otherComponenttype, otherComponentVersion string // Iterate over the components to find the desired name - for _, component := range bomComponents { - componentMap, ok := component.(map[string]interface{}) + for _, otherComponent := range Components { + componentsMap, ok := otherComponent.(map[string]interface{}) if !ok { log.Println("error: component not in expected format") continue } - if name, ok := componentMap["name"].(string); ok { - componentName = name + if name, ok := componentsMap["name"].(string); ok { + otherComponentName = name // alpine + break + } + if bomref, ok := componentsMap["bom-ref"].(string); ok { + otherComponentbomref = bomref // 92fc3e51-41d6-48da-831e-a1f5f9b6444d + break + } + if types, ok := componentsMap["type"].(string); ok { + otherComponenttype = types // operating-system + break + } + if version, ok := componentsMap["version"].(string); ok { + otherComponentVersion = version // 3.18.4 break } - } - metadata, ok := data["metadata"].(map[string]interface{}) - if !ok { - log.Println("error: metadata not found or not in expected format") - return - } - - component, ok := metadata["component"].(map[string]interface{}) - if !ok { - log.Println("error: component not found or not in expected format") - return } - bomRef, _ = component["bom-ref"].(string) - purl, _ = component["purl"].(string) - componentType, _ = component["type"].(string) - - serialNumber, _ = data["serialNumber"].(string) - version, _ = data["version"].(int32) - bomFormat, _ = data["bomFormat"].(string) - if _, err := stmt.Exec( metrics.ID, metrics.ClusterName, + bomFormat, + serialNumber, + bomRef, componentName, componentType, - purl, - bomRef, - serialNumber, - int32(version), - bomFormat, + packageURL, + timestamp, + otherComponentName, + otherComponentbomref, + otherComponenttype, + otherComponentVersion, ); err != nil { log.Fatal(err) } @@ -1001,6 +1023,86 @@ func (c *DBClient) InsertTrivySbomMetrics(metrics model.Sbom) { } stmt.Close() } + +// func (c *DBClient) InsertTrivySbomMetrics(metrics model.Sbom) { +// //opentelemetry +// opentelconfig, err := opentelemetry.GetConfigurations() +// if err != nil { +// log.Println("Unable to read open telemetry configurations") +// } +// if opentelconfig.IsEnabled { +// ctx := context.Background() +// tracer := otel.Tracer("insert-trivy-sbom") +// _, span := tracer.Start(opentelemetry.BuildContext(ctx), "InsertTrivySbomMetrics") +// defer span.End() +// } + +// tx, err := c.conn.Begin() +// if err != nil { +// log.Fatalf("error beginning transaction, clickhouse connection not available: %v", err) +// } +// stmt, err := tx.Prepare(InsertTrivySbom) +// if err != nil { +// log.Fatalf("error preparing statement: %v", err) +// } + +// data := metrics.Report +// bomComponents, ok := data["components"].([]interface{}) +// if !ok { +// log.Println("error: components not found or not in expected format") +// } +// var componentName, bomRef, serialNumber, bomFormat, purl, componentType string +// var version int32 +// // Iterate over the components to find the desired name +// for _, component := range bomComponents { +// componentMap, ok := component.(map[string]interface{}) +// if !ok { +// log.Println("error: component not in expected format") +// continue +// } +// if name, ok := componentMap["name"].(string); ok { +// componentName = name +// break +// } +// } +// metadata, ok := data["metadata"].(map[string]interface{}) +// if !ok { +// log.Println("error: metadata not found or not in expected format") +// return +// } + +// component, ok := metadata["component"].(map[string]interface{}) +// if !ok { +// log.Println("error: component not found or not in expected format") +// return +// } + +// bomRef, _ = component["bom-ref"].(string) +// purl, _ = component["purl"].(string) +// componentType, _ = component["type"].(string) + +// serialNumber, _ = data["serialNumber"].(string) +// version, _ = data["version"].(int32) +// bomFormat, _ = data["bomFormat"].(string) + +// if _, err := stmt.Exec( +// metrics.ID, +// metrics.ClusterName, +// componentName, +// componentType, +// purl, +// bomRef, +// serialNumber, +// int32(version), +// bomFormat, +// ); err != nil { +// log.Fatal(err) +// } +// if err := tx.Commit(); err != nil { +// log.Fatal(err) +// } +// stmt.Close() +// } func (c *DBClient) Close() { _ = c.conn.Close() } diff --git a/client/pkg/clickhouse/statements.go b/client/pkg/clickhouse/statements.go index a728ceec..7f02e5ac 100644 --- a/client/pkg/clickhouse/statements.go +++ b/client/pkg/clickhouse/statements.go @@ -230,7 +230,7 @@ const InsertTrivyVul string = "INSERT INTO trivy_vul (id, cluster_name, namespac 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" const InsertAzureContainerPushEvent DBStatement = "INSERT INTO azurecontainerpush (RegistryURL, RepositoryName, Tag, ImageName, Event, Size, SHAID, EventTime) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?)" -const InsertTrivySbom string = "INSERT INTO trivysbom (id, cluster_name, image_name, package_name, package_url, bom_ref, serial_number, version, bom_format) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" +const InsertTrivySbom string = "INSERT INTO trivysbom (id, cluster_name, bom_format, serial_number, bom_ref, image_name, componet_type, package_url, time_stamp, other_component_name, other_component_bomref, other_component_type, other_component_version) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" const InsertQuayContainerPushEvent DBStatement = "INSERT INTO quaycontainerpush (name, repository, nameSpace, dockerURL, homePage, tag, Event, EventTime) VALUES (?, ?, ?, ?, ?, ?, ?, ?)" const InsertJfrogContainerPushEvent DBStatement = "INSERT INTO jfrogcontainerpush (Domain, EventType, RegistryURL, RepositoryName, SHAID, Size, ImageName, Tag, Event, EventTime) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" const InsertKuberhealthy string = "INSERT INTO kuberhealthy (CurrentUUID, CheckName, OK, Errors, RunDuration, Namespace, Node, LastRun, AuthoritativePod) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)" \ No newline at end of file diff --git a/sql/0000015_trivysbom.up.sql b/sql/0000015_trivysbom.up.sql index 7bc749ac..0d84589d 100644 --- a/sql/0000015_trivysbom.up.sql +++ b/sql/0000015_trivysbom.up.sql @@ -1,13 +1,17 @@ CREATE TABLE IF NOT EXISTS trivysbom ( id UUID, - cluster_name String, + cluster_name String, + bom_format String, + serial_number String, + bom_ref String, image_name String, - package_name String, + componet_type String, package_url String, - bom_ref String, - serial_number String, - version INTEGER, - bom_format String, + time_stamp DateTime('UTC'), + other_component_name String, + other_component_bomref String, + other_component_type String, + other_component_version String, ExpiryDate DateTime DEFAULT now() + INTERVAL {{.TTLValue}} {{.TTLUnit}}, ExportedAt DateTime DEFAULT NULL ) ENGINE = MergeTree()