Skip to content

Commit

Permalink
Feat/trivy (#109)
Browse files Browse the repository at this point in the history
* Integrated trivy in code base and in Dockerfile

* changed to dockerfile in action.yml

* changed entrypoint.sh for aws auth

* feat: changed action.yml image to version 2.0.0 release

* feat: changed to release 1.0.0 in action.yml
  • Loading branch information
Bharadwajshivam28 authored Mar 3, 2025
1 parent 2926b32 commit fae2c73
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 95 deletions.
6 changes: 5 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ RUN apk add --no-cache \
unzip \
docker-cli \
aws-cli \
bash
bash \
docker

# Install Terraform
RUN curl -fsSL https://releases.hashicorp.com/terraform/1.5.7/terraform_1.5.7_linux_amd64.zip -o terraform.zip && \
unzip terraform.zip && \
mv terraform /usr/local/bin/ && \
rm terraform.zip

# Install Trivy (Vulnerability Scanner)
RUN curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

# Set working directory
WORKDIR /go/src/app

Expand Down
16 changes: 4 additions & 12 deletions cmd/sdkr/provisionHub.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ Set DOCKER_USERNAME and DOCKER_PASSWORD environment variables for Docker Hub aut
}
pterm.Success.Println("Build completed successfully.")

pterm.Info.Println("Starting scan...")
scanErr := docker.Scout(fullImageName, configs.SarifFile)
pterm.Info.Println("Starting scan with Trivy...")
scanErr := docker.Trivy(fullImageName)
if scanErr != nil {
pterm.Error.Println("Scan failed:", scanErr)
} else {
Expand Down Expand Up @@ -158,7 +158,7 @@ Set DOCKER_USERNAME and DOCKER_PASSWORD environment variables for Docker Hub aut
# Provide "myuser/myimage:latest" as an argument
smurf sdkr provision-hub myuser/myimage:latest --context . --file Dockerfile --no-cache \
--build-arg key1=value1 --build-arg key2=value2 --target my-target --platform linux/amd64 \
--output myscan.sarif --yes --delete
--yes --delete
# If you omit the argument, it will read from config and rely on "image_name" from there
smurf sdkr provision-hub --yes --delete
Expand Down Expand Up @@ -208,14 +208,6 @@ func init() {
"",
"Build context directory (default: current directory)",
)

provisionHubCmd.Flags().StringVarP(
&configs.SarifFile,
"output", "o",
"",
"Output file for SARIF report",
)

provisionHubCmd.Flags().BoolVarP(
&configs.ConfirmAfterPush,
"yes", "y",
Expand All @@ -230,4 +222,4 @@ func init() {
)

sdkrCmd.AddCommand(provisionHubCmd)
}
}
85 changes: 40 additions & 45 deletions cmd/sdkr/scan.go
Original file line number Diff line number Diff line change
@@ -1,58 +1,53 @@
package sdkr

import (
"errors"
"fmt"

"github.com/clouddrove/smurf/configs"
"github.com/clouddrove/smurf/internal/docker"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
"errors"
"fmt"
"github.com/clouddrove/smurf/configs"
"github.com/clouddrove/smurf/internal/docker"
"github.com/pterm/pterm"
"github.com/spf13/cobra"
)

// scanCmd provides functionality to scan a Docker image for known security issues.
// It supports both direct command-line arguments and configuration file values for the image name,
// and optionally allows saving the scan report to a specified SARIF file.
var scanCmd = &cobra.Command{
Use: "scan [IMAGE_NAME[:TAG]]",
Short: "Scan a Docker image for known vulnerabilities.",
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
var imageRef string

if len(args) == 1 {
imageRef = args[0]
} else {
data, err := configs.LoadConfig(configs.FileName)
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}
if data.Sdkr.ImageName == "" {
return errors.New("image name (with optional tag) must be provided either as an argument or in the config")
}
imageRef = data.Sdkr.ImageName
}

