db

package
v0.22.0 Latest Latest
Warning

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

Go to latest
Published: Mar 26, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package db provides database connectivity and data models for scanorama. It handles database migrations, host management, scan results storage, and provides the core data access layer for the application.

Package db provides host-related database operations for scanorama. All host repository types and methods have been moved to repository_host.go.

Package db provides typed input structs for all database mutating methods. These replace the previous interface{}/map[string]interface{} parameters, giving callers compile-time safety and making the available fields explicit.

Package db provides network and discovery-related database operations for scanorama.

Package db provides scan profile database operations for scanorama.

Package db provides typed repository for database operations.

Package db provides typed repository for discovery job database operations.

Package db provides typed repository for host-related database operations.

Package db provides typed repository for scan profile database operations.

Package db provides typed repository for scan-related database operations.

Package db provides typed repository for scheduled job database operations.

Package db provides scan-related database operations for scanorama.

Package db provides scheduled job database operations for scanorama.

Index

Constants

View Source
const (
	ScanJobStatusPending   = "pending"
	ScanJobStatusRunning   = "running"
	ScanJobStatusCompleted = "completed"
	ScanJobStatusFailed    = "failed"
)

ScanJobStatus constants.

View Source
const (
	DiscoveryJobStatusPending   = "pending"
	DiscoveryJobStatusRunning   = "running"
	DiscoveryJobStatusCompleted = "completed"
	DiscoveryJobStatusFailed    = "failed"
)

DiscoveryJobStatus constants.

View Source
const (
	ScheduledJobTypeDiscovery = "discovery"
	ScheduledJobTypeScan      = "scan"
)

ScheduledJobType constants.

View Source
const (
	DiscoveryMethodPing = "ping"
	DiscoveryMethodARP  = "arp"
	DiscoveryMethodTCP  = "tcp"
)

DiscoveryMethod constants.

View Source
const (
	OSFamilyWindows = "windows"
	OSFamilyLinux   = "linux"
	OSFamilyMacOS   = "macos"
	OSFamilyFreeBSD = "freebsd"
	OSFamilyUnix    = "unix"
	OSFamilyUnknown = "unknown"
)

OSFamily constants.

View Source
const (
	ScanTimingParanoid   = "paranoid"
	ScanTimingPolite     = "polite"
	ScanTimingNormal     = "normal"
	ScanTimingAggressive = "aggressive"
	ScanTimingInsane     = "insane"
)

ScanTiming constants.

View Source
const (
	HostStatusUp      = "up"
	HostStatusDown    = "down"
	HostStatusUnknown = "unknown"
)

HostStatus constants.

View Source
const (
	PortStateOpen     = "open"
	PortStateClosed   = "closed"
	PortStateFiltered = "filtered"
	PortStateUnknown  = "unknown"
)

PortState constants.

View Source
const (
	ScanTypeConnect = "connect"
	ScanTypeSYN     = "syn"
	ScanTypeVersion = "version"
)

ScanType constants.

View Source
const (
	ProtocolTCP = "tcp"
	ProtocolUDP = "udp"
)

Protocol constants.

View Source
const (
	HostEventDiscovered   = "discovered"
	HostEventStatusChange = "status_change"
	HostEventPortsChanged = "ports_changed"
	HostEventServiceFound = "service_found"
)

HostHistoryEvent constants.

Variables

This section is empty.

Functions

This section is empty.

Types

type ActiveHost

type ActiveHost struct {
	IPAddress         IPAddr    `db:"ip_address" json:"ip_address"`
	Hostname          *string   `db:"hostname" json:"hostname,omitempty"`
	MACAddress        *MACAddr  `db:"mac_address" json:"mac_address,omitempty"`
	Vendor            *string   `db:"vendor" json:"vendor,omitempty"`
	Status            string    `db:"status" json:"status"`
	LastSeen          time.Time `db:"last_seen" json:"last_seen"`
	OpenPorts         int       `db:"open_ports" json:"open_ports"`
	TotalPortsScanned int       `db:"total_ports_scanned" json:"total_ports_scanned"`
}

ActiveHost represents the active_hosts view.

type Config

type Config struct {
	Host            string        `yaml:"host" json:"host"`
	Port            int           `yaml:"port" json:"port"`
	Database        string        `yaml:"database" json:"database"`
	Username        string        `yaml:"username" json:"username"`
	Password        string        `yaml:"password" json:"password"`
	SSLMode         string        `yaml:"ssl_mode" json:"ssl_mode"`
	MaxOpenConns    int           `yaml:"max_open_conns" json:"max_open_conns"`
	MaxIdleConns    int           `yaml:"max_idle_conns" json:"max_idle_conns"`
	ConnMaxLifetime time.Duration `yaml:"conn_max_lifetime" json:"conn_max_lifetime"`
	ConnMaxIdleTime time.Duration `yaml:"conn_max_idle_time" json:"conn_max_idle_time"`
}

Config holds database configuration.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default database configuration. Database name, username, and password must be explicitly configured.

type CreateDiscoveryJobInput added in v0.18.0

type CreateDiscoveryJobInput struct {
	Networks  []string
	Method    string
	NetworkID *uuid.UUID // optional FK to registered network
}

CreateDiscoveryJobInput holds the data required to create a new discovery job. Networks must contain at least one CIDR; only the first is used when creating the underlying DB row. NetworkID, when set, links the job to a registered network in the networks table so discovery history and stats can be surfaced from the network detail view.

type CreateHostInput added in v0.18.0

