Documentation
¶
Index ¶
- Constants
- type AgentAvailability
- type AgentSelector
- type AssetCompatibilityPreview
- type AssetFilterService
- type AuditContext
- type AuditEvent
- type AuditService
- type BulkActionResult
- type CreateScanInput
- type CreateScanResult
- type EmbeddedTemplate
- type FilteringResult
- type ListScansInput
- type OverviewStats
- type QuickScanInput
- type QuickScanResult
- type ScanConfigExport
- type SecurityValidator
- type SelectAgentRequest
- type SelectAgentResult
- type SelectMode
- type Service
- func (s *Service) ActivateScan(ctx context.Context, tenantID, scanID string) (*scan.Scan, error)
- func (s *Service) BulkActivate(ctx context.Context, tenantID string, scanIDs []string) (*BulkActionResult, error)
- func (s *Service) BulkDelete(ctx context.Context, tenantID string, scanIDs []string) (*BulkActionResult, error)
- func (s *Service) BulkDisable(ctx context.Context, tenantID string, scanIDs []string) (*BulkActionResult, error)
- func (s *Service) BulkPause(ctx context.Context, tenantID string, scanIDs []string) (*BulkActionResult, error)
- func (s *Service) CloneScan(ctx context.Context, tenantID, scanID, newName string) (*scan.Scan, error)
- func (s *Service) CreateScan(ctx context.Context, input CreateScanInput) (*scan.Scan, error)
- func (s *Service) DeactivateScansByPipeline(ctx context.Context, pipelineID shared.ID) (int, error)
- func (s *Service) DeleteScan(ctx context.Context, tenantID, scanID string) error
- func (s *Service) DisableScan(ctx context.Context, tenantID, scanID string) (*scan.Scan, error)
- func (s *Service) ExportConfig(ctx context.Context, tenantID, scanID shared.ID) ([]byte, error)
- func (s *Service) GetLatestScanRun(ctx context.Context, tenantID, scanID string) (*pipeline.Run, error)
- func (s *Service) GetOverviewStats(ctx context.Context, tenantID string) (*OverviewStats, error)
- func (s *Service) GetScan(ctx context.Context, tenantID, scanID string) (*scan.Scan, error)
- func (s *Service) GetScanRun(ctx context.Context, tenantID, scanID, runID string) (*pipeline.Run, error)
- func (s *Service) GetStats(ctx context.Context, tenantID string) (*scan.Stats, error)
- func (s *Service) ImportConfig(ctx context.Context, tenantID shared.ID, data []byte) (*scan.Scan, error)
- func (s *Service) ListScanRuns(ctx context.Context, tenantID, scanID string, page, perPage int) (map[string]any, error)
- func (s *Service) ListScans(ctx context.Context, input ListScansInput) (pagination.Result[*scan.Scan], error)
- func (s *Service) PauseScan(ctx context.Context, tenantID, scanID string) (*scan.Scan, error)
- func (s *Service) PreviewScanCompatibility(ctx context.Context, scannerName string, assetGroupIDs []shared.ID) (*AssetCompatibilityPreview, error)
- func (s *Service) QuickScan(ctx context.Context, input QuickScanInput) (*QuickScanResult, error)
- func (s *Service) RetryScanRun(ctx context.Context, tenantID, scanID shared.ID, retryAttempt int) error
- func (s *Service) TriggerScan(ctx context.Context, input TriggerScanExecInput) (*pipeline.Run, error)
- func (s *Service) UpdateScan(ctx context.Context, input UpdateScanInput) (*scan.Scan, error)
- type ServiceOption
- type SkipReason
- type StatusCounts
- type TemplateSyncResult
- type TemplateSyncer
- type TriggerScanExecInput
- type UpdateScanInput
- type ValidationError
- type ValidationResult
Constants ¶
const ( // MaxConcurrentRunsPerScan is the maximum concurrent runs per scan config. MaxConcurrentRunsPerScan = 3 // MaxConcurrentRunsPerTenant is the maximum concurrent runs per tenant. MaxConcurrentRunsPerTenant = 50 )
Concurrent run limits for scans.
const QuickScanTemplateID = "00000000-0000-0000-0000-000000000001"
QuickScanTemplateID is the system template ID for quick/single scans. This template is created during database migration/seed.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AgentAvailability ¶
type AgentAvailability struct {
HasTenantAgent bool
HasPlatformAgent bool
Available bool
Message string
}
AgentAvailability represents agent availability status.
type AgentSelector ¶
type AgentSelector interface {
CheckAgentAvailability(ctx context.Context, tenantID shared.ID, tool string, tenantOnly bool) *AgentAvailability
CanUsePlatformAgents(ctx context.Context, tenantID shared.ID) (bool, string)
SelectAgent(ctx context.Context, req SelectAgentRequest) (*SelectAgentResult, error)
}
AgentSelector interface for agent selection.
type AssetCompatibilityPreview ¶
type AssetCompatibilityPreview struct {
// Whether fully compatible
IsFullyCompatible bool `json:"is_fully_compatible"`
// Compatibility percentage (0-100)
CompatibilityPercent float64 `json:"compatibility_percent"`
// Counts by compatibility
CompatibleCount int `json:"compatible_count"`
IncompatibleCount int `json:"incompatible_count"`
UnclassifiedCount int `json:"unclassified_count"`
TotalCount int `json:"total_count"`
// Details
CompatibleTypes []string `json:"compatible_types,omitempty"`
IncompatibleTypes []string `json:"incompatible_types,omitempty"`
// Human-readable message
Message string `json:"message"`
}
AssetCompatibilityPreview represents a compatibility preview at scan creation. This is shown as a warning before the scan is created.
type AssetFilterService ¶
type AssetFilterService struct {
// contains filtered or unexported fields
}
AssetFilterService handles smart filtering of assets based on tool compatibility.
func NewAssetFilterService ¶
func NewAssetFilterService( targetMappingRepo tool.TargetMappingRepository, assetGroupRepo assetgroup.Repository, ) *AssetFilterService
NewAssetFilterService creates a new AssetFilterService.
func (*AssetFilterService) FilterAssetsForScan ¶
func (s *AssetFilterService) FilterAssetsForScan( ctx context.Context, toolTargets []string, toolName string, assetTypeCounts map[string]int64, ) (*FilteringResult, error)
FilterAssetsForScan filters assets based on tool compatibility. Returns the filtering result showing what was scanned vs skipped.
func (*AssetFilterService) PreviewCompatibility ¶
func (s *AssetFilterService) PreviewCompatibility( ctx context.Context, toolTargets []string, groupIDs []shared.ID, ) (*AssetCompatibilityPreview, error)
PreviewCompatibility checks asset compatibility at scan creation time. Returns a preview showing what percentage of assets will be scanned.
type AuditContext ¶
AuditContext contains context for audit logging.
type AuditEvent ¶
type AuditEvent struct {
Action audit.Action
ResourceType audit.ResourceType
ResourceID string
ResourceName string
Message string
Success bool
Error error
Metadata map[string]any
}
AuditEvent represents an audit event.
func NewFailureEvent ¶
func NewFailureEvent(action audit.Action, resourceType audit.ResourceType, resourceID string, err error) AuditEvent
NewFailureEvent creates a failure audit event.
func NewSuccessEvent ¶
func NewSuccessEvent(action audit.Action, resourceType audit.ResourceType, resourceID string) AuditEvent
NewSuccessEvent creates a success audit event.
func (AuditEvent) WithMessage ¶
func (e AuditEvent) WithMessage(msg string) AuditEvent
WithMessage sets the message.
func (AuditEvent) WithMetadata ¶
func (e AuditEvent) WithMetadata(key string, value any) AuditEvent
WithMetadata adds metadata.
func (AuditEvent) WithResourceName ¶
func (e AuditEvent) WithResourceName(name string) AuditEvent
WithResourceName sets the resource name.
type AuditService ¶
type AuditService interface {
LogEvent(ctx context.Context, actx AuditContext, event AuditEvent) error
}
AuditService interface for audit logging.
type BulkActionResult ¶
type BulkActionResult struct {
Successful []string `json:"successful"` // IDs that were successfully updated
Failed []struct {
ID string `json:"id"`
Error string `json:"error"`
} `json:"failed"` // IDs that failed with error messages
}
BulkActionResult represents the result of a bulk action.
type CreateScanInput ¶
type CreateScanInput struct {
TenantID string `json:"tenant_id" validate:"required,uuid"`
Name string `json:"name" validate:"required,min=1,max=200"`
Description string `json:"description" validate:"max=1000"`
AssetGroupID string `json:"asset_group_id" validate:"omitempty,uuid"` // Primary asset group (legacy)
AssetGroupIDs []string `json:"asset_group_ids" validate:"omitempty,dive,uuid"` // Multiple asset groups (NEW)
Targets []string `json:"targets" validate:"omitempty,max=1000"` // Direct targets
ScanType string `json:"scan_type" validate:"required,oneof=workflow single"`
PipelineID string `json:"pipeline_id" validate:"omitempty,uuid"`
ScannerName string `json:"scanner_name" validate:"max=100"`
ScannerConfig map[string]any `json:"scanner_config"`
TargetsPerJob int `json:"targets_per_job"`
ScheduleType string `json:"schedule_type" validate:"omitempty,oneof=manual daily weekly monthly crontab"`
ScheduleCron string `json:"schedule_cron" validate:"max=100"`
ScheduleDay *int `json:"schedule_day"`
ScheduleTime *time.Time `json:"schedule_time"`
Timezone string `json:"timezone" validate:"max=50"`
Tags []string `json:"tags" validate:"max=20,dive,max=50"`
TenantRunner bool `json:"run_on_tenant_runner"`
AgentPreference string `json:"agent_preference" validate:"omitempty,oneof=auto tenant platform"` // Agent selection mode: auto (default), tenant, platform
ProfileID string `json:"profile_id" validate:"omitempty,uuid"` // Optional scan profile (tool configs, quality gates)
TimeoutSeconds int `json:"timeout_seconds" validate:"omitempty,min=30,max=86400"` // Max execution time (default 3600, min 30, max 86400)
// Retry config: max_retries=0 disables retry; backoff is initial delay (exponential per attempt)
MaxRetries int `json:"max_retries" validate:"omitempty,min=0,max=10"`
RetryBackoffSeconds int `json:"retry_backoff_seconds" validate:"omitempty,min=10,max=86400"`
CreatedBy string `json:"created_by" validate:"omitempty,uuid"`
}
CreateScanInput represents the input for creating a scan. Either AssetGroupID/AssetGroupIDs OR Targets must be provided (can have all).
type CreateScanResult ¶
type CreateScanResult struct {
Scan *scan.Scan `json:"scan"`
CompatibilityWarning *AssetCompatibilityPreview `json:"compatibility_warning,omitempty"`
}
CreateScanResult represents the result of creating a scan. It includes the scan entity and optional compatibility warnings.
type EmbeddedTemplate ¶
type EmbeddedTemplate struct {
ID string `json:"id"`
Name string `json:"name"`
TemplateType string `json:"template_type"`
Content string `json:"content"` // Base64 encoded content
ContentHash string `json:"content_hash"` // SHA256 hash for verification
}
EmbeddedTemplate represents a template embedded in scan command payload. This is the format sent to agents for custom templates.
type FilteringResult ¶
type FilteringResult struct {
// Counts
TotalAssets int `json:"total_assets"`
ScannedAssets int `json:"scanned_assets"`
SkippedAssets int `json:"skipped_assets"`
UnclassifiedAssets int `json:"unclassified_assets"`
// Compatibility percentage (0-100)
CompatibilityPercent float64 `json:"compatibility_percent"`
// Details by asset type
ScannedByType map[string]int `json:"scanned_by_type,omitempty"`
SkippedByType map[string]int `json:"skipped_by_type,omitempty"`
// Reasons for skipping (for UI display)
SkipReasons []SkipReason `json:"skip_reasons,omitempty"`
// Whether any filtering occurred
WasFiltered bool `json:"was_filtered"`
// Tool info for context
ToolName string `json:"tool_name,omitempty"`
SupportedTargets []string `json:"supported_targets,omitempty"`
}
FilteringResult represents the result of smart filtering during scan trigger. It shows which assets were scanned vs skipped and why.
type ListScansInput ¶
type ListScansInput struct {
TenantID string `json:"tenant_id" validate:"required,uuid"`
AssetGroupID string `json:"asset_group_id" validate:"omitempty,uuid"`
PipelineID string `json:"pipeline_id" validate:"omitempty,uuid"`
ScanType string `json:"scan_type" validate:"omitempty,oneof=workflow single"`
ScheduleType string `json:"schedule_type" validate:"omitempty,oneof=manual daily weekly monthly crontab"`
Status string `json:"status" validate:"omitempty,oneof=active paused disabled"`
Tags []string `json:"tags"`
Search string `json:"search" validate:"max=255"`
Page int `json:"page"`
PerPage int `json:"per_page"`
}
ListScansInput represents the input for listing scans.
type OverviewStats ¶
type OverviewStats struct {
Pipelines StatusCounts `json:"pipelines"`
Scans StatusCounts `json:"scans"`
Jobs StatusCounts `json:"jobs"`
}
OverviewStats represents aggregated statistics for scan management overview.
type QuickScanInput ¶
type QuickScanInput struct {
TenantID string `json:"tenant_id" validate:"required,uuid"`
Targets []string `json:"targets" validate:"required,min=1,max=1000"`
ScannerName string `json:"scanner_name" validate:"omitempty,max=100"`
WorkflowID string `json:"workflow_id" validate:"omitempty,uuid"`
Config map[string]any `json:"config"`
Tags []string `json:"tags" validate:"max=20,dive,max=50"`
CreatedBy string `json:"created_by" validate:"omitempty,uuid"`
}
QuickScanInput represents the input for quick scan.
type QuickScanResult ¶
type QuickScanResult struct {
PipelineRunID string `json:"pipeline_run_id"`
ScanID string `json:"scan_id"`
AssetGroupID string `json:"asset_group_id"`
Status string `json:"status"`
TargetCount int `json:"target_count"`
}
QuickScanResult represents the result of a quick scan.
type ScanConfigExport ¶ added in v0.1.2
type ScanConfigExport struct {
// Metadata
Name string `json:"name"`
Description string `json:"description,omitempty"`
// Targets
AssetGroupIDs []string `json:"asset_group_ids,omitempty"`
Targets []string `json:"targets,omitempty"`
// Scan Type
ScanType string `json:"scan_type"`
PipelineID *string `json:"pipeline_id,omitempty"`
ScannerName string `json:"scanner_name,omitempty"`
ScannerConfig map[string]any `json:"scanner_config,omitempty"`
TargetsPerJob int `json:"targets_per_job"`
// Schedule
ScheduleType string `json:"schedule_type"`
ScheduleCron string `json:"schedule_cron,omitempty"`
ScheduleDay *int `json:"schedule_day,omitempty"`
ScheduleTime *string `json:"schedule_time,omitempty"`
ScheduleTimezone string `json:"schedule_timezone"`
// Routing
Tags []string `json:"tags,omitempty"`
RunOnTenantRunner bool `json:"run_on_tenant_runner"`
AgentPreference string `json:"agent_preference,omitempty"`
// Profile and timeout
ProfileID string `json:"profile_id,omitempty"`
TimeoutSeconds int `json:"timeout_seconds,omitempty"`
// Retry config
MaxRetries int `json:"max_retries,omitempty"`
RetryBackoffSeconds int `json:"retry_backoff_seconds,omitempty"`
// Export metadata
ExportedAt string `json:"exported_at"`
Version string `json:"version"`
}
ScanConfigExport represents the exportable configuration of a scan. It excludes runtime data like status, execution stats, and timestamps.
type SecurityValidator ¶
type SecurityValidator interface {
ValidateIdentifier(value string, maxLen int, fieldName string) *ValidationResult
ValidateIdentifiers(values []string, maxLen int, fieldName string) *ValidationResult
ValidateScannerConfig(ctx context.Context, tenantID shared.ID, config map[string]any) *ValidationResult
ValidateCronExpression(cronExpr string) error
}
SecurityValidator interface for security validation.
type SelectAgentRequest ¶
type SelectAgentRequest struct {
TenantID shared.ID
Capabilities []string
Tool string
Mode SelectMode
AllowQueue bool
}
SelectAgentRequest represents a request to select an agent.
type SelectAgentResult ¶
SelectAgentResult represents the result of agent selection.
type SelectMode ¶
type SelectMode int
SelectMode represents the agent selection mode.
const ( // SelectTenantFirst tries tenant agents first, then platform. SelectTenantFirst SelectMode = iota )
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service handles scan business operations.
func NewService ¶
func NewService( scanRepo scan.Repository, templateRepo pipeline.TemplateRepository, assetGroupRepo assetgroup.Repository, runRepo pipeline.RunRepository, stepRepo pipeline.StepRepository, stepRunRepo pipeline.StepRunRepository, commandRepo command.Repository, scannerTemplateRepo scannertemplate.Repository, templateSourceRepo templatesource.Repository, toolRepo tool.Repository, templateSyncer TemplateSyncer, agentSelector AgentSelector, securityValidator SecurityValidator, log *logger.Logger, opts ...ServiceOption, ) *Service
NewService creates a new Service.
func (*Service) ActivateScan ¶
ActivateScan activates a scan.
func (*Service) BulkActivate ¶
func (s *Service) BulkActivate(ctx context.Context, tenantID string, scanIDs []string) (*BulkActionResult, error)
BulkActivate activates multiple scans.
func (*Service) BulkDelete ¶
func (s *Service) BulkDelete(ctx context.Context, tenantID string, scanIDs []string) (*BulkActionResult, error)
BulkDelete deletes multiple scans.
func (*Service) BulkDisable ¶
func (s *Service) BulkDisable(ctx context.Context, tenantID string, scanIDs []string) (*BulkActionResult, error)
BulkDisable disables multiple scans.
func (*Service) BulkPause ¶
func (s *Service) BulkPause(ctx context.Context, tenantID string, scanIDs []string) (*BulkActionResult, error)
BulkPause pauses multiple scans.
func (*Service) CloneScan ¶
func (s *Service) CloneScan(ctx context.Context, tenantID, scanID, newName string) (*scan.Scan, error)
CloneScan clones a scan with a new name.
func (*Service) CreateScan ¶
CreateScan creates a new scan.
func (*Service) DeactivateScansByPipeline ¶
DeactivateScansByPipeline pauses all active scans that use the specified pipeline. This implements the ScanDeactivator interface for cascade deactivation. Scans are paused (not disabled) so they can be easily resumed when the pipeline is reactivated. Returns the count of paused scans.
func (*Service) DeleteScan ¶
DeleteScan deletes a scan.
func (*Service) DisableScan ¶
DisableScan disables a scan.
func (*Service) ExportConfig ¶ added in v0.1.2
ExportConfig exports a scan configuration as JSON bytes. It strips runtime data (status, results, timestamps) and returns only the configuration fields needed to recreate the scan.
func (*Service) GetLatestScanRun ¶
func (s *Service) GetLatestScanRun(ctx context.Context, tenantID, scanID string) (*pipeline.Run, error)
GetLatestScanRun gets the latest run for a specific scan.
func (*Service) GetOverviewStats ¶
GetOverviewStats returns aggregated statistics for scan management. This includes pipeline runs, step runs (scans), and commands (jobs).
func (*Service) GetScanRun ¶
func (s *Service) GetScanRun(ctx context.Context, tenantID, scanID, runID string) (*pipeline.Run, error)
GetScanRun gets a specific run for a scan.
func (*Service) ImportConfig ¶ added in v0.1.2
func (s *Service) ImportConfig(ctx context.Context, tenantID shared.ID, data []byte) (*scan.Scan, error)
ImportConfig creates a new scan from imported JSON configuration. The imported config is validated and a new scan entity is created.
func (*Service) ListScanRuns ¶
func (s *Service) ListScanRuns(ctx context.Context, tenantID, scanID string, page, perPage int) (map[string]any, error)
ListScanRuns lists runs for a specific scan.
func (*Service) ListScans ¶
func (s *Service) ListScans(ctx context.Context, input ListScansInput) (pagination.Result[*scan.Scan], error)
ListScans lists scans with filters.
func (*Service) PreviewScanCompatibility ¶
func (s *Service) PreviewScanCompatibility( ctx context.Context, scannerName string, assetGroupIDs []shared.ID, ) (*AssetCompatibilityPreview, error)
PreviewScanCompatibility checks asset-scanner compatibility for a scan configuration. This is called before scan creation to show warnings about incompatible assets. Returns nil if no warning needed (100% compatible or no asset groups).
func (*Service) QuickScan ¶
func (s *Service) QuickScan(ctx context.Context, input QuickScanInput) (*QuickScanResult, error)
QuickScan performs an immediate scan on provided targets. It creates an ephemeral asset group and scan, then triggers immediately.
func (*Service) RetryScanRun ¶ added in v0.1.5
func (s *Service) RetryScanRun(ctx context.Context, tenantID, scanID shared.ID, retryAttempt int) error
RetryScanRun creates a new pipeline run for a scan as part of automatic retry. Called by the ScanRetryController when a previous run failed and the scan has retry budget remaining.
The new run is tagged with retry_attempt = previous attempt + 1.
func (*Service) TriggerScan ¶
func (s *Service) TriggerScan(ctx context.Context, input TriggerScanExecInput) (*pipeline.Run, error)
TriggerScan triggers a scan execution.
func (*Service) UpdateScan ¶
UpdateScan updates a scan.
type ServiceOption ¶
type ServiceOption func(*Service)
ServiceOption is a functional option for Service.
func WithAuditService ¶
func WithAuditService(auditService AuditService) ServiceOption
WithAuditService sets the audit service for Service.
func WithProfileRepo ¶ added in v0.1.5
func WithProfileRepo(repo scanprofile.Repository) ServiceOption
WithProfileRepo sets the scan profile repository for ScanProfile linking and quality gates.
func WithTargetMappingRepo ¶
func WithTargetMappingRepo(repo tool.TargetMappingRepository) ServiceOption
WithTargetMappingRepo sets the target mapping repository for asset-scanner compatibility.
type SkipReason ¶
type SkipReason struct {
AssetType string `json:"asset_type"`
Count int `json:"count"`
Reason string `json:"reason"`
}
SkipReason explains why assets of a certain type were skipped.
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 grouped by status.
type TemplateSyncResult ¶
TemplateSyncResult represents the result of syncing a template source.
type TemplateSyncer ¶
type TemplateSyncer interface {
SyncSource(ctx context.Context, source *templatesource.TemplateSource) (*TemplateSyncResult, error)
}
TemplateSyncer interface for template sync operations.
type TriggerScanExecInput ¶
type TriggerScanExecInput struct {
TenantID string `json:"tenant_id" validate:"required,uuid"`
ScanID string `json:"scan_id" validate:"required,uuid"`
TriggeredBy string `json:"triggered_by" validate:"omitempty,uuid"`
Context map[string]any `json:"context"`
}
TriggerScanExecInput represents the input for triggering a scan execution.
type UpdateScanInput ¶
type UpdateScanInput struct {
TenantID string `json:"tenant_id" validate:"required,uuid"`
ScanID string `json:"scan_id" validate:"required,uuid"`
Name string `json:"name" validate:"omitempty,min=1,max=200"`
Description string `json:"description" validate:"max=1000"`
PipelineID string `json:"pipeline_id" validate:"omitempty,uuid"`
ScannerName string `json:"scanner_name" validate:"max=100"`
ScannerConfig map[string]any `json:"scanner_config"`
TargetsPerJob *int `json:"targets_per_job"`
ScheduleType string `json:"schedule_type" validate:"omitempty,oneof=manual daily weekly monthly crontab"`
ScheduleCron string `json:"schedule_cron" validate:"max=100"`
ScheduleDay *int `json:"schedule_day"`
ScheduleTime *time.Time `json:"schedule_time"`
Timezone string `json:"timezone" validate:"max=50"`
Tags []string `json:"tags" validate:"max=20,dive,max=50"`
TenantRunner *bool `json:"run_on_tenant_runner"`
AgentPreference string `json:"agent_preference" validate:"omitempty,oneof=auto tenant platform"`
// ProfileID: pointer with sentinel:
// nil = leave unchanged
// pointer to "" = unlink profile
// pointer to id = link to profile
ProfileID *string `json:"profile_id" validate:"omitempty"`
// TimeoutSeconds: nil = leave unchanged, otherwise min=30 max=86400
TimeoutSeconds *int `json:"timeout_seconds" validate:"omitempty,min=30,max=86400"`
// Retry config: nil = leave unchanged
MaxRetries *int `json:"max_retries" validate:"omitempty,min=0,max=10"`
RetryBackoffSeconds *int `json:"retry_backoff_seconds" validate:"omitempty,min=10,max=86400"`
}
UpdateScanInput represents the input for updating a scan.
type ValidationError ¶
ValidationError represents a validation error.
type ValidationResult ¶
type ValidationResult struct {
Valid bool
Errors []ValidationError
}
ValidationResult represents the result of a validation.