services

package
v0.26.0 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2026 License: MIT Imports: 20 Imported by: 0

Documentation

Overview

Package services provides business logic for host group management.

Package services provides business logic services for Scanorama. This file implements host management functionality including CRUD operations and host scan history retrieval.

Package services contains the scanorama application-layer orchestration. This file holds the host-identity resolver: given a snapshot of every name-like signal observed for a host, it picks one canonical display name and enumerates all the alternatives for the Identity tab.

Package services provides business logic services for Scanorama. This file implements network management functionality including config-based network seeding, exclusion management, and integration with the discovery engine.

Package services provides business logic services for Scanorama. This file implements scan profile management functionality including CRUD operations and profile cloning.

Package services provides business logic for Scanorama operations. This file implements scan management, including input validation, profile verification, and enriched state-transition methods.

Package services provides business logic for Scanorama operations. This file implements schedule management, including cron-expression validation and a NextRun helper.

Package services provides business logic for Scanorama operations. This file implements the pure knowledge-score calculation used to summarize how much is known about a discovered host.

Package services - Smart Scan orchestration service. Evaluates per-host knowledge gaps and queues the appropriate next scan stage.

Index

Constants

View Source
const (
	AutoProgressDefaultThreshold    = 80 // re-queue when knowledge score < 80
	AutoProgressDefaultMaxPerWindow = 3  // max auto-queues per host per window
	AutoProgressDefaultWindowHours  = 24 // rolling window duration in hours
)

Auto-progression defaults. Exported so the API server can pass them explicitly to WithAutoProgression rather than using magic numbers.

View Source
const MaxScanNameLength = 100

MaxScanNameLength is the maximum allowed length for a scan name.

View Source
const MaxTargetCount = 100

MaxTargetCount is the maximum number of targets allowed per scan.

View Source
const MaxTargetLength = 200

MaxTargetLength is the maximum allowed length for a single target string.

Variables

View Source
var DefaultIdentityRankOrder = []string{"mdns", "snmp", "ptr", "cert"}

DefaultIdentityRankOrder matches the seeded identity.rank_order setting (migration 027). Callers that can't reach the settings row should use this slice so behavior stays consistent with a fresh install.

Don't take &DefaultIdentityRankOrder — it's meant to be copied or ranged over, not mutated.

Functions

func CalculateScore added in v0.25.0

func CalculateScore(in ScoreInput) int

CalculateScore returns a 0-100 score from the provided boolean inputs. Each of the five factors contributes 20 points.

func IsValidScanTarget added in v0.25.0

func IsValidScanTarget(s string) bool

IsValidScanTarget reports whether s is an acceptable scan target: a plain IP address, a CIDR range, or an RFC 1123 hostname.

func ParsePortSpec added in v0.19.1

func ParsePortSpec(ports string) error

ParsePortSpec validates a port specification string. The spec is comma-separated with optional T:/U: protocol prefixes and optional hyphenated ranges (e.g. "T:80,U:53,1024-9999"). Every individual port value must be in the range 1-65535.

func ValidateCronExpression added in v0.19.1

func ValidateCronExpression(cronExpr string) error

ValidateCronExpression checks that cronExpr is a non-empty, syntactically valid standard 5-field cron expression.

Types

type BatchDetailEntry added in v0.25.0

type BatchDetailEntry struct {
	HostID string `json:"host_id"`
	Stage  string `json:"stage"`
	ScanID string `json:"scan_id,omitempty"`
	Reason string `json:"reason,omitempty"`
}

BatchDetailEntry records what happened for a single host in a batch.

type BatchFilter added in v0.25.0

type BatchFilter struct {
	Stage             string      // empty = all eligible stages; otherwise one of ScanStage.Stage values
	HostIDs           []uuid.UUID // non-empty = only these hosts; empty = all hosts
	NetworkCIDR       string      // non-empty = only hosts whose IP falls within this CIDR
	OSFamily          string      // non-empty = only hosts whose os_family matches (case-insensitive)
	Limit             int         // max hosts to queue; 0 = use defaultBatchLimit
	Source            string      // db.ScanSourceAPI / ScanSourceScheduled; defaults to ScanSourceAPI
	ScoreThreshold    int         // 0 = no filter; >0 = only hosts with knowledge_score < threshold
	MaxStalenessHours int         // 0 = no filter; >0 = only hosts not seen within N hours
}