type CreateHostInput struct {
	IPAddress      string
	Hostname       string
	Vendor         string
	OSFamily       string
	OSName         string
	OSVersion      string
	IgnoreScanning bool
	Status         string
}

CreateHostInput holds the data required to create a new host record.

type CreateProfileInput added in v0.18.0

type CreateProfileInput struct {
	Name        string
	Description string
	ScanType    string
	Ports       string
	Options     map[string]interface{}
	Timing      string
}

CreateProfileInput holds the data required to create a new scan profile.

type CreateScanInput added in v0.18.0

type CreateScanInput struct {
	Name        string
	Description string
	Targets     []string
	ScanType    string
	Ports       string
	ProfileID   *string
	OSDetection bool
}

CreateScanInput holds the data required to create a new scan record.

type CreateScheduleInput added in v0.18.0

type CreateScheduleInput struct {
	Name           string
	JobType        string
	CronExpression string
	JobConfig      map[string]interface{}
	Enabled        bool
}

CreateScheduleInput holds the data required to create a new scheduled job.

type DB

type DB struct {
	*sqlx.DB
}

DB wraps sqlx.DB with additional functionality.

func Connect

func Connect(ctx context.Context, config *Config) (*DB, error)

Connect establishes a connection to PostgreSQL. Returns sanitized errors that don't leak credentials or DSN details.

func ConnectAndMigrate

func ConnectAndMigrate(ctx context.Context, config *Config) (*DB, error)

ConnectAndMigrate is a convenience function to connect to database and run migrations.

func (*DB) BeginTx

func (db *DB) BeginTx(ctx context.Context) (*sqlx.Tx, error)

BeginTx starts a new transaction.

func (*DB) Close

func (db *DB) Close() error

Close closes the database connection.

func (*DB) Ping

func (db *DB) Ping(ctx context.Context) error

Ping tests the database connection.

type DiscoveryFilters

type DiscoveryFilters struct {
	Status string
	Method string
}

DiscoveryFilters represents filters for listing discovery jobs.

type DiscoveryJob

type DiscoveryJob struct {
	ID              uuid.UUID   `db:"id" json:"id"`
	NetworkID       *uuid.UUID  `db:"network_id" json:"network_id,omitempty"`
	Network         NetworkAddr `db:"network" json:"network"`
	Method          string      `db:"method" json:"method"`
	StartedAt       *time.Time  `db:"started_at" json:"started_at,omitempty"`
	CompletedAt     *time.Time  `db:"completed_at" json:"completed_at,omitempty"`
	HostsDiscovered int         `db:"hosts_discovered" json:"hosts_discovered"`
	HostsResponsive int         `db:"hosts_responsive" json:"hosts_responsive"`
	Status          string      `db:"status" json:"status"`
	CreatedAt       time.Time   `db:"created_at" json:"created_at"`
}

DiscoveryJob represents a network discovery job.

type DiscoveryRepository added in v0.19.0

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

DiscoveryRepository implements DiscoveryStore against a *DB connection.

func NewDiscoveryRepository added in v0.19.0

func NewDiscoveryRepository(db *DB) *DiscoveryRepository

NewDiscoveryRepository creates a new DiscoveryRepository.

func (*DiscoveryRepository) CreateDiscoveryJob added in v0.19.0

func (r *DiscoveryRepository) CreateDiscoveryJob(
	ctx context.Context, input CreateDiscoveryJobInput,
) (*DiscoveryJob, error)

CreateDiscoveryJob creates a new discovery job.

func (*DiscoveryRepository) DeleteDiscoveryJob added in v0.19.0

func (r *DiscoveryRepository) DeleteDiscoveryJob(ctx context.Context, id uuid.UUID) error

DeleteDiscoveryJob deletes a discovery job by ID.

func (*DiscoveryRepository) GetDiscoveryJob added in v0.19.0

func (r *DiscoveryRepository) GetDiscoveryJob(ctx context.Context, id uuid.UUID) (*DiscoveryJob, error)

GetDiscoveryJob retrieves a discovery job by ID.

func (*DiscoveryRepository) ListDiscoveryJobs added in v0.19.0

func (r *DiscoveryRepository) ListDiscoveryJobs(
	ctx context.Context,
	filters DiscoveryFilters,
	offset, limit int,
) ([]*DiscoveryJob, int64, error)

ListDiscoveryJobs retrieves discovery jobs with filtering and pagination.

func (*DiscoveryRepository) ListDiscoveryJobsByNetwork added in v0.20.0

func (r *DiscoveryRepository) ListDiscoveryJobsByNetwork(
	ctx context.Context, networkID uuid.UUID, offset, limit int,
) ([]*DiscoveryJob, int64, error)

ListDiscoveryJobsByNetwork retrieves discovery jobs linked to a specific network, ordered most-recent first, with pagination.

func (*DiscoveryRepository) StartDiscoveryJob added in v0.19.0

func (r *DiscoveryRepository) StartDiscoveryJob(ctx context.Context, id uuid.UUID) error

StartDiscoveryJob starts discovery job execution.

func (*DiscoveryRepository) StopDiscoveryJob added in v0.19.0

func (r *DiscoveryRepository) StopDiscoveryJob(ctx context.Context, id uuid.UUID) error

StopDiscoveryJob stops discovery job execution.

func (*DiscoveryRepository) UpdateDiscoveryJob added in v0.19.0

func (r *DiscoveryRepository) UpdateDiscoveryJob(
	ctx context.Context, id uuid.UUID, input UpdateDiscoveryJobInput,
) (*DiscoveryJob, error)

