Skip to content

Commit

Permalink
sbom-struct
Browse files Browse the repository at this point in the history
  • Loading branch information
an1l4 committed Feb 28, 2024
1 parent f2555bf commit b58860c
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 85 deletions.
151 changes: 107 additions & 44 deletions agent/kubviz/plugins/trivy/trivy_sbom.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,57 +8,58 @@ import (
"log"
"os"
"os/exec"
"strings"

"github.com/aquasecurity/trivy/pkg/sbom/cyclonedx"
"github.com/google/uuid"
"github.com/intelops/kubviz/agent/kubviz/plugins/outdated"
//"github.com/intelops/kubviz/agent/kubviz/plugins/outdated"
"github.com/intelops/kubviz/constants"
"github.com/intelops/kubviz/model"
"github.com/intelops/kubviz/pkg/opentelemetry"
"github.com/pkg/errors"

// "github.com/intelops/kubviz/pkg/opentelemetry"
"github.com/nats-io/nats.go"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
//"go.opentelemetry.io/otel"
// "go.opentelemetry.io/otel/attribute"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)

func PublishTrivySbomReport(report cyclonedx.BOM, js nats.JetStreamContext) error {

for _, packageinfo := range report.Packages {
for _, pkg := range packageinfo.Packages {

metrics := model.SbomData{
ID: uuid.New().String(),
ClusterName: ClusterName,
ComponentName: report.CycloneDX.Metadata.Component.Name,
PackageName: pkg.Name,
PackageUrl: report.CycloneDX.Metadata.Component.PackageURL,
BomRef: report.CycloneDX.Metadata.Component.BOMRef,
SerialNumber: report.CycloneDX.SerialNumber,
CycloneDxVersion: report.CycloneDX.Version,
BomFormat: report.CycloneDX.BOMFormat,
}
metricsJson, err := json.Marshal(metrics)
if err != nil {
log.Println("error occurred while marshalling sbom metrics in agent", err.Error())
return err
}
_, err = js.Publish(constants.TRIVY_SBOM_SUBJECT, metricsJson)
if err != nil {
return err
}
log.Printf("Trivy sbom report with Id %v has been published\n", metrics.ID)
}
func PublishTrivySbomReport(report model.AutoGenerated, js nats.JetStreamContext) error {
log.Println("trivy PublishTrivySbomReport started...")

metrics := model.Sbom{
ID: uuid.New().String(),
ClusterName: ClusterName,
Report: report,
}
metricsJson, err := json.Marshal(metrics)
if err != nil {
log.Println("error occurred while marshalling sbom metrics in agent", err.Error())
return err
}
_, err = js.Publish(constants.TRIVY_SBOM_SUBJECT, metricsJson)
if err != nil {
return err
}
log.Printf("Trivy sbom report with Id %v has been published\n", metrics.ID)
log.Printf("Trivy sbom report with cluster name %v has been published\n", metrics.ClusterName)
log.Printf("Trivy sbom report with BomFormat %v has been published\n", metrics.Report.BomFormat)
log.Printf("Trivy sbom report with SerialNumber %v has been published\n", metrics.Report.SerialNumber)
log.Printf("Trivy sbom report with imageName %v has been published\n", metrics.Report.Metadata.Component.Name)
log.Printf("Trivy sbom report with image Type %v has been published\n", metrics.Report.Metadata.Component.Type)

return nil
}

func executeCommandSbom(command string) ([]byte, error) {
log.Println("trivy execute command started...")

ctx := context.Background()
tracer := otel.Tracer("trivy-sbom")
_, span := tracer.Start(opentelemetry.BuildContext(ctx), "executeCommandSbom")
span.SetAttributes(attribute.String("trivy-sbom-agent", "sbom-command-running"))
defer span.End()
// ctx := context.Background()
// tracer := otel.Tracer("trivy-sbom")
// _, span := tracer.Start(opentelemetry.BuildContext(ctx), "executeCommandSbom")
// span.SetAttributes(attribute.String("trivy-sbom-agent", "sbom-command-running"))
// defer span.End()

cmd := exec.Command("/bin/sh", "-c", command)
var outc, errc bytes.Buffer
Expand All @@ -81,13 +82,13 @@ func RunTrivySbomScan(config *rest.Config, js nats.JetStreamContext) error {
return err
}

ctx := context.Background()
tracer := otel.Tracer("trivy-sbom")
_, span := tracer.Start(opentelemetry.BuildContext(ctx), "RunTrivySbomScan")
span.SetAttributes(attribute.String("sbom", "sbom-creation"))
defer span.End()
// ctx := context.Background()
// tracer := otel.Tracer("trivy-sbom")
// _, span := tracer.Start(opentelemetry.BuildContext(ctx), "RunTrivySbomScan")
// span.SetAttributes(attribute.String("sbom", "sbom-creation"))
// defer span.End()

images, err := outdated.ListImages(config)
images, err := ListImages(config)

if err != nil {
log.Printf("failed to list images: %v", err)
Expand All @@ -111,7 +112,7 @@ func RunTrivySbomScan(config *rest.Config, js nats.JetStreamContext) error {
continue // Move on to the next image
}

var report cyclonedx.BOM
var report model.AutoGenerated
err = json.Unmarshal(out, &report)
if err != nil {
log.Printf("Error unmarshaling JSON data for image sbom %s: %v", image.PullableImage, err)
Expand All @@ -121,3 +122,65 @@ func RunTrivySbomScan(config *rest.Config, js nats.JetStreamContext) error {
}
return nil
}

func ListImages(config *rest.Config) ([]model.RunningImage, error) {
var err error
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
return nil, errors.Wrap(err, "failed to create clientset")
}
ctx := context.Background()
namespaces, err := clientset.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
if err != nil {
return nil, errors.Wrap(err, "failed to list namespaces")
}

runningImages := []model.RunningImage{}
for _, namespace := range namespaces.Items {
pods, err := clientset.CoreV1().Pods(namespace.Name).List(ctx, metav1.ListOptions{})
if err != nil {
return nil, errors.Wrap(err, "failed to list pods")
}

for _, pod := range pods.Items {
for _, initContainerStatus := range pod.Status.InitContainerStatuses {
pullable := initContainerStatus.ImageID
pullable = strings.TrimPrefix(pullable, "docker-pullable://")
runningImage := model.RunningImage{
Pod: pod.Name,
Namespace: pod.Namespace,
InitContainer: &initContainerStatus.Name,
Image: initContainerStatus.Image,
PullableImage: pullable,
}
runningImages = append(runningImages, runningImage)
}

for _, containerStatus := range pod.Status.ContainerStatuses {
pullable := containerStatus.ImageID
pullable = strings.TrimPrefix(pullable, "docker-pullable://")

runningImage := model.RunningImage{
Pod: pod.Name,
Namespace: pod.Namespace,
Container: &containerStatus.Name,
Image: containerStatus.Image,
PullableImage: pullable,
}
runningImages = append(runningImages, runningImage)
}
}
}

// Remove exact duplicates
cleanedImages := []model.RunningImage{}
seenImages := make(map[string]bool)
for _, runningImage := range runningImages {
if !seenImages[runningImage.PullableImage] {
cleanedImages = append(cleanedImages, runningImage)
seenImages[runningImage.PullableImage] = true
}
}

return cleanedImages, nil
}
18 changes: 9 additions & 9 deletions client/pkg/clickhouse/db_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type DBInterface interface {
InsertGitEvent(string)
InsertKubeScoreMetrics(model.KubeScoreRecommendations)
InsertTrivyImageMetrics(metrics model.TrivyImage)
InsertTrivySbomMetrics(metrics model.SbomData)
InsertTrivySbomMetrics(metrics model.Sbom)
InsertTrivyMetrics(metrics model.Trivy)
RetriveKetallEvent() ([]model.Resource, error)
RetriveOutdatedEvent() ([]model.CheckResultfinal, error)
Expand Down Expand Up @@ -841,7 +841,7 @@ func (c *DBClient) InsertTrivyImageMetrics(metrics model.TrivyImage) {

}
}
func (c *DBClient) InsertTrivySbomMetrics(metrics model.SbomData) {
func (c *DBClient) InsertTrivySbomMetrics(metrics model.Sbom) {
ctx := context.Background()
tracer := otel.Tracer("insert-trivy-sbom")
_, span := tracer.Start(opentelemetry.BuildContext(ctx), "InsertTrivySbomMetrics")
Expand All @@ -860,13 +860,13 @@ func (c *DBClient) InsertTrivySbomMetrics(metrics model.SbomData) {
if _, err := stmt.Exec(
metrics.ID,
metrics.ClusterName,
metrics.ComponentName,
metrics.PackageName,
metrics.PackageUrl,
metrics.BomRef,
metrics.SerialNumber,
int32(metrics.CycloneDxVersion),
metrics.BomFormat,
// metrics.ComponentName,
// metrics.PackageName,
// metrics.PackageUrl,
// metrics.BomRef,
// metrics.SerialNumber,
// int32(metrics.CycloneDxVersion),
// metrics.BomFormat,
); err != nil {
log.Fatal(err)
}
Expand Down
32 changes: 16 additions & 16 deletions client/pkg/clients/kubviz_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,22 +146,22 @@ func (n *NATSContext) SubscribeAllKubvizNats(conn clickhouse.DBInterface) {
log.Println()
},
},
{
Subject: constants.TRIVY_SBOM_SUBJECT,
Consumer: cfg.TrivySbomConsumer,
Handler: func(msg *nats.Msg) {
msg.Ack()
var metrics model.SbomData
err := json.Unmarshal(msg.Data, &metrics)
if err != nil {
log.Println("failed to unmarshal from nats", err)
return
}
log.Printf("Trivy sbom Metrics Received: %#v,", metrics)
conn.InsertTrivySbomMetrics(metrics)
log.Println()
},
},
// {
// Subject: constants.TRIVY_SBOM_SUBJECT,
// Consumer: cfg.TrivySbomConsumer,
// Handler: func(msg *nats.Msg) {
// msg.Ack()
// var metrics model.SbomData
// err := json.Unmarshal(msg.Data, &metrics)
// if err != nil {
// log.Println("failed to unmarshal from nats", err)
// return
// }
// log.Printf("Trivy sbom Metrics Received: %#v,", metrics)
// conn.InsertTrivySbomMetrics(metrics)
// log.Println()
// },
// },
{
Subject: constants.KubvizSubject,
Consumer: cfg.KubvizConsumer,
Expand Down
90 changes: 74 additions & 16 deletions model/trivy_sbom.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,82 @@
package model

import (
"github.com/aquasecurity/trivy/pkg/sbom/cyclonedx"
)
import "time"

type Sbom struct {
ID string
Report cyclonedx.BOM
}
//"github.com/aquasecurity/trivy/pkg/sbom/cyclonedx"

// type Sbom struct {
// ID string
// Report cyclonedx.BOM
// }

type SbomData struct {
ID string
// type SbomData struct {
// ID string
// ClusterName string
// ComponentName string
// PackageName string
// PackageUrl string
// BomRef string
// SerialNumber string
// CycloneDxVersion int
// BomFormat string
// }

type Sbom struct {
ID string
ClusterName string
ComponentName string
PackageName string
PackageUrl string
BomRef string
SerialNumber string
CycloneDxVersion int
BomFormat string
Report AutoGenerated
}

// type SbomData struct {
// ID string
// ClusterName string
// ComponentName string
// PackageName string
// PackageUrl string
// BomRef string
// SerialNumber string
// CycloneDxVersion int
// BomFormat string
// }

type AutoGenerated struct {
Schema string `json:"$schema"`
BomFormat string `json:"bomFormat"`
SpecVersion string `json:"specVersion"`
SerialNumber string `json:"serialNumber"`
Version int `json:"version"`
Metadata struct {
Timestamp time.Time `json:"timestamp"`
Tools []struct {
Vendor string `json:"vendor"`
Name string `json:"name"`
Version string `json:"version"`
} `json:"tools"`
Component struct {
BomRef string `json:"bom-ref"`
Type string `json:"type"`
Name string `json:"name"`
Purl string `json:"purl"`
Properties []struct {
Name string `json:"name"`
Value string `json:"value"`
} `json:"properties"`
} `json:"component"`
} `json:"metadata"`
Components []struct {
BomRef string `json:"bom-ref"`
Type string `json:"type"`
Name string `json:"name"`
Properties []struct {
Name string `json:"name"`
Value string `json:"value"`
} `json:"properties"`
Version string `json:"version,omitempty"`
Purl string `json:"purl,omitempty"`
} `json:"components"`
Dependencies []struct {
Ref string `json:"ref"`
DependsOn []string `json:"dependsOn"`
} `json:"dependencies"`
Vulnerabilities []interface{} `json:"vulnerabilities"`
}

0 comments on commit b58860c

Please sign in to comment.