diff --git a/internal/handler/testassets/bin/grype b/internal/handler/testassets/bin/grype deleted file mode 100755 index 44b55b1..0000000 Binary files a/internal/handler/testassets/bin/grype and /dev/null differ diff --git a/internal/handler/trivyProcessing.go b/internal/handler/trivyProcessing.go index 9ab579f..eec5d65 100644 --- a/internal/handler/trivyProcessing.go +++ b/internal/handler/trivyProcessing.go @@ -151,15 +151,44 @@ func writeProblemsArrayToApi(environment int, source string, service string, pro return nil } -func executeProcessingTrivy(bom cyclonedx.BOM) (cyclonedx.BOM, error) { +func executeProcessingTrivy(trivyRemoteAddress string, bomWriteDir string, bom cyclonedx.BOM) (types.Report, error) { //first, we write this thing to disk + file, err := os.CreateTemp(bomWriteDir, "cycloneDX-*.json") + if err != nil { + return types.Report{}, err + } + + marshalledBom, err := json.Marshal(bom) + + if err != nil { + return types.Report{}, err + } + + _, err = file.Write(marshalledBom) + if err != nil { + return types.Report{}, err + } + + fileInfo, err := file.Stat() + if err != nil { + return types.Report{}, err + } + + fullFilename := fmt.Sprintf("%v/%v", bomWriteDir, fileInfo.Name()) + + // Let's defer removing our file till the function returns + defer func() { + os.Remove(fullFilename) + file.Close() + }() + ctx, cancel := context.WithTimeout(context.Background(), time.Second*1000) defer cancel() opts := flag.Options{ GlobalOptions: flag.GlobalOptions{ ConfigFile: "trivy.yaml", - CacheDir: "/home/bomoko/.cache/trivy", + CacheDir: "/tmp/.cache/trivy", }, AWSOptions: flag.AWSOptions{}, CacheOptions: flag.CacheOptions{ @@ -178,7 +207,7 @@ func executeProcessingTrivy(bom cyclonedx.BOM) (cyclonedx.BOM, error) { RegistryOptions: flag.RegistryOptions{}, RegoOptions: flag.RegoOptions{}, RemoteOptions: flag.RemoteOptions{ - ServerAddr: "http://localhost:4954", + ServerAddr: trivyRemoteAddress, Token: "", TokenHeader: "Trivy-Token", CustomHeaders: http.Header{}, @@ -187,7 +216,7 @@ func executeProcessingTrivy(bom cyclonedx.BOM) (cyclonedx.BOM, error) { ReportOptions: flag.ReportOptions{}, SBOMOptions: flag.SBOMOptions{}, ScanOptions: flag.ScanOptions{ - Target: "/home/bomoko/Downloads/sbomtest.json", + Target: fullFilename, Scanners: types.Scanners{ types.VulnerabilityScanner, }, @@ -205,19 +234,16 @@ func executeProcessingTrivy(bom cyclonedx.BOM) (cyclonedx.BOM, error) { runner, err := artifact.NewRunner(ctx, opts) if err != nil { - fmt.Println(err.Error()) - os.Exit(1) + return types.Report{}, err } rep, err := runner.ScanSBOM(context.TODO(), opts) if err != nil { - fmt.Println(err.Error()) - os.Exit(1) + return types.Report{}, err } - fmt.Println(rep) - return cyclonedx.BOM{}, nil + return rep, nil } func trivyReportToProblems(environment int, source string, service string, report types.Report) ([]lagoonclient.LagoonProblem, error) { @@ -247,6 +273,7 @@ func trivyReportToProblems(environment int, source string, service string, repor p.Severity = lagoonclient.ProblemSeverityRating(v.Vulnerability.Severity) + ret = append(ret, p) } } return ret, nil diff --git a/internal/handler/trivyProcessing_test.go b/internal/handler/trivyProcessing_test.go index a5b6723..3668cc4 100644 --- a/internal/handler/trivyProcessing_test.go +++ b/internal/handler/trivyProcessing_test.go @@ -28,7 +28,7 @@ func Test_executeProcessing(t *testing.T) { } //Let's ensure that grype is available locally - grypePath := "./testassets/bin/grype" + grypePath := "./testassets/bin/trivy" if _, err := os.Stat(grypePath); os.IsNotExist(err) { t.Errorf("Grype not found at %v - please run `make gettestgrype`", grypePath) return @@ -148,3 +148,61 @@ func Test_trivyReportToProblems(t *testing.T) { }) } } + +func Test_executeProcessingTrivy(t *testing.T) { + type args struct { + trivyRemoteAddress string + bomWriteDir string + bomFile string + } + tests := []struct { + name string + args args + numberProblemsMin int + wantErr bool + }{ + { + name: "Basic test", + numberProblemsMin: 20, + args: args{ + trivyRemoteAddress: "http://localhost:4954", + bomWriteDir: "/tmp/", + bomFile: "testassets/bomToProblems_test1.json", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + // load up the bom + fileData, err := os.ReadFile(tt.args.bomFile) + if err != nil { + t.Errorf("Unable to open sbom file '%v' error '%v'", tt.args.bomFile, err.Error()) + return + } + + var testBom cyclonedx.BOM + + err = json.Unmarshal(fileData, &testBom) + if err != nil { + t.Errorf("Unable to parse sbom file '%v' error %v ", tt.args.bomFile, err.Error()) + return + } + + got, err := executeProcessingTrivy(tt.args.trivyRemoteAddress, tt.args.bomWriteDir, testBom) + if (err != nil) != tt.wantErr { + t.Errorf("executeProcessingTrivy() error = %v, wantErr %v", err, tt.wantErr) + return + } + problems, err := trivyReportToProblems(0, "", "", got) + if err != nil { + t.Errorf("%v", err.Error()) + return + } + + if len(problems) < tt.numberProblemsMin { + t.Errorf("Number of problems inaccurate got %v, wanted more than %v", len(problems), tt.numberProblemsMin) + } + }) + } +}