UpdateDiscoveryJob updates an existing discovery job.

type Host

type Host struct {
	ID              uuid.UUID  `db:"id" json:"id"`
	IPAddress       IPAddr     `db:"ip_address" json:"ip_address"`
	Hostname        *string    `db:"hostname" json:"hostname,omitempty"`
	MACAddress      *MACAddr   `db:"mac_address" json:"mac_address,omitempty"`
	Vendor          *string    `db:"vendor" json:"vendor,omitempty"`
	OSFamily        *string    `db:"os_family" json:"os_family,omitempty"`
	OSName          *string    `db:"os_name" json:"os_name,omitempty"`
	OSVersion       *string    `db:"os_version" json:"os_version,omitempty"`
	OSConfidence    *int       `db:"os_confidence" json:"os_confidence,omitempty"`
	OSDetectedAt    *time.Time `db:"os_detected_at" json:"os_detected_at,omitempty"`
	OSMethod        *string    `db:"os_method" json:"os_method,omitempty"`
	OSDetails       JSONB      `db:"os_details" json:"os_details,omitempty"`
	DiscoveryMethod *string    `db:"discovery_method" json:"discovery_method,omitempty"`
	ResponseTimeMS  *int       `db:"response_time_ms" json:"response_time_ms,omitempty"`
	DiscoveryCount  int        `db:"discovery_count" json:"discovery_count"`
	IgnoreScanning  bool       `db:"ignore_scanning" json:"ignore_scanning"`
	FirstSeen       time.Time  `db:"first_seen" json:"first_seen"`
	LastSeen        time.Time  `db:"last_seen" json:"last_seen"`
	Status          string     `db:"status" json:"status"`
	// Computed from port_scans — latest known state per (port, protocol).
	// Ports holds the full PortInfo for every distinct (port, protocol) seen.
	// TotalPorts is the count of distinct (port, protocol) pairs ever seen.
	Ports      []PortInfo `db:"-" json:"-"`
	TotalPorts int        `db:"-" json:"-"`
	ScanCount  int        `db:"-" json:"-"`
}

Host represents a discovered host.

func (*Host) GetOSFingerprint

func (h *Host) GetOSFingerprint() *OSFingerprint

GetOSFingerprint returns the OS fingerprint information.

func (*Host) SetOSFingerprint

func (h *Host) SetOSFingerprint(fp *OSFingerprint) error

SetOSFingerprint updates the host with OS fingerprint information.

type HostFilters

type HostFilters struct {
	Status    string
	OSFamily  string
	Network   string
	Search    string // searches ip_address and hostname
	SortBy    string // column to sort by: ip_address, hostname, os_family, status, last_seen, first_seen
	SortOrder string // asc or desc
}

HostFilters represents filters for listing hosts.

type HostHistory

type HostHistory struct {
	ID           uuid.UUID `db:"id" json:"id"`
	HostID       uuid.UUID `db:"host_id" json:"host_id"`
	JobID        uuid.UUID `db:"job_id" json:"job_id"`
	EventType    string    `db:"event_type" json:"event_type"`
	OldValue     JSONB     `db:"old_value" json:"old_value,omitempty"`
	NewValue     JSONB     `db:"new_value" json:"new_value,omitempty"`
	CreatedAt    time.Time `db:"created_at" json:"created_at"`
	ChangedBy    *string   `db:"changed_by" json:"changed_by,omitempty"`
	ChangeReason *string   `db:"change_reason" json:"change_reason,omitempty"`
	ClientIP     *IPAddr   `db:"client_ip" json:"client_ip,omitempty"`
}

HostHistory represents changes to hosts over time.

type HostRepository

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

HostRepository handles host operations.

func NewHostRepository

func NewHostRepository(db *DB) *HostRepository

NewHostRepository creates a new host repository.

func (*HostRepository) CreateHost added in v0.19.0

func (r *HostRepository) CreateHost(ctx context.Context, input CreateHostInput) (*Host, error)

CreateHost creates a new host record.

func (*HostRepository) CreateOrUpdate

func (r *HostRepository) CreateOrUpdate(ctx context.Context, host *Host) error

CreateOrUpdate creates a new host or updates existing one.

func (*HostRepository) DeleteHost added in v0.19.0

func (r *HostRepository) DeleteHost(ctx context.Context, id uuid.UUID) error

DeleteHost deletes a host by ID.

func (*HostRepository) GetActiveHosts

func (r *HostRepository) GetActiveHosts(ctx context.Context) ([]*ActiveHost, error)

GetActiveHosts retrieves all active hosts.

func (*HostRepository) GetByIP

func (r *HostRepository) GetByIP(ctx context.Context, ip IPAddr) (*Host, error)

GetByIP retrieves a host by IP address.

func (*HostRepository) GetHost added in v0.19.0

func (r *HostRepository) GetHost(ctx context.Context, id uuid.UUID) (*Host, error)

GetHost retrieves a host by ID.

func (*HostRepository) GetHostScans added in v0.19.0

func (r *HostRepository) GetHostScans(
	ctx context.Context, hostID uuid.UUID, offset, limit int,
) ([]*Scan, int64, error)

GetHostScans retrieves scans for a specific host with pagination.

func (*HostRepository) ListHosts added in v0.19.0

func (r *HostRepository) ListHosts(
	ctx context.Context, filters *HostFilters, offset, limit int,
) ([]*Host, int64, error)

ListHosts retrieves hosts with filtering and pagination.