BatchFilter constrains which hosts to include in a batch smart-scan trigger.

type BatchResult added in v0.25.0

type BatchResult struct {
	Queued  int                `json:"queued"`
	Skipped int                `json:"skipped"`
	Details []BatchDetailEntry `json:"details"`
}

BatchResult summarizes the outcome of a QueueBatch call.

type CertSubject added in v0.26.0

type CertSubject struct {
	Name             string
	Kind             string // "cn" or "san"
	ObservedAt       time.Time
	ForwardMatchesIP bool
}

CertSubject is a TLS cert CN or SAN entry with pre-computed reverse-match information. ForwardMatchesIP is true when a forward A/AAAA lookup of Name resolves back to the host's IP — the only case where the cert identity can be trusted as the host's identity.

type DeviceMatcher added in v0.26.0

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

DeviceMatcher scores existing devices against a host's signals and either auto-attaches the host or creates a suggestion, based on confidence thresholds.

It is designed to run post-discovery — not during live scanning — after the host record has been enriched with mDNS, SNMP, and DNS names.

func NewDeviceMatcher added in v0.26.0

func NewDeviceMatcher(repo matcherRepository, logger *slog.Logger) *DeviceMatcher

NewDeviceMatcher creates a DeviceMatcher.

func (*DeviceMatcher) MatchHost added in v0.26.0

func (m *DeviceMatcher) MatchHost(ctx context.Context, host *db.Host) error

MatchHost scores all known devices against the host and auto-attaches or suggests.

Thresholds:

  • Score ≥ 3 with no tie → auto-attach and learn new signals
  • Score 1–2, or tie at ≥ 3 → UpsertSuggestion for each candidate
  • Score 0 → no action

func (*DeviceMatcher) MatchHosts added in v0.26.0

func (m *DeviceMatcher) MatchHosts(ctx context.Context, hosts []*db.Host)

MatchHosts runs MatchHost for each host in the slice. Individual host errors are logged but do not abort the remaining matches.

type DeviceService added in v0.26.0

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

DeviceService handles business logic for device management.

func NewDeviceService added in v0.26.0

func NewDeviceService(repo deviceRepository, logger *slog.Logger) *DeviceService

NewDeviceService creates a new DeviceService.

func (*DeviceService) AcceptSuggestion added in v0.26.0

func (s *DeviceService) AcceptSuggestion(ctx context.Context, suggestionID uuid.UUID) error

AcceptSuggestion attaches the host to the device and removes the suggestion row.

func (*DeviceService) AttachHost added in v0.26.0

func (s *DeviceService) AttachHost(ctx context.Context, deviceID, hostID uuid.UUID) error

AttachHost manually attaches a host to a device.

func (*DeviceService) CreateDevice added in v0.26.0

func (s *DeviceService) CreateDevice(ctx context.Context, input db.CreateDeviceInput) (*db.Device, error)

CreateDevice validates the input and creates a new device record.

func (*DeviceService) DeleteDevice added in v0.26.0

func (s *DeviceService) DeleteDevice(ctx context.Context, id uuid.UUID) error

DeleteDevice removes a device; attached hosts become unidentified (device_id → NULL).

func (*DeviceService) DetachHost added in v0.26.0

func (s *DeviceService) DetachHost(ctx context.Context, deviceID, hostID uuid.UUID) error

DetachHost removes a host from a device.

func (*DeviceService) DismissSuggestion added in v0.26.0

func (s *DeviceService) DismissSuggestion(ctx context.Context, suggestionID uuid.UUID) error

DismissSuggestion marks a suggestion as dismissed without attaching.

func (*DeviceService) GetDevice added in v0.26.0

func (s *DeviceService) GetDevice(ctx context.Context, id uuid.UUID) (*db.Device, error)

GetDevice returns a device by its UUID.

func (*DeviceService) GetDeviceDetail added in v0.26.0

func (s *DeviceService) GetDeviceDetail(ctx context.Context, id uuid.UUID) (*db.DeviceDetail, error)

GetDeviceDetail returns the full device view including MACs, names, and hosts.

func (*DeviceService) ListDevices added in v0.26.0

