scanner

package
v0.0.0-...-0979862 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package scanner provides Docker-based scanner orchestration for SAST tools.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ContainerConfig

type ContainerConfig struct {
	Image       string
	Cmd         []string
	Entrypoint  []string
	Env         []string
	Mounts      []Mount
	CPUQuota    int64
	MemoryMB    int64
	WorkingDir  string
	NetworkMode string // "none" by default — SAST doesn't need network
}

ContainerConfig contains configuration for creating a container.

type ContainerInspect

type ContainerInspect struct {
	State struct {
		ExitCode int64
		Running  bool
		Status   string
	}
}

ContainerInspect contains container state information.

type DockerClient

type DockerClient interface {
	ImageBuild(ctx context.Context, buildContext io.Reader, options ImageBuildOptions) (io.ReadCloser, error)
	ContainerCreate(ctx context.Context, config *ContainerConfig) (string, error)
	ContainerStart(ctx context.Context, containerID string) error
	ContainerWait(ctx context.Context, containerID string) (int64, error)
	ContainerLogs(ctx context.Context, containerID string) (io.ReadCloser, error)
	ContainerInspect(ctx context.Context, containerID string) (*ContainerInspect, error)
	ContainerRemove(ctx context.Context, containerID string, force bool) error
	ContainerStop(ctx context.Context, containerID string, timeout *time.Duration) error
}

DockerClient defines the interface for Docker operations. This abstraction allows for easy testing with mocks.

type DockerRunner

type DockerRunner struct {
	// contains filtered or unexported fields
}

DockerRunner orchestrates Docker containers for running SAST scanners.

func NewDockerRunner

func NewDockerRunner(client DockerClient) (*DockerRunner, error)

NewDockerRunner creates a new DockerRunner with the given Docker client.

func (*DockerRunner) BuildImage

func (d *DockerRunner) BuildImage(ctx context.Context, scannerName, dockerfilePath string) (string, error)

BuildImage builds a Docker image from the specified Dockerfile.

func (*DockerRunner) Run

func (d *DockerRunner) Run(ctx context.Context, opts RunOptions) (*RunResult, error)

Run executes a scanner container with the specified options.

func (*DockerRunner) SetLogWriter

func (d *DockerRunner) SetLogWriter(w io.Writer)

SetLogWriter sets an optional writer for capturing build and execution output. Useful for verbose logging during debugging.

type ImageBuildOptions

type ImageBuildOptions struct {
	Tags       []string
	Dockerfile string
}

ImageBuildOptions contains options for building a Docker image.

type LocalRunOptions

type LocalRunOptions struct {
	ExecutablePath string
	Args           []string
	CorpusPath     string
	OutputDir      string
	TimeoutMinutes int
	EnvVars        map[string]string
	OutputFile     string // Expected output filename (default: "results.sarif")
}

LocalRunOptions contains options for running a scanner as a local process.

type LocalRunner

type LocalRunner struct{}

LocalRunner executes scanners as local processes instead of Docker containers.

func NewLocalRunner

func NewLocalRunner() *LocalRunner

NewLocalRunner creates a new LocalRunner.

func (*LocalRunner) Run

func (l *LocalRunner) Run(ctx context.Context, opts LocalRunOptions) (*RunResult, error)

Run executes a scanner as a local process.

type Mount

type Mount struct {
	Source   string
	Target   string
	ReadOnly bool
}

Mount represents a bind mount configuration.

type RealDockerClient

type RealDockerClient struct{}

RealDockerClient implements the DockerClient interface using the Docker CLI. This is a simplified implementation that shells out to the Docker binary.

func NewRealDockerClient

func NewRealDockerClient() (*RealDockerClient, error)

NewRealDockerClient creates a new RealDockerClient after verifying Docker is available.

func (*RealDockerClient) ContainerCreate

func (c *RealDockerClient) ContainerCreate(ctx context.Context, config *ContainerConfig) (string, error)

ContainerCreate creates a new container.

func (*RealDockerClient) ContainerInspect

func (c *RealDockerClient) ContainerInspect(ctx context.Context, containerID string) (*ContainerInspect, error)

ContainerInspect returns information about a container.

func (*RealDockerClient) ContainerLogs

func (c *RealDockerClient) ContainerLogs(ctx context.Context, containerID string) (io.ReadCloser, error)

ContainerLogs returns the logs from a container.

func (*RealDockerClient) ContainerRemove

func (c *RealDockerClient) ContainerRemove(ctx context.Context, containerID string, force bool) error

ContainerRemove removes a container.

func (*RealDockerClient) ContainerStart

func (c *RealDockerClient) ContainerStart(ctx context.Context, containerID string) error

ContainerStart starts a container.

func (*RealDockerClient) ContainerStop

func (c *RealDockerClient) ContainerStop(ctx context.Context, containerID string, timeout *time.Duration) error

ContainerStop stops a container.

func (*RealDockerClient) ContainerWait

func (c *RealDockerClient) ContainerWait(ctx context.Context, containerID string) (int64, error)

ContainerWait waits for a container to stop and returns its exit code.

func (*RealDockerClient) ImageBuild

func (c *RealDockerClient) ImageBuild(ctx context.Context, buildContext io.Reader, options ImageBuildOptions) (io.ReadCloser, error)

ImageBuild builds a Docker image from the provided context.

type RegisterOptions

type RegisterOptions struct {
	Name           string
	Version        string
	DockerImage    string
	ExecutionMode  string // "docker" or "local" (default: "docker")
	ExecutablePath string // required when execution_mode = "local"
	ConfigJSON     string
}

RegisterOptions contains options for registering a scanner.

type RunOptions