func (*HostRepository) UpdateHost added in v0.19.0

func (r *HostRepository) UpdateHost(ctx context.Context, id uuid.UUID, input UpdateHostInput) (*Host, error)

UpdateHost updates an existing host.

type IPAddr

type IPAddr struct {
	net.IP
}

IPAddr wraps net.IP to implement PostgreSQL INET type.

func (*IPAddr) Scan

func (ip *IPAddr) Scan(value interface{}) error

Scan implements sql.Scanner for PostgreSQL INET type.

func (IPAddr) String

func (ip IPAddr) String() string

String returns the IP address string.

func (IPAddr) Value

func (ip IPAddr) Value() (driver.Value, error)

Value implements driver.Valuer for PostgreSQL INET type.

type JSONB

type JSONB json.RawMessage

JSONB wraps json.RawMessage for PostgreSQL JSONB type.

func (JSONB) MarshalJSON

func (j JSONB) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (*JSONB) Scan

func (j *JSONB) Scan(value interface{}) error

Scan implements sql.Scanner for PostgreSQL JSONB type.

func (JSONB) String

func (j JSONB) String() string

String returns the JSON string.

func (*JSONB) UnmarshalJSON

func (j *JSONB) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (JSONB) Value

func (j JSONB) Value() (driver.Value, error)

Value implements driver.Valuer for PostgreSQL JSONB type.

type MACAddr

type MACAddr struct {
	net.HardwareAddr
}

MACAddr wraps net.HardwareAddr to implement PostgreSQL MACADDR type.

func (*MACAddr) Scan

func (mac *MACAddr) Scan(value interface{}) error

Scan implements sql.Scanner for PostgreSQL MACADDR type.

func (MACAddr) String

func (mac MACAddr) String() string

String returns the MAC address string.

func (MACAddr) Value

func (mac MACAddr) Value() (driver.Value, error)

Value implements driver.Valuer for PostgreSQL MACADDR type.

type Migration

type Migration struct {
	ID        int       `db:"id"`
	Name      string    `db:"name"`
	AppliedAt time.Time `db:"applied_at"`
	Checksum  string    `db:"checksum"`
}

Migration represents a database migration.

type Migrator

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

Migrator handles database migrations.

func NewMigrator

func NewMigrator(db *sqlx.DB) *Migrator

NewMigrator creates a new migrator instance.

func (*Migrator) Reset

func (m *Migrator) Reset(ctx context.Context) error

Reset drops all tables and re-runs migrations (USE WITH CAUTION).

func (*Migrator) Status

func (m *Migrator) Status(ctx context.Context) error

Status shows the current migration status.

func (*Migrator) Up

func (m *Migrator) Up(ctx context.Context) error

Up runs all pending migrations.

type Network

type Network struct {
	ID                  uuid.UUID   `db:"id" json:"id"`
	Name                string      `db:"name" json:"name"`
	CIDR                NetworkAddr `db:"cidr" json:"cidr"`
	Description         *string     `db:"description" json:"description,omitempty"`
	DiscoveryMethod     string      `db:"discovery_method" json:"discovery_method"`
	IsActive            bool        `db:"is_active" json:"is_active"`
	ScanEnabled         bool        `db:"scan_enabled" json:"scan_enabled"`
	ScanIntervalSeconds int         `db:"scan_interval_seconds" json:"scan_interval_seconds"`
	ScanPorts           string      `db:"scan_ports" json:"scan_ports"`
	ScanType            string      `db:"scan_type" json:"scan_type"`
	LastDiscovery       *time.Time  `db:"last_discovery" json:"last_discovery,omitempty"`
	LastScan            *time.Time  `db:"last_scan" json:"last_scan,omitempty"`
	HostCount           int         `db:"host_count" json:"host_count"`
	ActiveHostCount     int         `db:"active_host_count" json:"active_host_count"`
	CreatedAt           time.Time   `db:"created_at" json:"created_at"`
	UpdatedAt           time.Time   `db:"updated_at" json:"updated_at"`
	CreatedBy           *string     `db:"created_by" json:"created_by,omitempty"`
	ModifiedBy          *string     `db:"modified_by" json:"modified_by,omitempty"`
}

Network represents a network configured for discovery and scanning.

type NetworkAddr

type NetworkAddr struct {
	net.IPNet
}

NetworkAddr wraps net.IPNet to implement PostgreSQL CIDR type.

func (NetworkAddr) MarshalJSON added in v0.17.1

func (n NetworkAddr) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for NetworkAddr, encoding as a CIDR string.

func (*NetworkAddr) Scan

func (n *NetworkAddr) Scan(value interface{}) error

Scan implements sql.Scanner for PostgreSQL CIDR type.

func (NetworkAddr) String

func (n NetworkAddr) String() string

String returns the CIDR notation string.

func (*NetworkAddr) UnmarshalJSON added in v0.17.1

func (n *NetworkAddr) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler for NetworkAddr, decoding from a CIDR string.

func (NetworkAddr) Value

func (n NetworkAddr) Value() (driver.Value, error)

Value implements driver.Valuer for PostgreSQL CIDR type.

type NetworkExclusion

type NetworkExclusion struct {
	ID           uuid.UUID  `db:"id" json:"id"`
	NetworkID    *uuid.UUID `db:"network_id" json:"network_id,omitempty"` // NULL for global exclusions
	ExcludedCIDR string     `db:"excluded_cidr" json:"excluded_cidr"`
	Reason       *string    `db:"reason" json:"reason,omitempty"`
	Enabled      bool       `db:"enabled" json:"enabled"`
	CreatedAt    time.Time  `db:"created_at" json:"created_at"`
	UpdatedAt    time.Time  `db:"updated_at" json:"updated_at"`
	CreatedBy    *string    `db:"created_by" json:"created_by,omitempty"`
}