pterm.Info.Printf("Scanning Docker image %q...\n", imageRef)
err := docker.Scout(imageRef, configs.SarifFile)
if err != nil {
pterm.Error.Println("Scan failed:", err)
return err
}
pterm.Success.Println("Scan completed successfully.")
return nil
},
Example: `
smurf sdkr scan my-image:latest
smurf sdkr scan
# In the second example, it will read IMAGE_NAME from the config file
smurf sdkr scan my-image:latest --output scan.json
# Saves the scan report to 'scan.json' in SARIF format
Use: "scan [IMAGE_NAME[:TAG]]",
Short: "Scan a Docker image for known vulnerabilities.",
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
var imageRef string
if len(args) == 1 {
imageRef = args[0]
} else {
data, err := configs.LoadConfig(configs.FileName)
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}
if data.Sdkr.ImageName == "" {
return errors.New("image name (with optional tag) must be provided either as an argument or in the config")
}
imageRef = data.Sdkr.ImageName
}

pterm.Info.Printf("Scanning Docker image %q...\n", imageRef)
err := docker.Trivy(imageRef)
if err != nil {
pterm.Error.Println("Scan failed:", err)
return err
}

pterm.Success.Println("Scan completed successfully.")
return nil
},
Example: `
smurf sdkr scan my-image:latest
smurf sdkr scan
# In the second example, it will read IMAGE_NAME from the config file
`,
}

func init() {
scanCmd.Flags().StringVarP(&configs.SarifFile, "output", "o", "", "Output file for SARIF report")
sdkrCmd.AddCommand(scanCmd)
}
sdkrCmd.AddCommand(scanCmd)
}
9 changes: 7 additions & 2 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,13 @@ if [[ -n "$DOCKER_USERNAME" && -n "$DOCKER_PASSWORD" ]]; then
echo "✅ Successfully logged into Docker Hub."
fi

# Perform AWS and EKS login
aws_eks_login
# Perform AWS and EKS login only if AWS_AUTH=true
if [[ "$AWS_AUTH" == "true" ]]; then
echo "🔹 AWS authentication is enabled. Performing AWS login..."
aws_eks_login
else
echo "⚠️ AWS authentication is disabled. Skipping AWS login."
fi

# Initialize command with base command
SMURF_CMD="/usr/local/bin/smurf"
Expand Down
52 changes: 17 additions & 35 deletions internal/docker/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,62 +4,44 @@ import (
"bytes"
"context"
"fmt"
"os"
"os/exec"

"github.com/fatih/color"
"github.com/pterm/pterm"
)

// Scout runs 'docker scout cves' to scan a Docker image for vulnerabilities
// and optionally saves the results to a SARIF file.
// It displays the output of the scan and prints a success message upon completion.
func Scout(dockerTag, sarifFile string) error {
// Trivy runs 'trivy image' to scan a Docker image for vulnerabilities
// and displays the results. It's a simplified version that accepts just the image name and tag.
func Trivy(dockerImage string) error {
ctx := context.Background()

args := []string{"scout", "cves", dockerTag}

if sarifFile != "" {
args = append(args, "--output", sarifFile)
}

cmd := exec.CommandContext(ctx, "docker", args...)

args := []string{"image", dockerImage, "--format", "table"}

cmd := exec.CommandContext(ctx, "trivy", args...)
var stdoutBuf, stderrBuf bytes.Buffer
cmd.Stdout = &stdoutBuf
cmd.Stderr = &stderrBuf

spinner, _ := pterm.DefaultSpinner.Start("Running 'docker scout cves'")
spinner, _ := pterm.DefaultSpinner.Start("Running 'trivy image' scan")
defer spinner.Stop()

err := cmd.Run()

spinner.Stop()

outStr := stdoutBuf.String()
errStr := stderrBuf.String()

if err != nil {
pterm.Error.Println("Error running 'docker scout cves':", err)
pterm.Error.Println("Error running 'trivy image':", err)
if errStr != "" {
pterm.Error.Println(errStr)
}
return fmt.Errorf("failed to run 'docker scout cves': %w", err)
return fmt.Errorf("failed to run 'trivy image': %w", err)
}

if outStr != "" {
pterm.Info.Println("Docker Scout CVEs output:")
pterm.Info.Println("Trivy scan results:")
fmt.Println(color.YellowString(outStr))
}

if sarifFile != "" {
if _, err := os.Stat(sarifFile); err == nil {
pterm.Success.Println("SARIF report saved to:", sarifFile)
} else {
pterm.Warning.Println("Expected SARIF report not found at:", sarifFile)
}
}


pterm.Success.Println("Scan completed successfully.")
return nil
}
}

0 comments on commit fae2c73

Please sign in to comment.