Skip to content

Commit

Permalink
Use Trivy GCR for Trivy vuln database
Browse files Browse the repository at this point in the history
  • Loading branch information
baksetercx committed Nov 26, 2024
1 parent d047bc2 commit bc616d8
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 22 deletions.
53 changes: 49 additions & 4 deletions pkg/scan/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import (
"os"
"os/exec"
"slices"
"strings"

"github.com/3lvia/cli/pkg/command"
"github.com/3lvia/cli/pkg/shared"
"github.com/3lvia/cli/pkg/utils"
"github.com/urfave/cli/v2"
"golang.org/x/mod/semver"
)

const commandName = "scan"
Expand Down Expand Up @@ -57,6 +59,7 @@ func scanImageCommand(
imageName string,
severity string,
disableError bool,
versionOlderThan0_57_1 bool,
runOptions *command.RunOptions,
) command.Output {
exitCode := func() string {
Expand All @@ -78,17 +81,22 @@ func scanImageCommand(
"json",
"--output",
"trivy.json",
"--db-repository",
"ghcr.io/3lvia/trivy-db",
"--java-db-repository",
"ghcr.io/3lvia/trivy-java-db",
"--ignore-unfixed",
"--exit-code",
exitCode,
"--scanners",
"vuln",
)

// Before v0.57.1, the default database repository was using Aqua's GHCR which was heavily rate-limited.
// To circumvent this, we used a mirror of the database repository hosted on 3lvia's GHCR.
// This is no longer necessary as the default database repository is now hosted on Google Container Registry.
// So, we will only explicitly set the database repository if the version is older than 0.57.1.
if versionOlderThan0_57_1 {
cmd.Args = append(cmd.Args, "--db-repository", "mirror.gcr.io/aquasec/trivy-db:2")
cmd.Args = append(cmd.Args, "--java-db-repository", "mirror.gcr.io/aquasec/trivy-java-db:1")
}

cmd.Args = append(cmd.Args, imageName)

return command.Run(*cmd, runOptions)
Expand Down Expand Up @@ -135,10 +143,19 @@ func ScanImage(
formats []string,
disableError bool,
) error {
version, err := getTrivyVersion()
if err != nil {
log.Printf("Could not get Trivy version: %v", err)
log.Println("Will assume version is older than 0.57.1 and continue.")
} else {
log.Printf("Trivy version: %s", version)
}

scanImageOutput := scanImageCommand(
imageName,
severity,
disableError,
checkIfVersionOlderThan0_57_1(version),
nil,
)

Expand Down Expand Up @@ -212,3 +229,31 @@ func ScanImage(

return nil
}

func checkIfVersionOlderThan0_57_1(version string) bool {
if version == "" {
return true
}

return semver.Compare(version, "v0.57.1") == -1
}

func getTrivyVersion() (string, error) {
cmd := exec.Command("trivy", "--version")
output := command.Run(*cmd, nil)
if command.IsError(output) {
return "", output.Error
}

versionLine := strings.Split(output.Output, "\n")
if len(versionLine) < 1 {
return "", fmt.Errorf("Trivy version not found")
}

version, wasFound := strings.CutPrefix(versionLine[0], "Version: ")
if !wasFound {
return "", fmt.Errorf("Trivy version not found")
}

return "v" + version, nil
}
119 changes: 101 additions & 18 deletions pkg/scan/scan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ func TestScanImageCommandNormal(t *testing.T) {
const imageName = "test-image:latest"
const severity = "CRITICAL,HIGH"
const disableError = false
const versionOlderThan0_57_1 = false

expectedCommandString := strings.Join(
[]string{
Expand All @@ -24,10 +25,6 @@ func TestScanImageCommandNormal(t *testing.T) {
"json",
"--output",
"trivy.json",
"--db-repository",
"ghcr.io/3lvia/trivy-db",
"--java-db-repository",
"ghcr.io/3lvia/trivy-java-db",
"--ignore-unfixed",
"--exit-code",
"1",
Expand All @@ -42,6 +39,7 @@ func TestScanImageCommandNormal(t *testing.T) {
imageName,
severity,
disableError,
versionOlderThan0_57_1,
&command.RunOptions{DryRun: true},
)

Expand All @@ -56,6 +54,7 @@ func TestScanImageDisableErrorAndMoreSeverities(t *testing.T) {
const imageName = "test-image:latest"
const severity = "CRITICAL,HIGH,MEDIUM"
const disableError = true
const versionOlderThan0_57_1 = false

expectedCommandString := strings.Join(
[]string{
Expand All @@ -68,10 +67,6 @@ func TestScanImageDisableErrorAndMoreSeverities(t *testing.T) {
"json",
"--output",
"trivy.json",
"--db-repository",
"ghcr.io/3lvia/trivy-db",
"--java-db-repository",
"ghcr.io/3lvia/trivy-java-db",
"--ignore-unfixed",
"--exit-code",
"0",
Expand All @@ -86,6 +81,7 @@ func TestScanImageDisableErrorAndMoreSeverities(t *testing.T) {
imageName,
severity,
disableError,
versionOlderThan0_57_1,
&command.RunOptions{DryRun: true},
)

Expand All @@ -100,6 +96,7 @@ func TestScanImageCommandDisableErrorAndLessSeverities(t *testing.T) {
const imageName = "test-image:latest"
const severity = "CRITICAL"
const disableError = true
const versionOlderThan0_57_1 = false

expectedCommandString := strings.Join(
[]string{
Expand All @@ -112,10 +109,6 @@ func TestScanImageCommandDisableErrorAndLessSeverities(t *testing.T) {
"json",
"--output",
"trivy.json",
"--db-repository",
"ghcr.io/3lvia/trivy-db",
"--java-db-repository",
"ghcr.io/3lvia/trivy-java-db",
"--ignore-unfixed",
"--exit-code",
"0",
Expand All @@ -130,6 +123,7 @@ func TestScanImageCommandDisableErrorAndLessSeverities(t *testing.T) {
imageName,
severity,
disableError,
versionOlderThan0_57_1,
&command.RunOptions{DryRun: true},
)

Expand All @@ -144,6 +138,7 @@ func TestScanImageCommandEventMoreSeverities(t *testing.T) {
const imageName = "test-image:latest"
const severity = "CRITICAL,HIGH,MEDIUM,LOW"
const disableError = true
const versionOlderThan0_57_1 = false

expectedCommandString := strings.Join(
[]string{
Expand All @@ -156,10 +151,6 @@ func TestScanImageCommandEventMoreSeverities(t *testing.T) {
"json",
"--output",
"trivy.json",
"--db-repository",
"ghcr.io/3lvia/trivy-db",
"--java-db-repository",
"ghcr.io/3lvia/trivy-java-db",
"--ignore-unfixed",
"--exit-code",
"0",
Expand All @@ -174,6 +165,7 @@ func TestScanImageCommandEventMoreSeverities(t *testing.T) {
imageName,
severity,
disableError,
versionOlderThan0_57_1,
&command.RunOptions{DryRun: true},
)

Expand All @@ -188,6 +180,7 @@ func TestScanImageCommandAllSeveritiesAndVersionTag(t *testing.T) {
const imageName = "test-image:v42"
const severity = "CRITICAL,HIGH,MEDIUM,LOW,UNKNOWN"
const disableError = false
const versionOlderThan0_57_1 = false

expectedCommandString := strings.Join(
[]string{
Expand All @@ -200,15 +193,104 @@ func TestScanImageCommandAllSeveritiesAndVersionTag(t *testing.T) {
"json",
"--output",
"trivy.json",
"--ignore-unfixed",
"--exit-code",
"1",
"--scanners",
"vuln",
imageName,
},
" ",
)

actualCommand := scanImageCommand(
imageName,
severity,
disableError,
versionOlderThan0_57_1,
&command.RunOptions{DryRun: true},
)

command.ExpectedCommandStringEqualsActualCommand(
t,
expectedCommandString,
actualCommand,
)
}

func TestScanImageCommandVersionOlderThan0_57_1(t *testing.T) {
const imageName = "test-image:latest"
const severity = "CRITICAL,HIGH"
const disableError = false
const versionOlderThan0_57_1 = true

expectedCommandString := strings.Join(
[]string{
"trivy",
"image",
"--severity",
severity,
"--timeout",
"15m0s",
"--format",
"json",
"--output",
"trivy.json",
"--ignore-unfixed",
"--exit-code",
"1",
"--scanners",
"vuln",
"--db-repository",
"ghcr.io/3lvia/trivy-db",
"mirror.gcr.io/aquasec/trivy-db:2",
"--java-db-repository",
"ghcr.io/3lvia/trivy-java-db",
"mirror.gcr.io/aquasec/trivy-java-db:1",
imageName,
},
" ",
)

actualCommand := scanImageCommand(
imageName,
severity,
disableError,
versionOlderThan0_57_1,
&command.RunOptions{DryRun: true},
)

command.ExpectedCommandStringEqualsActualCommand(
t,
expectedCommandString,
actualCommand,
)
}

func TestScanImageCommandAllSeveritiesAndVersionTagAndVersionOlderThan0_57_1(t *testing.T) {
const imageName = "test-image:v42"
const severity = "CRITICAL,HIGH,MEDIUM,LOW,UNKNOWN"
const disableError = false
const versionOlderThan0_57_1 = true

expectedCommandString := strings.Join(
[]string{
"image",
"--severity",
severity,
"--timeout",
"15m0s",
"--format",
"json",
"--output",
"trivy.json",
"--ignore-unfixed",
"--exit-code",
"1",
"--scanners",
"vuln",
"--db-repository",
"mirror.gcr.io/aquasec/trivy-db:2",
"--java-db-repository",
"mirror.gcr.io/aquasec/trivy-java-db:1",
imageName,
},
" ",
Expand All @@ -218,6 +300,7 @@ func TestScanImageCommandAllSeveritiesAndVersionTag(t *testing.T) {
imageName,
severity,
disableError,
versionOlderThan0_57_1,
&command.RunOptions{DryRun: true},
)

Expand Down

0 comments on commit bc616d8

Please sign in to comment.