NetworkExclusion represents an IP exclusion rule for networks.

type NetworkSummary

type NetworkSummary struct {
	TargetName  string      `db:"target_name" json:"target_name"`
	Network     NetworkAddr `db:"network" json:"network"`
	ActiveHosts int         `db:"active_hosts" json:"active_hosts"`
	TotalHosts  int         `db:"total_hosts" json:"total_hosts"`
	OpenPorts   int         `db:"open_ports" json:"open_ports"`
	LastScan    *time.Time  `db:"last_scan" json:"last_scan,omitempty"`
}

NetworkSummary represents the network_summary view.

type NetworkSummaryRepository

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

NetworkSummaryRepository handles network summary operations.

func NewNetworkSummaryRepository

func NewNetworkSummaryRepository(db *DB) *NetworkSummaryRepository

NewNetworkSummaryRepository creates a new network summary repository.

func (*NetworkSummaryRepository) GetAll

GetAll retrieves all network summaries.

type OSFingerprint

type OSFingerprint struct {
	Family     string                 `json:"family"`     // "windows", "linux", "macos", "freebsd", etc.
	Name       string                 `json:"name"`       // "Windows Server 2019", "Ubuntu 22.04", etc.
	Version    string                 `json:"version"`    // "10.0.17763", "22.04.1", etc.
	Confidence int                    `json:"confidence"` // 0-100 confidence score
	Method     string                 `json:"method"`     // "tcp_fingerprint", "banner", "ttl_analysis"
	Details    map[string]interface{} `json:"details"`    // Additional OS-specific data
}

OSFingerprint represents OS detection information.

type PortInfo added in v0.17.0

type PortInfo struct {
	Port     int       `json:"port"`
	Protocol string    `json:"protocol"`
	State    string    `json:"state"`
	Service  string    `json:"service,omitempty"`
	LastSeen time.Time `json:"last_seen"`
}

PortInfo holds the latest known state for a single (port, protocol) pair on a host. It is computed from port_scans using DISTINCT ON so it always reflects the most recent scan observation, not a historical snapshot.

type PortScan

type PortScan struct {
	ID             uuid.UUID `db:"id" json:"id"`
	JobID          uuid.UUID `db:"job_id" json:"job_id"`
	HostID         uuid.UUID `db:"host_id" json:"host_id"`
	Port           int       `db:"port" json:"port"`
	Protocol       string    `db:"protocol" json:"protocol"`
	State          string    `db:"state" json:"state"`
	ServiceName    *string   `db:"service_name" json:"service_name,omitempty"`
	ServiceVersion *string   `db:"service_version" json:"service_version,omitempty"`
	ServiceProduct *string   `db:"service_product" json:"service_product,omitempty"`
	Banner         *string   `db:"banner" json:"banner,omitempty"`
	ScannedAt      time.Time `db:"scanned_at" json:"scanned_at"`
}

PortScan represents a port scan result.

type PortScanRepository

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

PortScanRepository handles port scan operations.

func NewPortScanRepository

func NewPortScanRepository(db *DB) *PortScanRepository

NewPortScanRepository creates a new port scan repository.

func (*PortScanRepository) CreateBatch

func (r *PortScanRepository) CreateBatch(ctx context.Context, scans []*PortScan) error

CreateBatch creates multiple port scan results in a transaction.

func (*PortScanRepository) GetByHost

func (r *PortScanRepository) GetByHost(ctx context.Context, hostID uuid.UUID) ([]*PortScan, error)

GetByHost retrieves all port scans for a host.

type ProfileFilters

type ProfileFilters struct {
	ScanType string
}

ProfileFilters represents filters for listing profiles.

type ProfileRepository added in v0.19.0

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

ProfileRepository implements ProfileStore against a *DB connection.

func NewProfileRepository added in v0.19.0

func NewProfileRepository(db *DB) *ProfileRepository

NewProfileRepository creates a new ProfileRepository.

func (*ProfileRepository) CreateProfile added in v0.19.0

func (r *ProfileRepository) CreateProfile(ctx context.Context, input CreateProfileInput) (*ScanProfile, error)

CreateProfile creates a new profile.

func (*ProfileRepository) DeleteProfile added in v0.19.0

func (r *ProfileRepository) DeleteProfile(ctx context.Context, id string) error

DeleteProfile deletes a profile by ID.

func (*ProfileRepository) GetProfile added in v0.19.0

func (r *ProfileRepository) GetProfile(ctx context.Context, id string) (*ScanProfile, error)

GetProfile retrieves a profile by ID.

func (*ProfileRepository) ListProfiles added in v0.19.0

func (r *ProfileRepository) ListProfiles(ctx context.Context, filters ProfileFilters,
	offset, limit int) ([]*ScanProfile, int64, error)

ListProfiles retrieves profiles with filtering and pagination.

func (*ProfileRepository) UpdateProfile added in v0.19.0

func (r *ProfileRepository) UpdateProfile(
	ctx context.Context, id string, input UpdateProfileInput,
) (*ScanProfile, error)

UpdateProfile updates an existing profile.

type RecoveryResult added in v0.20.0

type RecoveryResult struct {
	ScanJobsRecovered      int
	DiscoveryJobsRecovered int
}

RecoveryResult reports how many jobs were transitioned out of the 'running' state during startup recovery.

func RecoverStaleJobs added in v0.20.0

func RecoverStaleJobs(ctx context.Context, database *DB) (RecoveryResult, error)

RecoverStaleJobs transitions every job that is stuck in the 'running' state back to 'failed', stamping completed_at = NOW(). It must be called once after the database connection is established and before the HTTP listener opens so that:

  • Clients never see a job that is permanently 'running' but has no live goroutine behind it.
  • The job can be retried or re-queued by the operator / scheduler.

The function is intentionally idempotent: if there are no stale jobs both result counts are zero and no error is returned.

Errors from either UPDATE are returned immediately; the second UPDATE is skipped if the first fails, so the caller can decide whether to abort startup or continue with a warning.

func (RecoveryResult) Total added in v0.20.0

func (r RecoveryResult) Total() int

Total returns the combined number of recovered jobs across all tables.

type Repository

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

Repository provides database operations.

func NewRepository

func NewRepository(db *DB) *Repository

NewRepository creates a new repository instance.

type Scan

type Scan struct {
	ID           uuid.UUID              `json:"id" db:"id"`
	Name         string                 `json:"name" db:"name"`
	Description  string                 `json:"description" db:"description"`
	Targets      []string               `json:"targets" db:"targets"`
	ScanType     string                 `json:"scan_type" db:"scan_type"`
	Ports        string                 `json:"ports" db:"ports"`
	ProfileID    *string                `json:"profile_id" db:"profile_id"`
	Options      map[string]interface{} `json:"options" db:"options"`
	ScheduleID   *int64                 `json:"schedule_id" db:"schedule_id"`
	Tags         []string               `json:"tags" db:"tags"`
	Status       string                 `json:"status" db:"status"`
	CreatedAt    time.Time              `json:"created_at" db:"created_at"`
	UpdatedAt    time.Time              `json:"updated_at" db:"updated_at"`
	StartedAt    *time.Time             `json:"started_at" db:"started_at"`
	CompletedAt  *time.Time             `json:"completed_at" db:"completed_at"`
	ErrorMessage *string                `json:"error_message,omitempty" db:"error_message"`
	DurationStr  *string                `json:"duration,omitempty" db:"-"`
	PortsScanned *string                `json:"ports_scanned,omitempty" db:"-"`
}

Scan represents a scan configuration and execution state.

type ScanFilters

type ScanFilters struct {
	Status    string
	ScanType  string
	ProfileID *string
	Tags      []string
}

ScanFilters represents filters for listing scans.

type ScanJob

type ScanJob struct {
	ID               uuid.UUID  `db:"id" json:"id"`
	NetworkID        uuid.UUID  `db:"network_id" json:"network_id"`
	ProfileID        *string    `db:"profile_id" json:"profile_id,omitempty"`
	Status           string     `db:"status" json:"status"`
	StartedAt        *time.Time `db:"started_at" json:"started_at,omitempty"`
	CompletedAt      *time.Time `db:"completed_at" json:"completed_at,omitempty"`
	ErrorMessage     *string    `db:"error_message" json:"error_message,omitempty"`
	ScanStats        JSONB      `db:"scan_stats" json:"scan_stats,omitempty"`
	CreatedAt        time.Time  `db:"created_at" json:"created_at"`
	ProgressPercent  *int       `db:"progress_percent" json:"progress_percent,omitempty"`
	TimeoutAt        *time.Time `db:"timeout_at" json:"timeout_at,omitempty"`
	ExecutionDetails JSONB      `db:"execution_details" json:"execution_details,omitempty"`
	WorkerID         *string    `db:"worker_id" json:"worker_id,omitempty"`
	CreatedBy        *string    `db:"created_by" json:"created_by,omitempty"`
}

ScanJob represents a scan job execution.

type ScanJobRepository

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

ScanJobRepository handles scan job operations.

func NewScanJobRepository

func NewScanJobRepository(db *DB) *ScanJobRepository

NewScanJobRepository creates a new scan job repository.

func (*ScanJobRepository) Create

func (r *ScanJobRepository) Create(ctx context.Context, job *ScanJob) error

Create creates a new scan job.

func (*ScanJobRepository) GetByID

func (r *ScanJobRepository) GetByID(ctx context.Context, id uuid.UUID) (*ScanJob, error)

GetByID retrieves a scan job by ID.

func (*ScanJobRepository) UpdateStatus

func (r *ScanJobRepository) UpdateStatus(ctx context.Context, id uuid.UUID, status string, errorMsg *string) error

UpdateStatus updates a scan job status.

type ScanProfile

type ScanProfile struct {
	ID          string         `db:"id" json:"id"`
	Name        string         `db:"name" json:"name"`
	Description string         `db:"description" json:"description"`
	OSFamily    pq.StringArray `db:"os_family" json:"os_family"`
	OSPattern   pq.StringArray `db:"os_pattern" json:"os_pattern"`
	Ports       string         `db:"ports" json:"ports"`
	ScanType    string         `db:"scan_type" json:"scan_type"`
	Timing      string         `db:"timing" json:"timing"`
	Scripts     pq.StringArray `db:"scripts" json:"scripts"`
	Options     JSONB          `db:"options" json:"options"`
	Priority    int            `db:"priority" json:"priority"`
	BuiltIn     bool           `db:"built_in" json:"built_in"`
	CreatedAt   time.Time      `db:"created_at" json:"created_at"`
	UpdatedAt   time.Time      `db:"updated_at" json:"updated_at"`
}

ScanProfile represents a scanning profile configuration.

type ScanRepository added in v0.19.0

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

ScanRepository implements ScanStore against a *DB connection.

func NewScanRepository added in v0.19.0

func NewScanRepository(db *DB) *ScanRepository

NewScanRepository creates a new ScanRepository.

func (*ScanRepository) CompleteScan added in v0.19.0

func (r *ScanRepository) CompleteScan(ctx context.Context, id uuid.UUID) error

CompleteScan marks a scan as successfully completed.

func (*ScanRepository) CreateScan added in v0.19.0

func (r *ScanRepository) CreateScan(ctx context.Context, input CreateScanInput) (*Scan, error)

CreateScan creates a new scan record.

func (*ScanRepository) DB added in v0.19.0

func (r *ScanRepository) DB() *DB

DB returns the underlying *DB connection. This is used by the scan handler to obtain a concrete *DB for the scan runner.

func (*ScanRepository) DeleteScan added in v0.19.0

func (r *ScanRepository) DeleteScan(ctx context.Context, id uuid.UUID) error

DeleteScan deletes a scan by ID.

func (*ScanRepository) GetProfile added in v0.19.0

func (r *ScanRepository) GetProfile(ctx context.Context, id string) (*ScanProfile, error)

GetProfile satisfies the ScanStore interface by delegating to ProfileRepository.

func (*ScanRepository) GetScan added in v0.19.0

func (r *ScanRepository) GetScan(ctx context.Context, id uuid.UUID) (*Scan, error)

GetScan retrieves a scan by ID.

func (*ScanRepository) GetScanResults added in v0.19.0

func (r *ScanRepository) GetScanResults(ctx context.Context, scanID uuid.UUID, offset, limit int) (
	[]*ScanResult, int64, error)

GetScanResults retrieves scan results with pagination.

func (*ScanRepository) GetScanSummary added in v0.19.0

func (r *ScanRepository) GetScanSummary(ctx context.Context, scanID uuid.UUID) (*ScanSummary, error)

GetScanSummary retrieves aggregated scan statistics.

func (*ScanRepository) ListScans added in v0.19.0

func (r *ScanRepository) ListScans(
	ctx context.Context, filters ScanFilters, offset, limit int,
) ([]*Scan, int64, error)

ListScans retrieves scans with filtering and pagination.

func (*ScanRepository) StartScan added in v0.19.0

func (r *ScanRepository) StartScan(ctx context.Context, id uuid.UUID) error

StartScan starts scan execution.

func (*ScanRepository) StopScan added in v0.19.0

func (r *ScanRepository) StopScan(ctx context.Context, id uuid.UUID, errMsg ...string) error

StopScan stops scan execution and marks it as failed.

func (*ScanRepository) UpdateScan added in v0.19.0

func (r *ScanRepository) UpdateScan(ctx context.Context, id uuid.UUID, input UpdateScanInput) (*Scan, error)

UpdateScan updates an existing scan.

type ScanResult

type ScanResult struct {
	ID           uuid.UUID `json:"id" db:"id"`
	ScanID       uuid.UUID `json:"scan_id" db:"scan_id"`
	HostID       uuid.UUID `json:"host_id" db:"host_id"`
	HostIP       string    `json:"host_ip" db:"host_ip"`
	Port         int       `json:"port" db:"port"`
	Protocol     string    `json:"protocol" db:"protocol"`
	State        string    `json:"state" db:"state"`
	Service      string    `json:"service" db:"service"`
	ScannedAt    time.Time `json:"scanned_at" db:"scanned_at"`
	OSName       string    `json:"os_name,omitempty" db:"os_name"`
	OSFamily     string    `json:"os_family,omitempty" db:"os_family"`
	OSVersion    string    `json:"os_version,omitempty" db:"os_version"`
	OSConfidence *int      `json:"os_confidence,omitempty" db:"os_confidence"`
}

ScanResult represents a scan result entry.

type ScanSummary

type ScanSummary struct {
	ScanID      uuid.UUID `json:"scan_id"`
	TotalHosts  int       `json:"total_hosts"`
	TotalPorts  int       `json:"total_ports"`
	OpenPorts   int       `json:"open_ports"`
	ClosedPorts int       `json:"closed_ports"`
	Duration    int64     `json:"duration_ms"`
}

ScanSummary represents aggregated scan statistics.

type Schedule

type Schedule struct {
	ID             uuid.UUID              `json:"id" db:"id"`
	Name           string                 `json:"name" db:"name"`
	Description    string                 `json:"description" db:"description"`
	CronExpression string                 `json:"cron_expression" db:"cron_expression"`
	JobType        string                 `json:"job_type" db:"job_type"`
	JobConfig      map[string]interface{} `json:"job_config" db:"job_config"`
	Enabled        bool                   `json:"enabled" db:"enabled"`
	CreatedAt      time.Time              `json:"created_at" db:"created_at"`
	UpdatedAt      time.Time              `json:"updated_at" db:"updated_at"`
	LastRun        *time.Time             `json:"last_run" db:"last_run"`
	NextRun        *time.Time             `json:"next_run" db:"next_run"`
}

Schedule represents a scheduled task.

type ScheduleFilters

type ScheduleFilters struct {
	Enabled bool
	JobType string
}

ScheduleFilters represents filters for listing schedules.

type ScheduleRepository added in v0.19.0

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

ScheduleRepository implements ScheduleStore against a *DB connection.

func NewScheduleRepository added in v0.19.0

func NewScheduleRepository(db *DB) *ScheduleRepository

NewScheduleRepository creates a new ScheduleRepository.

func (*ScheduleRepository) CreateSchedule added in v0.19.0

func (r *ScheduleRepository) CreateSchedule(ctx context.Context, input CreateScheduleInput) (*Schedule, error)

CreateSchedule creates a new schedule.

func (*ScheduleRepository) DeleteSchedule added in v0.19.0

func (r *ScheduleRepository) DeleteSchedule(ctx context.Context, id uuid.UUID) error

DeleteSchedule deletes a schedule by ID.

func (*ScheduleRepository) DisableSchedule added in v0.19.0

func (r *ScheduleRepository) DisableSchedule(ctx context.Context, id uuid.UUID) error

DisableSchedule disables a schedule.

func (*ScheduleRepository) EnableSchedule added in v0.19.0

func (r *ScheduleRepository) EnableSchedule(ctx context.Context, id uuid.UUID) error

EnableSchedule enables a schedule.

func (*ScheduleRepository) GetSchedule added in v0.19.0

func (r *ScheduleRepository) GetSchedule(ctx context.Context, id uuid.UUID) (*Schedule, error)

GetSchedule retrieves a schedule by ID.

func (*ScheduleRepository) ListSchedules added in v0.19.0

func (r *ScheduleRepository) ListSchedules(
	ctx context.Context,
	filters ScheduleFilters,
	offset, limit int,
) ([]*Schedule, int64, error)

ListSchedules retrieves schedules with filtering and pagination.

func (*ScheduleRepository) UpdateSchedule added in v0.19.0

func (r *ScheduleRepository) UpdateSchedule(
	ctx context.Context, id uuid.UUID, input UpdateScheduleInput,
) (*Schedule, error)

UpdateSchedule updates an existing schedule.

type ScheduledJob

type ScheduledJob struct {
	ID                  uuid.UUID  `db:"id" json:"id"`
	Name                string     `db:"name" json:"name"`
	Type                string     `db:"type" json:"type"` // 'discovery' or 'scan'
	CronExpression      string     `db:"cron_expression" json:"cron_expression"`
	Config              JSONB      `db:"config" json:"config"`
	Enabled             bool       `db:"enabled" json:"enabled"`
	LastRun             *time.Time `db:"last_run" json:"last_run,omitempty"`
	NextRun             *time.Time `db:"next_run" json:"next_run,omitempty"`
	CreatedAt           time.Time  `db:"created_at" json:"created_at"`
	LastRunDurationMs   *int       `db:"last_run_duration_ms" json:"last_run_duration_ms,omitempty"`
	LastRunStatus       *string    `db:"last_run_status" json:"last_run_status,omitempty"`
	ConsecutiveFailures *int       `db:"consecutive_failures" json:"consecutive_failures,omitempty"`
	MaxFailures         *int       `db:"max_failures" json:"max_failures,omitempty"`
}

ScheduledJob represents a scheduled scanning or discovery job.

type Service

type Service struct {
	ID          uuid.UUID `db:"id" json:"id"`
	PortScanID  uuid.UUID `db:"port_scan_id" json:"port_scan_id"`
	ServiceType *string   `db:"service_type" json:"service_type,omitempty"`
	Version     *string   `db:"version" json:"version,omitempty"`
	CPE         *string   `db:"cpe" json:"cpe,omitempty"`
	Confidence  *int      `db:"confidence" json:"confidence,omitempty"`
	Details     JSONB     `db:"details" json:"details,omitempty"`
	DetectedAt  time.Time `db:"detected_at" json:"detected_at"`
}

Service represents detailed service detection.

type UpdateDiscoveryJobInput added in v0.18.0

type UpdateDiscoveryJobInput struct {
	Method          *string
	Status          *string
	HostsDiscovered *int
	HostsResponsive *int
	StartedAt       *time.Time
	CompletedAt     *time.Time
}

UpdateDiscoveryJobInput holds the optional fields that may be changed on an existing discovery job. A nil pointer means "leave this field unchanged".

type UpdateHostInput added in v0.18.0

type UpdateHostInput struct {
	Hostname       *string
	Vendor         *string
	OSFamily       *string
	OSName         *string
	OSVersion      *string
	IgnoreScanning *bool
	Status         *string
}

UpdateHostInput holds the optional fields that may be changed on an existing host. A nil pointer means "leave this field unchanged".

type UpdateProfileInput added in v0.18.0

type UpdateProfileInput struct {
	Name        *string
	Description *string
	ScanType    *string
	Ports       *string
	Timing      *string
	Scripts     []string
	Options     map[string]interface{}
	Priority    *int
}

UpdateProfileInput holds the optional fields that may be changed on an existing profile. A nil pointer / nil map means "leave this field unchanged".

type UpdateScanInput added in v0.18.0

type UpdateScanInput struct {
	Name        *string
	Description *string
	ScanType    *string
	Ports       *string
	ProfileID   *string
	Status      *string
}

UpdateScanInput holds the optional fields that may be changed on an existing scan. A nil pointer means "leave this field unchanged".

type UpdateScheduleInput added in v0.18.0

type UpdateScheduleInput struct {
	Name           *string
	JobType        *string
	CronExpression *string
	JobConfig      map[string]interface{}
	Enabled        *bool
	NextRun        *time.Time
}

UpdateScheduleInput holds the optional fields that may be changed on an existing schedule. A nil pointer / nil map means "leave this field unchanged".

Jump to

Keyboard shortcuts

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