func (s *DeviceService) ListDevices(ctx context.Context) ([]db.DeviceSummary, error)

ListDevices returns all devices with MAC and host counts.

func (*DeviceService) UpdateDevice added in v0.26.0

func (s *DeviceService) UpdateDevice(
	ctx context.Context, id uuid.UUID, input db.UpdateDeviceInput,
) (*db.Device, error)

UpdateDevice applies name/notes changes to an existing device.

type GroupService added in v0.24.0

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

GroupService handles business logic for host group management.

func NewGroupService added in v0.24.0

func NewGroupService(repo groupRepository, logger *slog.Logger) *GroupService

NewGroupService creates a new GroupService.

func (*GroupService) AddHostsToGroup added in v0.24.0

func (s *GroupService) AddHostsToGroup(ctx context.Context, groupID uuid.UUID, hostIDs []uuid.UUID) error

AddHostsToGroup adds one or more hosts to the specified group.

func (*GroupService) CreateGroup added in v0.24.0

func (s *GroupService) CreateGroup(ctx context.Context, input db.CreateGroupInput) (*db.HostGroup, error)

CreateGroup validates the input and creates a new host group.

func (*GroupService) DeleteGroup added in v0.24.0

func (s *GroupService) DeleteGroup(ctx context.Context, id uuid.UUID) error

DeleteGroup removes a host group by its UUID.

func (*GroupService) GetGroup added in v0.24.0

func (s *GroupService) GetGroup(ctx context.Context, id uuid.UUID) (*db.HostGroup, error)

GetGroup retrieves a single host group by its UUID.

func (*GroupService) GetGroupMembers added in v0.24.0

func (s *GroupService) GetGroupMembers(
	ctx context.Context, groupID uuid.UUID, offset, limit int,
) ([]*db.Host, int64, error)

GetGroupMembers returns a paginated list of hosts belonging to the given group.

func (*GroupService) ListGroups added in v0.24.0

func (s *GroupService) ListGroups(ctx context.Context) ([]*db.HostGroup, error)

ListGroups returns all host groups.

func (*GroupService) RemoveHostsFromGroup added in v0.24.0

func (s *GroupService) RemoveHostsFromGroup(ctx context.Context, groupID uuid.UUID, hostIDs []uuid.UUID) error

RemoveHostsFromGroup removes one or more hosts from the specified group.

func (*GroupService) UpdateGroup added in v0.24.0

func (s *GroupService) UpdateGroup(
	ctx context.Context, id uuid.UUID, input db.UpdateGroupInput,
) (*db.HostGroup, error)

UpdateGroup applies the provided changes to an existing host group.

type HostService added in v0.19.1

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

HostService handles business logic for host management.

func NewHostService added in v0.19.1

func NewHostService(repo hostRepository, logger *slog.Logger) *HostService

NewHostService creates a new HostService with the provided repository and logger.

func (*HostService) AddHostTags added in v0.24.0

func (s *HostService) AddHostTags(ctx context.Context, id uuid.UUID, tags []string) error

AddHostTags appends tags to the host's tag list, deduplicating the result.

func (*HostService) BulkDeleteHosts added in v0.23.0

func (s *HostService) BulkDeleteHosts(ctx context.Context, ids []uuid.UUID) (int64, error)

BulkDeleteHosts deletes multiple hosts and returns the count of deleted rows.

func (*HostService) BulkUpdateTags added in v0.24.0

func (s *HostService) BulkUpdateTags(ctx context.Context, ids []uuid.UUID, tags []string, action string) error

BulkUpdateTags applies an add/remove/set tag operation to multiple hosts at once.

func (*HostService) CreateHost added in v0.19.1

func (s *HostService) CreateHost(ctx context.Context, input db.CreateHostInput) (*db.Host, error)

CreateHost validates the input and creates a new host record. It returns a validation error if the IP address is empty.

func (*HostService) DeleteHost added in v0.19.1

func (s *HostService) DeleteHost(ctx context.Context, id uuid.UUID) error

DeleteHost removes a host record by its UUID.

func (*HostService) GetHost added in v0.19.1

func (s *HostService) GetHost(ctx context.Context, id uuid.UUID) (*db.Host, error)

GetHost retrieves a single host by its UUID.

func (*HostService) GetHostGroups added in v0.24.0