type RunOptions struct {
	Image          string
	CorpusPath     string
	OutputDir      string
	CPU            float64
	MemoryMB       int64
	TimeoutMinutes int
	EnvVars        map[string]string
	Cmd            []string // Override container CMD
	Entrypoint     []string // Override container ENTRYPOINT
	OutputFile     string   // Expected output filename (default: "results.sarif")
}

RunOptions contains options for running a scanner container.

type RunResult

type RunResult struct {
	ExitCode        int64
	DurationMs      int64
	MemoryPeakBytes int64
	OutputPath      string // Path to scanner output file (renamed from SarifPath)
	Logs            string
	Error           error
}

RunResult contains the results of a scanner run.

type ScanOptions

type ScanOptions struct {
	ExperimentID   int64
	Iteration      int
	CPU            float64
	MemoryMB       int64
	TimeoutMinutes int
	// RunID, when set, reuses an existing run record instead of creating a new one.
	// Used by the experiment engine which pre-creates pending runs.
	RunID int64
	// ConfigOverrides allows per-run override of scanner configuration.
	// Fields set here take precedence over the scanner's registered config.
	ConfigOverrides *ScannerConfig
	// ImportPath is the path to a pre-existing output file. When set, Docker
	// execution is skipped and the file is imported directly.
	ImportPath string
	// FormatOverride overrides the scanner's configured output format for
	// imports (e.g., "sarif", "semgrep-json").
	FormatOverride string
}

ScanOptions contains options for running a scan.

type ScannerConfig

type ScannerConfig struct {
	// Cmd overrides the container's CMD. If empty, uses the image default (entrypoint.sh).
	Cmd []string `json:"cmd,omitempty"`

	// Entrypoint overrides the container's ENTRYPOINT. If empty, uses the image default.
	Entrypoint []string `json:"entrypoint,omitempty"`

	// Env contains additional environment variables passed to the container.
	// These are merged with the standard env vars (SCANNER_NAME, SCANNER_VERSION, TARGET_LANGUAGE).
	Env map[string]string `json:"env,omitempty"`

	// OutputFormat specifies the expected output format. Used by the normalisation
	// layer to select the appropriate converter.
	// Supported values: "sarif" (default), "semgrep-json".
	OutputFormat string `json:"output_format,omitempty"`

	// OutputFile specifies the output filename within /output/.
	// If empty, derived from OutputFormat: "sarif" → "results.sarif", others → "results.json".
	OutputFile string `json:"output_file,omitempty"`
}

ScannerConfig holds structured execution parameters for a scanner. Stored as JSON in the scanner's config_json database field.

func ParseScannerConfig

func ParseScannerConfig(configJSON string) (ScannerConfig, error)

ParseScannerConfig parses a JSON string into a ScannerConfig. Returns a zero-value ScannerConfig if the input is empty.

func (ScannerConfig) Merge

func (c ScannerConfig) Merge(overrides ScannerConfig) ScannerConfig

Merge returns a new config with overrides applied on top of the base config. Non-zero override fields take precedence. Env maps are merged with override keys winning.

func (ScannerConfig) ResolvedOutputFile

func (c ScannerConfig) ResolvedOutputFile() string

ResolvedOutputFile returns the expected output filename. If OutputFile is set explicitly, returns that. Otherwise derives from OutputFormat: "sarif" or "" → "results.sarif", anything else → "results.json".

func (ScannerConfig) ResolvedOutputFormat

func (c ScannerConfig) ResolvedOutputFormat() string

ResolvedOutputFormat returns the output format, defaulting to "sarif".

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service provides scanner management and execution operations.

func NewService

func NewService(s Store, runner *DockerRunner, cfg ServiceConfig) (*Service, error)

NewService creates a new scanner service.

func (*Service) Build

func (s *Service) Build(ctx context.Context, scannerName string) error

Build builds a Docker image for the specified scanner from its Dockerfile. If a prepare.sh script exists in the scanner directory, it is executed first to set up the build context (e.g., copying external source files).

func (*Service) List

func (s *Service) List(ctx context.Context) ([]store.Scanner, error)

List returns all registered scanners.

func (*Service) Register

func (s *Service) Register(ctx context.Context, opts RegisterOptions) (*store.Scanner, error)

Register creates a new scanner registration in the database.

func (*Service) Scan

func (s *Service) Scan(ctx context.Context, scannerName, projectName string, opts ScanOptions) (*store.Run, error)

Scan orchestrates a complete scan: create run, execute container, parse SARIF, store findings.

type ServiceConfig

type ServiceConfig struct {
	ScannersDir string
	OutputDir   string
	Converters  *normalise.Registry
}

ServiceConfig contains configuration for the scanner service.

type Store

type Store interface {
	CreateScanner(ctx context.Context, sc *store.Scanner) (int64, error)
	GetScanner(ctx context.Context, id int64) (*store.Scanner, error)
	GetScannerByNameVersion(ctx context.Context, name, version string) (*store.Scanner, error)
	ListScanners(ctx context.Context) ([]store.Scanner, error)
	GetProject(ctx context.Context, id int64) (*store.CorpusProject, error)
	GetProjectByName(ctx context.Context, name string) (*store.CorpusProject, error)
	CreateRun(ctx context.Context, r *store.Run) (int64, error)
	GetRun(ctx context.Context, id int64) (*store.Run, error)
	UpdateRunStatus(ctx context.Context, id int64, status store.RunStatus, startedAt, completedAt sql.NullTime, durationMs, memoryPeakBytes sql.NullInt64, sarifPath, logPath, errorMessage sql.NullString) error
	BulkCreateFindings(ctx context.Context, findings []store.Finding) error
}

Store defines the interface for scanner persistence operations.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL