scan

package
v0.1.6 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2026 License: GPL-3.0 Imports: 5 Imported by: 0

Documentation

Overview

Package scan defines the Scan domain entity and types. A Scan binds an Asset Group with a Scanner/Workflow and Schedule.

Index

Constants

View Source
const (
	// MinScanTimeoutSeconds is the minimum allowed scan timeout (30 seconds).
	// Lower values would create DoS pressure on the timeout sweeper.
	MinScanTimeoutSeconds = 30
	// DefaultScanTimeoutSeconds is the default scan timeout (1 hour).
	DefaultScanTimeoutSeconds = 3600
	// MaxScanTimeoutSeconds is the maximum allowed scan timeout (24 hours).
	MaxScanTimeoutSeconds = 86400
)

Timeout constants for scan execution.

View Source
const (
	// MaxRetryCount is the absolute maximum retries allowed per scan.
	MaxRetryCount = 10
	// DefaultRetryBackoffSeconds is the default initial backoff between retries.
	DefaultRetryBackoffSeconds = 60
	// MinRetryBackoffSeconds is the minimum allowed initial backoff.
	MinRetryBackoffSeconds = 10
	// MaxRetryBackoffSeconds is the maximum allowed initial backoff (24 hours).
	MaxRetryBackoffSeconds = 86400
)

Retry constants for scan execution.

Variables

This section is empty.

Functions

This section is empty.

Types

type AgentPreference

type AgentPreference string

AgentPreference determines which agents can execute the scan.

const (
	// AgentPreferenceAuto tries tenant agents first, falls back to platform.
	AgentPreferenceAuto AgentPreference = "auto"
	// AgentPreferenceTenant only uses tenant's own agents.
	AgentPreferenceTenant AgentPreference = "tenant"
	// AgentPreferencePlatform only uses platform agents.
	AgentPreferencePlatform AgentPreference = "platform"
)

type Filter

type Filter struct {
	TenantID     *shared.ID
	AssetGroupID *shared.ID
	PipelineID   *shared.ID
	ScanType     *ScanType
	ScheduleType *ScheduleType
	Status       *Status
	Tags         []string
	Search       string
}

Filter represents filter options for listing scans.

type OverviewStats

type OverviewStats struct {
	Pipelines StatusCounts `json:"pipelines"`
	Scans     StatusCounts `json:"scans"`
	Jobs      StatusCounts `json:"jobs"`
}

OverviewStats represents the scan management overview statistics.

type Repository

type Repository interface {
	// Create creates a new scan.
	Create(ctx context.Context, scan *Scan) error

	// GetByID retrieves a scan by ID.
	GetByID(ctx context.Context, id shared.ID) (*Scan, error)

	// GetByTenantAndID retrieves a scan by tenant and ID.
	GetByTenantAndID(ctx context.Context, tenantID, id shared.ID) (*Scan, error)

	// GetByName retrieves a scan by tenant and name.
	GetByName(ctx context.Context, tenantID shared.ID, name string) (*Scan, error)

	// List lists scans with filters and pagination.
	List(ctx context.Context, filter Filter, page pagination.Pagination) (pagination.Result[*Scan], error)

	// Update updates a scan.
	Update(ctx context.Context, scan *Scan) error

	// Delete deletes a scan.
	Delete(ctx context.Context, id shared.ID) error

	// ListDueForExecution lists scans that are due for scheduled execution.
	ListDueForExecution(ctx context.Context, now time.Time) ([]*Scan, error)

	// UpdateNextRunAt updates the next run time for a scan.
	UpdateNextRunAt(ctx context.Context, id shared.ID, nextRunAt *time.Time) error

	// RecordRun records a run result for a scan.
	RecordRun(ctx context.Context, id shared.ID, runID shared.ID, status string) error

	// GetStats returns aggregated statistics for scans.
	GetStats(ctx context.Context, tenantID shared.ID) (*Stats, error)

	// Count counts scans matching the filter.
	Count(ctx context.Context, filter Filter) (int64, error)

	// ListByAssetGroupID lists all scans for an asset group.
	ListByAssetGroupID(ctx context.Context, assetGroupID shared.ID) ([]*Scan, error)

	// ListByPipelineID lists all scans using a pipeline.
	ListByPipelineID(ctx context.Context, pipelineID shared.ID) ([]*Scan, error)

	// UpdateStatusByAssetGroupID updates status for all scans in an asset group.
	UpdateStatusByAssetGroupID(ctx context.Context, assetGroupID shared.ID, status Status) error

	// TryLockScanForScheduler attempts to acquire a session-level advisory lock
	// for the given scan ID. Returns true if the lock was acquired, false if
	// another instance already holds it. The lock must be released with
	// UnlockScanForScheduler when the trigger completes.
	TryLockScanForScheduler(ctx context.Context, id shared.ID) (bool, error)

	// UnlockScanForScheduler releases a previously acquired scheduler lock for the given scan ID.
	UnlockScanForScheduler(ctx context.Context, id shared.ID) error
}

Repository defines the interface for scan persistence.

type Scan

type Scan struct {
	ID          shared.ID
	TenantID    shared.ID
	Name        string
	Description string

	// Target - can use AssetGroupID/AssetGroupIDs, Targets, or both
	AssetGroupID  shared.ID   // Optional: primary asset group (legacy, for single asset group)
	AssetGroupIDs []shared.ID // Optional: multiple asset groups (NEW)
	Targets       []string    // Optional: direct target list (domains, IPs, URLs)

	// Scan Type
	ScanType      ScanType
	PipelineID    *shared.ID     // For workflow type
	ScannerName   string         // For single type
	ScannerConfig map[string]any // Scanner-specific configuration
	TargetsPerJob int            // Number of targets per job batch

	// Schedule
	ScheduleType     ScheduleType
	ScheduleCron     string     // Cron expression (for crontab type)
	ScheduleDay      *int       // Day of week (0-6) or month (1-31)
	ScheduleTime     *time.Time // Time of day to run
	ScheduleTimezone string
	NextRunAt        *time.Time // Pre-computed next run time

	// Routing
	Tags              []string        // Route to agents with matching tags
	RunOnTenantRunner bool            // Restrict to tenant's own runners
	AgentPreference   AgentPreference // Agent selection mode: auto, tenant, platform

	// Profile - links to ScanProfile for tool configs, intensity, quality gates
	ProfileID *shared.ID

	// Timeout - max execution time in seconds (default 3600 = 1h, max 86400 = 24h)
	TimeoutSeconds int

	// Retry config - automatic retry of failed runs with exponential backoff
	MaxRetries          int // 0 = no retry, max 10
	RetryBackoffSeconds int // Initial backoff (default 60s), actual delay is backoff * 2^attempt

	// Status
	Status Status

	// Execution Statistics
	LastRunID      *shared.ID
	LastRunAt      *time.Time
	LastRunStatus  string
	TotalRuns      int
	SuccessfulRuns int
	FailedRuns     int

	// Audit
	CreatedBy *shared.ID
	CreatedAt time.Time
	UpdatedAt time.Time
}

Scan represents a scan definition that binds an asset group with a scanner/workflow and schedule.

func NewScan

func NewScan(tenantID shared.ID, name string, assetGroupID shared.ID, scanType ScanType) (*Scan, error)

NewScan creates a new scan definition. assetGroupID is optional if targets are provided later via SetTargets.

func NewScanWithTargets

func NewScanWithTargets(tenantID shared.ID, name string, targets []string, scanType ScanType) (*Scan, error)

NewScanWithTargets creates a new scan definition with direct targets. This is used when creating scans without a pre-existing asset group.

func (*Scan) Activate

func (s *Scan) Activate() error

Activate activates the scan.

func (*Scan) CalculateNextRunAt

func (s *Scan) CalculateNextRunAt() *time.Time

CalculateNextRunAt returns the next scheduled run time. This is used by the scheduler to update next_run_at after triggering.

func (*Scan) CalculateRetryDelay added in v0.1.5

func (s *Scan) CalculateRetryDelay(attempt int) time.Duration

CalculateRetryDelay returns the exponential backoff delay for the given attempt number. attempt 0 = first retry, attempt 1 = second retry, etc. Capped at MaxRetryBackoffSeconds.

func (*Scan) CanTrigger

func (s *Scan) CanTrigger() bool

CanTrigger returns true if the scan can be triggered.

func (*Scan) Clone

func (s *Scan) Clone(newName string) *Scan

Clone creates a copy of the scan with a new ID.

func (*Scan) Disable

func (s *Scan) Disable() error

Disable disables the scan.

func (*Scan) GetAllAssetGroupIDs

func (s *Scan) GetAllAssetGroupIDs() []shared.ID

GetAllAssetGroupIDs returns all asset group IDs (both singular and multiple).

func (*Scan) HasAssetGroup

func (s *Scan) HasAssetGroup() bool

HasAssetGroup returns true if the scan is linked to an asset group.

func (*Scan) HasTargets

func (s *Scan) HasTargets() bool

HasTargets returns true if the scan has direct targets.

func (*Scan) IsDueForExecution

func (s *Scan) IsDueForExecution(now time.Time) bool

IsDueForExecution returns true if the scan is due for scheduled execution.

func (*Scan) Pause

func (s *Scan) Pause() error

Pause pauses the scan (scheduled scans won't run).

func (*Scan) RecordRun

func (s *Scan) RecordRun(runID shared.ID, status string)

RecordRun records the result of a scan run.

func (*Scan) SetAgentPreference

func (s *Scan) SetAgentPreference(pref AgentPreference)

SetAgentPreference sets the agent selection preference.

func (*Scan) SetAssetGroupIDs

func (s *Scan) SetAssetGroupIDs(ids []shared.ID)

SetAssetGroupIDs sets multiple asset group IDs for the scan.

func (*Scan) SetCreatedBy

func (s *Scan) SetCreatedBy(userID shared.ID)

SetCreatedBy sets the user who created the scan.

func (*Scan) SetProfileID added in v0.1.5

func (s *Scan) SetProfileID(profileID *shared.ID)

SetProfileID links the scan to a scan profile (for tool configs and quality gates). Pass nil to unlink.

func (*Scan) SetRetryConfig added in v0.1.5

func (s *Scan) SetRetryConfig(maxRetries, backoffSeconds int)

SetRetryConfig configures the retry behavior for failed runs. maxRetries is capped at MaxRetryCount; backoff is bounded to [Min,Max]RetryBackoffSeconds.

func (*Scan) SetRunOnTenantRunner

func (s *Scan) SetRunOnTenantRunner(value bool)

SetRunOnTenantRunner sets whether to restrict to tenant runners only.

func (*Scan) SetSchedule

func (s *Scan) SetSchedule(scheduleType ScheduleType, cron string, day *int, t *time.Time, timezone string) error

SetSchedule configures the schedule for the scan.

func (*Scan) SetSingleScanner

func (s *Scan) SetSingleScanner(scannerName string, config map[string]any, targetsPerJob int) error

SetSingleScanner configures the scan to use a single scanner.

func (*Scan) SetTags

func (s *Scan) SetTags(tags []string)

SetTags sets the routing tags.

func (*Scan) SetTargets

func (s *Scan) SetTargets(targets []string)

SetTargets sets the direct target list for the scan.

func (*Scan) SetTimeoutSeconds added in v0.1.5

func (s *Scan) SetTimeoutSeconds(seconds int)

SetTimeoutSeconds sets the maximum execution time in seconds. Enforces [MinScanTimeoutSeconds, MaxScanTimeoutSeconds] bounds at the domain layer (defense-in-depth — even if HTTP validation is bypassed, the domain enforces the floor). If <= 0, defaults to DefaultScanTimeoutSeconds.

func (*Scan) SetWorkflow

func (s *Scan) SetWorkflow(pipelineID shared.ID) error

SetWorkflow configures the scan to use a workflow pipeline.

func (*Scan) ShouldRetry added in v0.1.5

func (s *Scan) ShouldRetry(currentAttempt int) bool

ShouldRetry returns true if a failed run with the given retry attempt should be retried.

func (*Scan) Update

func (s *Scan) Update(name, description string) error

Update updates the scan fields.

func (*Scan) Validate

func (s *Scan) Validate() error

Validate validates the scan.

type ScanType

type ScanType string

ScanType represents the type of scan to execute.

const (
	// ScanTypeWorkflow executes a multi-step pipeline workflow.
	ScanTypeWorkflow ScanType = "workflow"
	// ScanTypeSingle executes a single scanner.
	ScanTypeSingle ScanType = "single"
)

type ScheduleType

type ScheduleType string

ScheduleType represents when the scan should run.

const (
	ScheduleManual  ScheduleType = "manual"
	ScheduleDaily   ScheduleType = "daily"
	ScheduleWeekly  ScheduleType = "weekly"
	ScheduleMonthly ScheduleType = "monthly"
	ScheduleCrontab ScheduleType = "crontab"
)

type Stats

type Stats struct {
	Total          int64                  `json:"total"`
	Active         int64                  `json:"active"`
	Paused         int64                  `json:"paused"`
	Disabled       int64                  `json:"disabled"`
	ByScheduleType map[ScheduleType]int64 `json:"by_schedule_type"`
	ByScanType     map[ScanType]int64     `json:"by_scan_type"`
}

Stats represents aggregated statistics for scans.

type Status

type Status string

Status represents the scan status.

const (
	StatusActive   Status = "active"
	StatusPaused   Status = "paused"
	StatusDisabled Status = "disabled"
)

type StatusCounts

type StatusCounts struct {
	Total     int64 `json:"total"`
	Running   int64 `json:"running"`
	Pending   int64 `json:"pending"`
	Completed int64 `json:"completed"`
	Failed    int64 `json:"failed"`
	Canceled  int64 `json:"canceled"`
}

StatusCounts represents counts by status.

Jump to

Keyboard shortcuts

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