func (s *HostService) GetHostGroups(ctx context.Context, hostID uuid.UUID) ([]db.HostGroupSummary, error)

GetHostGroups returns the groups the given host belongs to.

func (*HostService) GetHostNetworks added in v0.26.0

func (s *HostService) GetHostNetworks(ctx context.Context, hostID uuid.UUID) ([]*db.Network, error)

GetHostNetworks returns the registered networks that contain the host's IP address, ordered by longest prefix first. Membership is derived from the host_network_memberships view; no row is stored. An empty slice (never nil) is returned when the host belongs to no registered network.

func (*HostService) GetHostScans added in v0.19.1

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

GetHostScans returns a paginated list of scans associated with the given host.

func (*HostService) ListHosts added in v0.19.1

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

ListHosts returns a paginated list of hosts matching the given filters.

func (*HostService) ListTags added in v0.24.0

func (s *HostService) ListTags(ctx context.Context) ([]string, error)

ListTags returns a deduplicated, sorted list of all tags in use across all hosts.

func (*HostService) RemoveHostTags added in v0.24.0

func (s *HostService) RemoveHostTags(ctx context.Context, id uuid.UUID, tags []string) error

RemoveHostTags removes the specified tags from the host's tag list.

func (*HostService) UpdateCustomName added in v0.26.0

func (s *HostService) UpdateCustomName(
	ctx context.Context, id uuid.UUID, name *string,
) (*db.Host, error)

UpdateCustomName sets or clears the user-defined display-name override for a host. Pass nil to clear.

func (*HostService) UpdateHost added in v0.19.1

func (s *HostService) UpdateHost(ctx context.Context, id uuid.UUID, input db.UpdateHostInput) (*db.Host, error)

UpdateHost applies the provided changes to an existing host record.

func (*HostService) UpdateHostTags added in v0.24.0

func (s *HostService) UpdateHostTags(ctx context.Context, id uuid.UUID, tags []string) error

UpdateHostTags replaces the entire tag list for the given host.

type IdentityInputs added in v0.26.0

type IdentityInputs struct {
	IPAddress string

	CustomName *string

	MDNSName   *string
	MDNSSeenAt time.Time

	SNMPSysName *string
	SNMPSeenAt  time.Time

	PTRRecords   []PTRObservation
	CertSubjects []CertSubject
}

IdentityInputs is the complete input to the resolver. Callers assemble it by querying the DB (and for cert subjects, forward-resolving CN/SAN values to compare against the host IP) before invoking ResolveDisplayName or ListNameCandidates.

type IdentityResolution added in v0.26.0

type IdentityResolution struct {
	Name       string
	Source     Source
	Confidence float64
}

IdentityResolution is the single winning display name for a host.

func ResolveDisplayName added in v0.26.0

func ResolveDisplayName(in IdentityInputs, rankOrder []string) IdentityResolution

ResolveDisplayName picks the winning display name by walking rankOrder (for example ["mdns","snmp","ptr","cert"]) and returning the first usable candidate from each source. A non-empty CustomName always wins, and the host IP is the last-resort fallback. Unknown source names in rankOrder are silently skipped so operator-edited config can't crash the resolver.

type NameCandidate added in v0.26.0

type NameCandidate struct {
	Name            string
	Source          Source
	Usable          bool
	NotUsableReason string
	ObservedAt      time.Time
}

NameCandidate is one row of the Identity tab table. Unusable candidates are still included so the UI can show users why a given value was not promoted.

func ListNameCandidates added in v0.26.0

func ListNameCandidates(in IdentityInputs) []NameCandidate

ListNameCandidates enumerates every automatic name candidate for a host, usable or not, in a stable order (mdns, snmp, ptr, cert). CustomName is intentionally excluded — the API surfaces it as its own field because the UI renders it in a separate input, not in the candidate table.

type NetworkService

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

NetworkService manages network configuration and exclusions.

func NewNetworkService

func NewNetworkService(database *db.DB) *NetworkService

NewNetworkService creates a new network service.

func (*NetworkService) AddExclusion

func (s *NetworkService) AddExclusion(
	ctx context.Context,
	networkID *uuid.UUID,
	cidr, reason string,
) (*db.NetworkExclusion, error)

AddExclusion adds a new exclusion rule.

func (*NetworkService) CreateNetwork

func (s *NetworkService) CreateNetwork(
	ctx context.Context,
	name, cidr, description, method string,
	isActive, scanEnabled bool,
) (*db.Network, error)

CreateNetwork creates a new network.

func (*NetworkService) DeleteNetwork

func (s *NetworkService) DeleteNetwork(ctx context.Context, id uuid.UUID) error

DeleteNetwork deletes a network and all its exclusions.

func (*NetworkService) GenerateTargetsForNetwork

func (s *NetworkService) GenerateTargetsForNetwork(
	ctx context.Context,
	networkID uuid.UUID,
	maxHosts int,
) ([]string, error)

GenerateTargetsForNetwork generates valid scan targets for a network, applying all exclusions.

func (*NetworkService) GetActiveNetworks

func (s *NetworkService) GetActiveNetworks(ctx context.Context) ([]*NetworkWithExclusions, error)

GetActiveNetworks returns all active networks with their exclusions.

func (*NetworkService) GetGlobalExclusions

func (s *NetworkService) GetGlobalExclusions(ctx context.Context) ([]*db.NetworkExclusion, error)

GetGlobalExclusions returns all global exclusions.

func (*NetworkService) GetNetworkByID

func (s *NetworkService) GetNetworkByID(ctx context.Context, id uuid.UUID) (*NetworkWithExclusions, error)

GetNetworkByID retrieves a network by ID with its exclusions.

func (*NetworkService) GetNetworkByName

func (s *NetworkService) GetNetworkByName(ctx context.Context, name string) (*NetworkWithExclusions, error)

GetNetworkByName retrieves a network by name with its exclusions.

func (*NetworkService) GetNetworkExclusions added in v0.13.0

func (s *NetworkService) GetNetworkExclusions(
	ctx context.Context, networkID uuid.UUID,
) ([]*db.NetworkExclusion, error)

GetNetworkExclusions returns all exclusions for a specific network.

func (*NetworkService) GetNetworkStats

func (s *NetworkService) GetNetworkStats(ctx context.Context) (map[string]interface{}, error)

GetNetworkStats returns statistics about networks and exclusions.

func (*NetworkService) ListNetworks

func (s *NetworkService) ListNetworks(ctx context.Context, activeOnly bool) ([]*db.Network, error)

ListNetworks returns all networks with optional filtering.

func (*NetworkService) RemoveExclusion

func (s *NetworkService) RemoveExclusion(ctx context.Context, exclusionID uuid.UUID) error

RemoveExclusion removes an exclusion rule.

func (*NetworkService) SeedNetworksFromConfig

func (s *NetworkService) SeedNetworksFromConfig(ctx context.Context, cfg *config.Config) error

SeedNetworksFromConfig creates or updates networks based on config.

func (*NetworkService) UpdateNetwork

func (s *NetworkService) UpdateNetwork(
	ctx context.Context,
	id uuid.UUID,
	name, cidr, description, method string,
	enabled bool,
) (*db.Network, error)

UpdateNetwork updates an existing network.

func (*NetworkService) UpdateNetworkDiscoveryTime

func (s *NetworkService) UpdateNetworkDiscoveryTime(
	ctx context.Context,
	networkID uuid.UUID,
	discoveredHosts, activeHosts int,
) error

UpdateNetworkDiscoveryTime updates the last discovery timestamp for a network.

type NetworkWithExclusions

type NetworkWithExclusions struct {
	Network    *db.Network
	Exclusions []*db.NetworkExclusion
}

NetworkWithExclusions represents a network with its exclusions.

type PTRObservation added in v0.26.0

type PTRObservation struct {
	Name       string
	ObservedAt time.Time
}

PTRObservation is a single PTR record with its observation timestamp.

type ProfileRecommendation added in v0.25.0

type ProfileRecommendation struct {
	OSFamily    string `json:"os_family"`
	HostCount   int    `json:"host_count"`
	ProfileID   string `json:"profile_id"`
	ProfileName string `json:"profile_name"`
	Action      string `json:"action"` // the ScanStage.Stage value to use
}

ProfileRecommendation suggests a scan profile for a group of hosts sharing the same detected OS family.

type ProfileService added in v0.19.1

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

ProfileService handles business logic for scan profile management.

func NewProfileService added in v0.19.1

func NewProfileService(repo profileRepository, logger *slog.Logger) *ProfileService

NewProfileService creates a new ProfileService with the provided repository and logger.

func (*ProfileService) CloneProfile added in v0.19.1

func (s *ProfileService) CloneProfile(ctx context.Context, fromID, newName string) (*db.ScanProfile, error)

CloneProfile creates a new scan profile based on an existing one, using newName as the name of the clone. Scripts are not copied to the clone.

func (*ProfileService) CreateProfile added in v0.19.1

func (s *ProfileService) CreateProfile(ctx context.Context, input db.CreateProfileInput) (*db.ScanProfile, error)

CreateProfile creates a new scan profile record.

func (*ProfileService) DeleteProfile added in v0.19.1

func (s *ProfileService) DeleteProfile(ctx context.Context, id string) error

DeleteProfile removes a scan profile by its ID.

func (*ProfileService) GetProfile added in v0.19.1

func (s *ProfileService) GetProfile(ctx context.Context, id string) (*db.ScanProfile, error)

GetProfile retrieves a single scan profile by its ID.

func (*ProfileService) GetProfileStats added in v0.25.0

func (s *ProfileService) GetProfileStats(ctx context.Context, id string) (*db.ProfileStats, error)

GetProfileStats returns scan effectiveness statistics for a profile.

func (*ProfileService) ListProfiles added in v0.19.1

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

ListProfiles returns a paginated list of profiles matching the given filters.

func (*ProfileService) UpdateProfile added in v0.19.1

func (s *ProfileService) UpdateProfile(
	ctx context.Context, id string, input db.UpdateProfileInput,
) (*db.ScanProfile, error)

UpdateProfile applies the provided changes to an existing scan profile.

type ScanService added in v0.19.1

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

ScanService provides business logic for scan lifecycle operations.

func NewScanService added in v0.19.1

func NewScanService(repo scanRepository, logger *slog.Logger) *ScanService

NewScanService creates a new ScanService backed by the given repository.

func (*ScanService) CompleteScan added in v0.19.1

func (s *ScanService) CompleteScan(ctx context.Context, id uuid.UUID) error

CompleteScan marks a scan as successfully completed.

func (*ScanService) CreateScan added in v0.19.1

func (s *ScanService) CreateScan(ctx context.Context, input db.CreateScanInput) (*db.Scan, error)

CreateScan validates the input, optionally verifies the referenced profile, and delegates creation to the repository.

func (*ScanService) DB added in v0.19.1

func (s *ScanService) DB() *db.DB

DB returns the underlying raw *db.DB connection, or nil when the repository is not a concrete *db.ScanRepository (e.g. a mock in tests). This is used exclusively by the scan execution pipeline which needs direct database access to persist discovered hosts and port-scan results.

func (*ScanService) DeleteScan added in v0.19.1

func (s *ScanService) DeleteScan(ctx context.Context, id uuid.UUID) error

DeleteScan removes a scan record by ID.

func (*ScanService) GetProfile added in v0.19.1

func (s *ScanService) GetProfile(ctx context.Context, id string) (*db.ScanProfile, error)

GetProfile retrieves a scan profile by its string ID.

func (*ScanService) GetScan added in v0.19.1

func (s *ScanService) GetScan(ctx context.Context, id uuid.UUID) (*db.Scan, error)

GetScan retrieves a single scan by its ID.

func (*ScanService) GetScanResults added in v0.19.1

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

GetScanResults retrieves paginated port-scan results for a given scan.

func (*ScanService) GetScanSummary added in v0.19.1

func (s *ScanService) GetScanSummary(ctx context.Context, scanID uuid.UUID) (*db.ScanSummary, error)

GetScanSummary retrieves aggregated statistics for a given scan.

func (*ScanService) ListScans added in v0.19.1

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

ListScans retrieves scans with optional filtering and pagination.

func (*ScanService) StartScan added in v0.19.1

func (s *ScanService) StartScan(ctx context.Context, id uuid.UUID) (*db.Scan, error)

StartScan transitions a scan to the running state. It fetches the current scan to guard against invalid state transitions, calls repo.StartScan, then returns the refreshed scan record.

func (*ScanService) StopScan added in v0.19.1

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

StopScan halts a running scan, optionally recording an error message.

func (*ScanService) UpdateScan added in v0.19.1

func (s *ScanService) UpdateScan(
	ctx context.Context,
	id uuid.UUID,
	input db.UpdateScanInput,
) (*db.Scan, error)

UpdateScan applies the given mutations to an existing scan.

type ScanStage added in v0.25.0

type ScanStage struct {
	Stage       string  `json:"stage"`                // os_detection, port_expansion, service_scan, refresh, skip
	ScanType    string  `json:"scan_type"`            // nmap scan type to use
	Ports       string  `json:"ports"`                // port specification
	OSDetection bool    `json:"os_detection"`         // whether to enable OS fingerprinting
	ProfileID   *string `json:"profile_id,omitempty"` // profile to attribute the scan to (may be nil)
	Reason      string  `json:"reason"`               // human-readable explanation
}

ScanStage describes what the Smart Scan orchestrator recommends doing next for a specific host.

type ScheduleService added in v0.19.1

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

ScheduleService provides business logic for scheduled-job operations.

func NewScheduleService added in v0.19.1

func NewScheduleService(repo scheduleRepository, logger *slog.Logger) *ScheduleService

NewScheduleService creates a new ScheduleService backed by the given repository.

func (*ScheduleService) CreateSchedule added in v0.19.1

func (s *ScheduleService) CreateSchedule(
	ctx context.Context,
	input db.CreateScheduleInput,
) (*db.Schedule, error)

CreateSchedule validates the cron expression and delegates creation to the repository.

func (*ScheduleService) DeleteSchedule added in v0.19.1

func (s *ScheduleService) DeleteSchedule(ctx context.Context, id uuid.UUID) error

DeleteSchedule removes a schedule by ID.

func (*ScheduleService) DisableSchedule added in v0.19.1

func (s *ScheduleService) DisableSchedule(ctx context.Context, id uuid.UUID) error

DisableSchedule prevents a schedule from being run by the scheduler.

func (*ScheduleService) EnableSchedule added in v0.19.1

func (s *ScheduleService) EnableSchedule(ctx context.Context, id uuid.UUID) error

EnableSchedule enables a schedule so it will be picked up by the scheduler.

func (*ScheduleService) GetSchedule added in v0.19.1

func (s *ScheduleService) GetSchedule(ctx context.Context, id uuid.UUID) (*db.Schedule, error)

GetSchedule retrieves a single schedule by its ID.

func (*ScheduleService) ListSchedules added in v0.19.1

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

ListSchedules retrieves schedules with optional filtering and pagination.

func (*ScheduleService) NextRun added in v0.19.1

func (s *ScheduleService) NextRun(ctx context.Context, id uuid.UUID) (time.Time, error)

NextRun fetches the schedule, parses its cron expression, and returns the next time the job would fire after the current UTC instant.

func (*ScheduleService) UpdateSchedule added in v0.19.1

func (s *ScheduleService) UpdateSchedule(
	ctx context.Context,
	id uuid.UUID,
	input db.UpdateScheduleInput,
) (*db.Schedule, error)

UpdateSchedule validates the cron expression if it is being changed, then delegates the update to the repository.

type ScoreInput added in v0.25.0

type ScoreInput struct {
	HasOSFamily   bool
	HasOpenPorts  bool
	HasServices   bool
	IsFresh       bool // last_seen within 7 days
	HasEnrichment bool // banners or SNMP data present
}

ScoreInput holds the boolean inputs used in the pure score calculation. This type is exposed for testing without database access.

type SmartScanService added in v0.25.0

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

SmartScanService evaluates host knowledge gaps and queues targeted scans.

func NewSmartScanService added in v0.25.0

func NewSmartScanService(
	database *db.DB,
	profileManager *profiles.Manager,
	scanQueue *scanning.ScanQueue,
	logger *slog.Logger,
) *SmartScanService

NewSmartScanService creates a new SmartScanService.

func (*SmartScanService) EvaluateHost added in v0.25.0

func (s *SmartScanService) EvaluateHost(ctx context.Context, host *db.Host) (*ScanStage, error)

EvaluateHost determines the next recommended scan stage for a single host. Returns a ScanStage with Stage == "skip" when no action is recommended.

func (*SmartScanService) EvaluateHostByID added in v0.25.0

func (s *SmartScanService) EvaluateHostByID(ctx context.Context, hostID uuid.UUID) (*ScanStage, error)

EvaluateHostByID is a convenience wrapper that loads the host then calls EvaluateHost.

func (*SmartScanService) GetProfileRecommendations added in v0.25.0

func (s *SmartScanService) GetProfileRecommendations(ctx context.Context) ([]ProfileRecommendation, error)

GetProfileRecommendations returns profile suggestions grouped by OS family. For each OS family present in the fleet, it finds the best matching profile template. Only families with an available profile are returned — an empty slice means there are no actionable recommendations.

func (*SmartScanService) GetSuggestions added in v0.25.0

func (s *SmartScanService) GetSuggestions(ctx context.Context) (*SuggestionSummary, error)

GetSuggestions aggregates host gap counts fleet-wide. Results are computed on-demand from the existing hosts table — no separate suggestions table needed.

func (*SmartScanService) QueueBatch added in v0.25.0

func (s *SmartScanService) QueueBatch(ctx context.Context, filter BatchFilter) (*BatchResult, error)

QueueBatch queues smart scans for all eligible hosts matching the filter.

func (*SmartScanService) QueueIdentityEnrichment added in v0.26.0

func (s *SmartScanService) QueueIdentityEnrichment(ctx context.Context, hostID uuid.UUID) (uuid.UUID, error)

QueueIdentityEnrichment queues an identity_enrichment scan for a host unconditionally — bypassing EvaluateHost's usability check. Used by the "Refresh identity now" button in the Identity tab; the user has asked explicitly, so the fact that the host may already have a usable name is irrelevant. Returns the created scan UUID.

func (*SmartScanService) QueueSmartScan added in v0.25.0

func (s *SmartScanService) QueueSmartScan(ctx context.Context, hostID uuid.UUID) (uuid.UUID, error)

QueueSmartScan evaluates a single host and queues the recommended scan. Returns the created scan UUID and an error. If the stage is "skip" a nil UUID is returned with no error.

func (*SmartScanService) ReEvaluateHosts added in v0.25.0

func (s *SmartScanService) ReEvaluateHosts(_ *db.DB, hostIDs []uuid.UUID)

ReEvaluateHosts is the PostScanHook callback. It recalculates knowledge scores for the given hosts, then evaluates their next scan stage and logs the recommendation. It does not auto-queue further scans.

func (*SmartScanService) WithAutoProgression added in v0.25.0

func (s *SmartScanService) WithAutoProgression(threshold, maxPerWindow, windowHours int) *SmartScanService

WithAutoProgression enables the post-scan auto-queuing feature. When enabled, ReEvaluateHosts will call QueueSmartScan for any host whose knowledge score after a scan is still below threshold — up to maxPerWindow times within windowHours. Pass 0 for maxPerWindow or windowHours to use defaults.

type Source added in v0.26.0

type Source string

Source identifies where a host name candidate came from.

const (
	SourceCustom Source = "custom"
	SourceMDNS   Source = "mdns"
	SourceSNMP   Source = "snmp"
	SourcePTR    Source = "ptr"
	SourceCert   Source = "cert"
	SourceIP     Source = "ip"
)

Known identity sources. SourceIP is the final fallback when nothing else produced a usable name.

type SuggestionGroup added in v0.25.0

type SuggestionGroup struct {
	Count       int    `json:"count"`
	Description string `json:"description"`
	Action      string `json:"action"` // matches ScanStage.Stage
}

SuggestionGroup aggregates hosts that share the same knowledge gap.

type SuggestionSummary added in v0.25.0

type SuggestionSummary struct {
	NoOSInfo    SuggestionGroup `json:"no_os_info"`
	NoPorts     SuggestionGroup `json:"no_ports"`
	NoServices  SuggestionGroup `json:"no_services"`
	Stale       SuggestionGroup `json:"stale"`
	WellKnown   SuggestionGroup `json:"well_known"`
	TotalHosts  int             `json:"total_hosts"`
	GeneratedAt time.Time       `json:"generated_at"`
}

SuggestionSummary holds fleet-wide gap counts for the dashboard widget.

Jump to

Keyboard shortcuts

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