diff --git a/cmd/kosli/attest.go b/cmd/kosli/attest.go index 367832544..8bb59f8c1 100644 --- a/cmd/kosli/attest.go +++ b/cmd/kosli/attest.go @@ -20,6 +20,7 @@ func newAttestCmd(out io.Writer) *cobra.Command { newAttestArtifactCmd(out), newAttestGenericCmd(out), newAttestSnykCmd(out), + newAttestSarifCmd(out), newAttestJunitCmd(out), newAttestJiraCmd(out), newAttestPRCmd(out), diff --git a/cmd/kosli/attestSarif.go b/cmd/kosli/attestSarif.go new file mode 100644 index 000000000..29b10d771 --- /dev/null +++ b/cmd/kosli/attestSarif.go @@ -0,0 +1,223 @@ +package main + +import ( + "fmt" + "io" + "net/http" + "net/url" + "os" + + "github.com/kosli-dev/cli/internal/requests" + "github.com/kosli-dev/cli/internal/sarif" + "github.com/spf13/cobra" +) + +type SarifAttestationPayload struct { + *CommonAttestationPayload + SarifResults *sarif.SarifData `json:"sarif_results"` + Compliant bool `json:"is_compliant"` +} + +type attestSarifOptions struct { + *CommonAttestationOptions + sarifFilePath string + uploadResultsFile bool + payload SarifAttestationPayload +} + +const attestSarifShortDesc = `Report a SARIF attestation to an artifact or a trail in a Kosli flow. ` + +const attestSarifLongDesc = attestSarifShortDesc + ` +Accepts SARIF v2.1.0 scan results from any compatible tool (e.g. Checkov, Trivy, Semgrep, Snyk, CodeQL). +The tool name and version are taken from the SARIF report's runs[0].tool.driver fields and shown in +the Kosli UI alongside the parsed findings. + +The ^--scan-results^ .json file is analyzed and a summary of the scan results is reported to Kosli. + +By default, the ^--scan-results^ .json file is also uploaded to Kosli's evidence vault. +You can disable that by setting ^--upload-results=false^. + +Compliance is determined by the ^--compliant^ flag (default true). The CLI does not derive +compliance from the SARIF findings — the caller decides whether the scan should be treated +as compliant or not (e.g. based on its own policy or rego rules). +` + attestationBindingDesc + ` + +` + commitDescription + +const attestSarifExample = ` +# report a SARIF attestation about a trail (compliant by default): +kosli attest sarif \ + --name yourAttestationName \ + --flow yourFlowName \ + --trail yourTrailName \ + --scan-results yourScanSARIFResults \ + --api-token yourAPIToken \ + --org yourOrgName + +# report a non-compliant SARIF attestation about a trail: +kosli attest sarif \ + --name yourAttestationName \ + --flow yourFlowName \ + --trail yourTrailName \ + --scan-results yourScanSARIFResults \ + --compliant=false \ + --api-token yourAPIToken \ + --org yourOrgName + +# report a SARIF attestation about a pre-built docker artifact (kosli calculates the fingerprint): +kosli attest sarif yourDockerImageName \ + --artifact-type docker \ + --name yourAttestationName \ + --flow yourFlowName \ + --trail yourTrailName \ + --scan-results yourScanSARIFResults \ + --api-token yourAPIToken \ + --org yourOrgName + +# report a SARIF attestation about a pre-built docker artifact (you provide the fingerprint): +kosli attest sarif \ + --fingerprint yourDockerImageFingerprint \ + --name yourAttestationName \ + --flow yourFlowName \ + --trail yourTrailName \ + --scan-results yourScanSARIFResults \ + --api-token yourAPIToken \ + --org yourOrgName + +# report a SARIF attestation about an artifact which has not been reported yet in a trail: +kosli attest sarif \ + --name yourTemplateArtifactName.yourAttestationName \ + --flow yourFlowName \ + --trail yourTrailName \ + --commit yourArtifactGitCommit \ + --scan-results yourScanSARIFResults \ + --api-token yourAPIToken \ + --org yourOrgName + +# report a SARIF attestation about a trail without uploading the results file: +kosli attest sarif \ + --name yourAttestationName \ + --flow yourFlowName \ + --trail yourTrailName \ + --scan-results yourScanSARIFResults \ + --upload-results=false \ + --api-token yourAPIToken \ + --org yourOrgName +` + +func newAttestSarifCmd(out io.Writer) *cobra.Command { + o := &attestSarifOptions{ + CommonAttestationOptions: &CommonAttestationOptions{ + fingerprintOptions: &fingerprintOptions{}, + }, + payload: SarifAttestationPayload{ + CommonAttestationPayload: &CommonAttestationPayload{}, + }, + } + cmd := &cobra.Command{ + Use: "sarif [IMAGE-NAME | FILE-PATH | DIR-PATH]", + Short: attestSarifShortDesc, + Long: attestSarifLongDesc, + Example: attestSarifExample, + PreRunE: func(cmd *cobra.Command, args []string) error { + + err := CustomMaximumNArgs(1, args) + if err != nil { + return err + } + + err = RequireGlobalFlags(global, []string{"Org", "ApiToken"}) + if err != nil { + return ErrorBeforePrintingUsage(cmd, err.Error()) + } + + err = MuXRequiredFlags(cmd, []string{"fingerprint", "artifact-type"}, false) + if err != nil { + return err + } + + err = ValidateSliceValues(o.redactedCommitInfo, allowedCommitRedactionValues) + if err != nil { + return fmt.Errorf("%s for --redact-commit-info", err.Error()) + } + + err = ValidateAttestationArtifactArg(args, o.fingerprintOptions.artifactType, o.payload.ArtifactFingerprint) + if err != nil { + return ErrorBeforePrintingUsage(cmd, err.Error()) + } + + return ValidateRegistryFlags(cmd, o.fingerprintOptions) + + }, + RunE: func(cmd *cobra.Command, args []string) error { + o.repoURLExplicit = cmd.Flags().Changed("repo-url") + return o.run(args) + }, + } + + ci := WhichCI() + addAttestationFlags(cmd, o.CommonAttestationOptions, o.payload.CommonAttestationPayload, ci) + cmd.Flags().StringVarP(&o.sarifFilePath, "scan-results", "R", "", sarifResultsFileFlag) + cmd.Flags().BoolVar(&o.uploadResultsFile, "upload-results", true, uploadSarifResultsFlag) + cmd.Flags().BoolVarP(&o.payload.Compliant, "compliant", "C", true, attestationCompliantFlag) + + err := RequireFlags(cmd, []string{"flow", "trail", "name", "scan-results"}) + if err != nil { + logger.Error("failed to configure required flags: %v", err) + } + + return cmd +} + +func (o *attestSarifOptions) run(args []string) error { + url, err := url.JoinPath(global.Host, "api/v2/attestations", global.Org, o.flowName, "trail", o.trailName, "sarif") + if err != nil { + return err + } + + err = o.CommonAttestationOptions.run(args, o.payload.CommonAttestationPayload) + if err != nil { + return err + } + + logger.Debug("parsing SARIF results file: %s", o.sarifFilePath) + o.payload.SarifResults, err = sarif.ProcessSarifResultFile(o.sarifFilePath) + if err != nil { + return fmt.Errorf("failed to parse SARIF results file [%s]: %s", o.sarifFilePath, err) + } + if len(o.payload.SarifResults.Results) > 0 { + r := o.payload.SarifResults.Results[0] + logger.Debug("SARIF parsed: tool=%s findings=%d high, %d medium, %d low (compliant=%t)", + o.payload.SarifResults.Tool.Name, r.HighCount, r.MediumCount, r.LowCount, o.payload.Compliant) + } + + if o.uploadResultsFile { + o.attachments = append(o.attachments, o.sarifFilePath) + } + + form, cleanupNeeded, evidencePath, err := prepareAttestationForm(o.payload, o.attachments) + if err != nil { + return err + } + // if we created a tar package, remove it after uploading it + if cleanupNeeded { + defer func() { + if err := os.Remove(evidencePath); err != nil { + logger.Warn("failed to remove evidence file %s: %v", evidencePath, err) + } + }() + } + + reqParams := &requests.RequestParams{ + Method: http.MethodPost, + URL: url, + Form: form, + DryRun: global.DryRun, + Token: global.ApiToken, + } + _, err = kosliClient.Do(reqParams) + if err == nil && !global.DryRun { + logger.Info("sarif attestation '%s' is reported to trail: %s", o.payload.AttestationName, o.trailName) + } + return wrapAttestationError(err) +} diff --git a/cmd/kosli/attestSarif_test.go b/cmd/kosli/attestSarif_test.go new file mode 100644 index 000000000..9e440f02a --- /dev/null +++ b/cmd/kosli/attestSarif_test.go @@ -0,0 +1,152 @@ +package main + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/suite" +) + +// Define the suite, and absorb the built-in basic suite +// functionality from testify - including a T() method which +// returns the current testing context +type AttestSarifCommandTestSuite struct { + flowName string + trailName string + artifactFingerprint string + suite.Suite + defaultKosliArguments string +} + +func (suite *AttestSarifCommandTestSuite) SetupTest() { + suite.flowName = "attest-sarif" + suite.trailName = "test-123" + suite.artifactFingerprint = "7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9" + global = &GlobalOpts{ + ApiToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6ImNkNzg4OTg5In0.e8i_lA_QrEhFncb05Xw6E_tkCHU9QfcY4OLTVUCHffY", + Org: "docs-cmd-test-user", + Host: "http://localhost:8001", + } + suite.defaultKosliArguments = fmt.Sprintf(" --flow %s --trail %s --repo-root ../.. --host %s --org %s --api-token %s", suite.flowName, suite.trailName, global.Host, global.Org, global.ApiToken) + CreateFlowWithTemplate(suite.flowName, "testdata/valid_template.yml", suite.T()) + BeginTrail(suite.trailName, suite.flowName, "", suite.T()) + CreateArtifactOnTrail(suite.flowName, suite.trailName, "cli", suite.artifactFingerprint, "file1", suite.T()) +} + +func (suite *AttestSarifCommandTestSuite) TestAttestSarifCmd() { + tests := []cmdTestCase{ + { + wantError: true, + name: "fails when more arguments are provided", + cmd: fmt.Sprintf("attest sarif foo bar %s", suite.defaultKosliArguments), + golden: "Error: accepts at most 1 arg(s), received 2 [foo bar]\n", + }, + { + wantError: true, + name: "fails when missing required flags", + cmd: fmt.Sprintf("attest sarif foo -t file %s", suite.defaultKosliArguments), + golden: "Error: required flag(s) \"name\", \"scan-results\" not set\n", + }, + { + wantError: true, + name: "fails when both --fingerprint and --artifact-type", + cmd: fmt.Sprintf("attest sarif testdata/file1 --fingerprint xxxx --artifact-type file --name bar --commit HEAD --origin-url https://example.com %s", suite.defaultKosliArguments), + golden: "Error: only one of --fingerprint, --artifact-type is allowed\n", + }, + { + wantError: true, + name: "fails when --fingerprint is not valid", + cmd: fmt.Sprintf("attest sarif --name foo --fingerprint xxxx --commit HEAD --origin-url https://example.com %s", suite.defaultKosliArguments), + golden: "Error: xxxx is not a valid SHA256 fingerprint. It should match the pattern ^([a-f0-9]{64})$\nUsage: kosli attest sarif [IMAGE-NAME | FILE-PATH | DIR-PATH] [flags]\n", + }, + { + wantError: true, + name: "attesting against an artifact that does not exist fails", + cmd: fmt.Sprintf("attest sarif --fingerprint 1234e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --name foo --commit HEAD --origin-url https://example.com --scan-results testdata/snyk_sarif.json %s", suite.defaultKosliArguments), + golden: "Error: Artifact with fingerprint 1234e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 does not exist in trail \"test-123\" of flow \"attest-sarif\" belonging to organization \"docs-cmd-test-user\"\n", + }, + { + wantError: true, + name: "fails when --scan-results is missing", + cmd: fmt.Sprintf("attest sarif testdata/file1 --artifact-type file --name foo --commit HEAD --origin-url https://example.com %s", suite.defaultKosliArguments), + golden: "Error: required flag(s) \"scan-results\" not set\n", + }, + { + name: "can attest sarif against an artifact using artifact name and --artifact-type", + cmd: fmt.Sprintf("attest sarif testdata/file1 --artifact-type file --name foo --commit HEAD --origin-url https://example.com --scan-results testdata/snyk_sarif.json %s", suite.defaultKosliArguments), + golden: "sarif attestation 'foo' is reported to trail: test-123\n", + }, + { + name: "can attest sarif against an artifact using artifact name and --artifact-type when --name does not exist in the trail template", + cmd: fmt.Sprintf("attest sarif testdata/file1 --artifact-type file --name bar --commit HEAD --origin-url https://example.com --scan-results testdata/snyk_sarif.json %s", suite.defaultKosliArguments), + golden: "sarif attestation 'bar' is reported to trail: test-123\n", + }, + { + name: "can attest sarif against an artifact using --fingerprint", + cmd: fmt.Sprintf("attest sarif --fingerprint 7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 --name foo --commit HEAD --origin-url https://example.com --scan-results testdata/snyk_sarif.json %s", suite.defaultKosliArguments), + golden: "sarif attestation 'foo' is reported to trail: test-123\n", + }, + { + name: "can attest sarif against a trail", + cmd: fmt.Sprintf("attest sarif --name bar --commit HEAD --origin-url https://example.com --scan-results testdata/snyk_sarif.json %s", suite.defaultKosliArguments), + golden: "sarif attestation 'bar' is reported to trail: test-123\n", + }, + { + name: "can attest sarif against a trail with --compliant=false", + cmd: fmt.Sprintf("attest sarif --name bar --commit HEAD --origin-url https://example.com --scan-results testdata/snyk_sarif.json --compliant=false %s", suite.defaultKosliArguments), + golden: "sarif attestation 'bar' is reported to trail: test-123\n", + }, + { + name: "can attest sarif against a trail with explicit --compliant=true", + cmd: fmt.Sprintf("attest sarif --name bar --commit HEAD --origin-url https://example.com --scan-results testdata/snyk_sarif.json --compliant=true %s", suite.defaultKosliArguments), + golden: "sarif attestation 'bar' is reported to trail: test-123\n", + }, + { + name: "can attest sarif against a trail when name is not found in the trail template", + cmd: fmt.Sprintf("attest sarif --name additional --commit HEAD --origin-url https://example.com --scan-results testdata/snyk_sarif.json %s", suite.defaultKosliArguments), + golden: "sarif attestation 'additional' is reported to trail: test-123\n", + }, + { + name: "can attest sarif against an artifact created using dot syntax in --name", + cmd: fmt.Sprintf("attest sarif --name cli.foo --commit HEAD --origin-url https://example.com --scan-results testdata/snyk_sarif.json %s", suite.defaultKosliArguments), + golden: "sarif attestation 'foo' is reported to trail: test-123\n", + }, + { + name: "can attest sarif with external-url and external-fingerprint against a trail", + cmd: fmt.Sprintf(`attest sarif --name bar --commit HEAD --origin-url https://example.com + --external-url file=https://example.com/file --external-url other=https://other.com + --external-fingerprint file=7509e5bda0c762d2bac7f90d758b5b2263fa01ccbc542ab5e3df163be08e6ca9 + --scan-results testdata/snyk_sarif.json %s`, suite.defaultKosliArguments), + golden: "sarif attestation 'bar' is reported to trail: test-123\n", + }, + { + name: "can attest sarif with annotations against a trail", + cmd: fmt.Sprintf(`attest sarif --name bar --commit HEAD --origin-url https://example.com + --annotate foo=bar --annotate baz=qux + --scan-results testdata/snyk_sarif.json %s`, suite.defaultKosliArguments), + golden: "sarif attestation 'bar' is reported to trail: test-123\n", + }, + { + wantError: true, + name: "fails when annotation is not valid", + cmd: fmt.Sprintf(`attest sarif --name bar --commit HEAD --origin-url https://example.com + --annotate foo.baz=bar + --scan-results testdata/snyk_sarif.json %s`, suite.defaultKosliArguments), + golden: "Error: --annotate flag should be in the format key=value. Invalid key: 'foo.baz'. Key can only contain [A-Za-z0-9_]\n", + }, + { + wantError: true, + name: "fails when --name has invalid dot format", + cmd: fmt.Sprintf("attest sarif --name .foo --scan-results testdata/snyk_sarif.json %s", suite.defaultKosliArguments), + golden: "Error: failed to parse attestation name: invalid attestation name format: .foo\n", + }, + } + + runTestCmd(suite.T(), tests) +} + +// In order for 'go test' to run this suite, we need to create +// a normal test function and pass our suite to suite.Run +func TestAttestSarifCommandTestSuite(t *testing.T) { + suite.Run(t, new(AttestSarifCommandTestSuite)) +} diff --git a/cmd/kosli/attestSnyk.go b/cmd/kosli/attestSnyk.go index 3a83eaaff..6a3933c33 100644 --- a/cmd/kosli/attestSnyk.go +++ b/cmd/kosli/attestSnyk.go @@ -8,13 +8,13 @@ import ( "os" "github.com/kosli-dev/cli/internal/requests" - "github.com/kosli-dev/cli/internal/snyk" + "github.com/kosli-dev/cli/internal/sarif" "github.com/spf13/cobra" ) type SnykAttestationPayload struct { *CommonAttestationPayload - SnykResults *snyk.SnykData `json:"snyk_results"` + SnykResults *sarif.SarifData `json:"snyk_results"` } type attestSnykOptions struct { @@ -174,7 +174,7 @@ func (o *attestSnykOptions) run(args []string) error { return err } - o.payload.SnykResults, err = snyk.ProcessSnykResultFile(o.snykSarifFilePath) + o.payload.SnykResults, err = sarif.ProcessSarifResultFile(o.snykSarifFilePath) if err != nil { return fmt.Errorf("failed to parse Snyk sarif results file [%s]: %s", o.snykSarifFilePath, err) } diff --git a/cmd/kosli/root.go b/cmd/kosli/root.go index 01c376817..89b15cbe7 100644 --- a/cmd/kosli/root.go +++ b/cmd/kosli/root.go @@ -219,6 +219,8 @@ The ^.kosli_ignore^ will be treated as part of the artifact like any other file, attestationCustomDataFileFlag = "The filepath of a json file containing the custom attestation data." uploadJunitResultsFlag = "[defaulted] Whether to upload the provided Junit results directory as an attachment to Kosli or not." uploadSnykResultsFlag = "[defaulted] Whether to upload the provided Snyk results file as an attachment to Kosli or not." + sarifResultsFileFlag = "The path to a SARIF v2.1.0 scan results file (e.g. from Checkov, Trivy, Semgrep, Snyk, CodeQL). By default, the results file will be uploaded to Kosli's evidence vault." + uploadSarifResultsFlag = "[defaulted] Whether to upload the provided SARIF results file as an attachment to Kosli or not." attestationAssertFlag = "[optional] Exit with non-zero code if the attestation is non-compliant" beginTrailCommitFlag = "[defaulted] The git commit from which the trail is begun. (defaulted in some CIs: https://docs.kosli.com/ci-defaults, otherwise defaults to HEAD )." attachmentsFlag = "[optional] The comma-separated list of paths of attachments for the reported attestation. Attachments can be files or directories. All attachments are compressed and uploaded to Kosli's evidence vault." diff --git a/internal/snyk/sarif-code.json b/internal/sarif/sarif-code.json similarity index 100% rename from internal/snyk/sarif-code.json rename to internal/sarif/sarif-code.json diff --git a/internal/snyk/sarif-container.json b/internal/sarif/sarif-container.json similarity index 100% rename from internal/snyk/sarif-container.json rename to internal/sarif/sarif-container.json diff --git a/internal/snyk/sarif-empty-container.json b/internal/sarif/sarif-empty-container.json similarity index 100% rename from internal/snyk/sarif-empty-container.json rename to internal/sarif/sarif-empty-container.json diff --git a/internal/snyk/sarif-helm.json b/internal/sarif/sarif-helm.json similarity index 100% rename from internal/snyk/sarif-helm.json rename to internal/sarif/sarif-helm.json diff --git a/internal/snyk/sarif-iac.json b/internal/sarif/sarif-iac.json similarity index 100% rename from internal/snyk/sarif-iac.json rename to internal/sarif/sarif-iac.json diff --git a/internal/snyk/sarif-os.json b/internal/sarif/sarif-os.json similarity index 100% rename from internal/snyk/sarif-os.json rename to internal/sarif/sarif-os.json diff --git a/internal/snyk/sarif-serverless.json b/internal/sarif/sarif-serverless.json similarity index 100% rename from internal/snyk/sarif-serverless.json rename to internal/sarif/sarif-serverless.json diff --git a/internal/snyk/snyk.go b/internal/sarif/sarif.go similarity index 85% rename from internal/snyk/snyk.go rename to internal/sarif/sarif.go index d8be5937c..ef86e53e3 100644 --- a/internal/snyk/snyk.go +++ b/internal/sarif/sarif.go @@ -1,4 +1,4 @@ -package snyk +package sarif import ( "fmt" @@ -8,7 +8,7 @@ import ( "github.com/owenrumney/go-sarif/v2/sarif" ) -type SnykTool struct { +type SarifTool struct { Name string `json:"name"` Version string `json:"version"` } @@ -25,7 +25,7 @@ type Vulnerability struct { PriorityScore float64 `json:"priority_score,omitempty"` } -type SnykResult struct { +type SarifResult struct { HighCount int `json:"high_count"` MediumCount int `json:"medium_count"` LowCount int `json:"low_count"` @@ -34,15 +34,18 @@ type SnykResult struct { Low []Vulnerability `json:"low,omitempty"` } -type SnykData struct { - SchemaVersion int `json:"schema_version"` - Tool SnykTool `json:"tool"` - Results []SnykResult `json:"results"` +type SarifData struct { + SchemaVersion int `json:"schema_version"` + Tool SarifTool `json:"tool"` + Results []SarifResult `json:"results"` } -// ProcessSnykResultFile takes a path to a Snyk scan results file -// and returns a processed SnykData object from it -func ProcessSnykResultFile(file string) (*SnykData, error) { +// ProcessSarifResultFile takes a path to a SARIF scan results file +// and returns a processed SarifData object from it. The parser is +// generic over SARIF v2.1.0 producers (Snyk, Checkov, Trivy, Semgrep, etc.) +// and uses Snyk-specific property fallbacks only when the standard SARIF +// `level` field is absent. +func ProcessSarifResultFile(file string) (*SarifData, error) { report, err := sarif.Open(file) if err != nil { return nil, err @@ -50,10 +53,10 @@ func ProcessSnykResultFile(file string) (*SnykData, error) { if !strings.HasPrefix(report.Schema, "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/main/") && !strings.HasPrefix(report.Schema, "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-") && !strings.HasPrefix(report.Schema, "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json") { return nil, fmt.Errorf("invalid sarif file") } - data := &SnykData{ + data := &SarifData{ SchemaVersion: 1, - Tool: SnykTool{}, - Results: []SnykResult{}, + Tool: SarifTool{}, + Results: []SarifResult{}, } if len(report.Runs) > 0 { @@ -64,7 +67,7 @@ func ProcessSnykResultFile(file string) (*SnykData, error) { } for _, run := range report.Runs { - result := SnykResult{} + result := SarifResult{} for _, r := range run.Results { level := r.Level vulnerability := createVulnerability(r) diff --git a/internal/snyk/snyk_test.go b/internal/sarif/sarif_test.go similarity index 87% rename from internal/snyk/snyk_test.go rename to internal/sarif/sarif_test.go index 83ca28b0e..8c815998a 100644 --- a/internal/snyk/snyk_test.go +++ b/internal/sarif/sarif_test.go @@ -1,10 +1,10 @@ -package snyk +package sarif import ( "testing" ) -func TestProcessSnykResultFile(t *testing.T) { +func TestProcessSarifResultFile(t *testing.T) { type result struct { high_count int medium_count int @@ -149,14 +149,14 @@ func TestProcessSnykResultFile(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := ProcessSnykResultFile(tt.file) + got, err := ProcessSarifResultFile(tt.file) if (err != nil) != tt.wantErr { - t.Errorf("ProcessSnykResultFile() error = %v, wantErr %v", err, tt.wantErr) + t.Errorf("ProcessSarifResultFile() error = %v, wantErr %v", err, tt.wantErr) return } if tt.want != nil && (tt.want.tool != got.Tool.Name || tt.want.version != got.Tool.Version) { - t.Errorf("ProcessSnykResultFile() failed, want: Tool: %s (got %s) -- Version: %s (got %s)", tt.want.tool, got.Tool.Name, tt.want.version, got.Tool.Version) + t.Errorf("ProcessSarifResultFile() failed, want: Tool: %s (got %s) -- Version: %s (got %s)", tt.want.tool, got.Tool.Name, tt.want.version, got.Tool.Version) } if tt.want != nil && len(tt.want.results) > 0 { @@ -164,7 +164,7 @@ func TestProcessSnykResultFile(t *testing.T) { if wantResult.high_count != got.Results[i].HighCount || wantResult.medium_count != got.Results[i].MediumCount || wantResult.low_count != got.Results[i].LowCount { - t.Errorf("ProcessSnykResultFile() failed for Result [%d], want %v -- got %v", i, wantResult, got.Results[i]) + t.Errorf("ProcessSarifResultFile() failed for Result [%d], want %v -- got %v", i, wantResult, got.Results[i]) } } } diff --git a/internal/snyk/snyk.json b/internal/sarif/snyk.json similarity index 100% rename from internal/snyk/snyk.json rename to internal/sarif/snyk.json