Skip to content

Commit

Permalink
Merge pull request #330 from intelops/newtrivy
Browse files Browse the repository at this point in the history
trivy changes
  • Loading branch information
vijeyashintelops authored Mar 1, 2024
2 parents f2555bf + 2e5eb83 commit ca4f01f
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 6 deletions.
5 changes: 4 additions & 1 deletion agent/kubviz/k8smetrics_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package main
import (
"log"
"os"

"os/signal"
"syscall"
"time"

//"github.com/go-co-op/gocron"
"github.com/go-co-op/gocron"
"github.com/nats-io/nats.go"

Expand All @@ -20,6 +22,7 @@ import (

"github.com/intelops/kubviz/agent/config"
"github.com/intelops/kubviz/agent/kubviz/plugins/events"

"github.com/intelops/kubviz/agent/kubviz/plugins/ketall"
"github.com/intelops/kubviz/agent/kubviz/plugins/kubepreupgrade"

Expand All @@ -35,8 +38,8 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"

// _ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
"github.com/intelops/kubviz/agent/server"
//_ "k8s.io/client-go/plugin/pkg/client/auth/openstack"
"k8s.io/client-go/tools/clientcmd"
)

Expand Down
99 changes: 94 additions & 5 deletions agent/kubviz/plugins/trivy/trivy_image.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
package trivy

import (
"bytes"
"context"
"encoding/json"
"fmt"
"log"
"os"
exec "os/exec"
"strings"

"github.com/aquasecurity/trivy/pkg/types"
"github.com/google/uuid"
"github.com/intelops/kubviz/agent/kubviz/plugins/kubescore"
"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/nats-io/nats.go"
"github.com/pkg/errors"
"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"
)

Expand All @@ -37,7 +40,7 @@ func RunTrivyImageScans(config *rest.Config, js nats.JetStreamContext) error {
span.SetAttributes(attribute.String("trivy-image-scan-agent", "image-scan"))
defer span.End()

images, err := outdated.ListImages(config)
images, err := ListImages(config)
if err != nil {
log.Println("error occured while trying to list images, error :", err.Error())
return err
Expand All @@ -46,13 +49,13 @@ func RunTrivyImageScans(config *rest.Config, js nats.JetStreamContext) error {
for _, image := range images {
var report types.Report
scanCmd := fmt.Sprintf("trivy image %s --timeout 60m -f json -q --cache-dir %s", image.PullableImage, trivyImageCacheDir)
out, err := kubescore.ExecuteCommand(scanCmd)
out, err := executeTrivyImage(scanCmd)
if err != nil {
log.Printf("Error scanning image %s: %v", image.PullableImage, err)
continue // Move on to the next image in case of an error
}

parts := strings.SplitN(out, "{", 2)
parts := strings.SplitN(string(out), "{", 2)
if len(parts) <= 1 {
log.Println("No output from image scan command", err)
continue // Move on to the next image if there's no output
Expand Down Expand Up @@ -95,3 +98,89 @@ func PublishImageScanReports(report types.Report, js nats.JetStreamContext) erro
log.Printf("Trivy image report with ID:%s has been published\n", metrics.ID)
return nil
}
func executeTrivyImage(command string) ([]byte, error) {

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

cmd := exec.Command("/bin/sh", "-c", command)
var outc, errc bytes.Buffer
cmd.Stdout = &outc
cmd.Stderr = &errc
err := cmd.Run()
// if outc.Len() > 0 {
// log.Printf("Command Output: %s\n", outc.String())
// }
if errc.Len() > 0 {
log.Printf("Command Error: %s\n", errc.String())
}
if err != nil {
return nil, fmt.Errorf("error while executing trivy image command: %v", err)
}
return outc.Bytes(), err
}

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
}

0 comments on commit ca4f01f

Please sign in to comment.