Documentation
¶
Overview ¶
Package hostinventory is the use-case layer for the VM host agent (#410/#446, epic #405). It takes a host inventory an agent collected (facts + installed OS packages + coverage) and persists the host as a Kind=host asset in the fleet asset model (#431), reusing the asset use case's idempotent upsert-by-natural-key + audit path.
Coverage honesty is preserved: the inventory's coverage issues are recorded (count + degraded flag on the asset, each issue audited), so a partial host inventory is never presented as complete. The asset model records the host identity, its facts, and a package count; the package LIST goes to the optional VulnerabilityRecorder (the hostvuln use case), which records it as the host's SBOM and queues the SCA vulnerability pipeline against it (#820).
Index ¶
Constants ¶
const ( ReasonNoPackages = "no packages reported" ReasonUnchanged = "package set unchanged since the last recorded scan" ReasonScanActive = "a vulnerability scan is still running for this host; the next sync records the change" // ReasonRecordedRecently: a different package set arrived within the minimum record interval. ReasonRecordedRecently = "a package set was recorded for this host less than ten minutes ago; the next sync records the change" ReasonQueueError = "vulnerability scan could not be queued; see the audit log" )
Reasons a sync records no new vulnerability scan.
const MaxHostsPerAgent = dhi.MaxHostsPerAgent
MaxHostsPerAgent bounds how many distinct host assets one agent identity may create. An agent reports the host it runs on; a machine-id change (reimage, cloned VM) legitimately makes a new one, so the cap is a small multiple rather than one. Above it, a new key is refused: an agent varying its facts must not mint host assets, hidden vulnerability contexts and scans without bound.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AssetWriter ¶
type AssetWriter interface {
GetAssetByKey(ctx context.Context, tenantID shared.ID, kind asset.Kind, key string) (*asset.Asset, error)
UpsertAsset(ctx context.Context, actor string, in assetuc.UpsertAssetInput) (*asset.Asset, error)
ListAssets(ctx context.Context, tenantID shared.ID) ([]*asset.Asset, error)
}
AssetWriter is the subset of the asset use case this service needs. The read is part of the authorization boundary: an authenticated agent may update the host it already reports, but must never silently take over a host natural key already owned by a different enrolled agent.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service maps and persists a host inventory.
func NewService ¶
func NewService(assets AssetWriter, audit ports.AuditLogger, clock ports.Clock) (*Service, error)
NewService validates its dependencies and constructs the service.
func (*Service) SetTelemetryBinder ¶ added in v0.2.0
func (s *Service) SetTelemetryBinder(b ports.TelemetryAssetBindingStore)
SetTelemetryBinder wires the server-authoritative agent→host telemetry binding store. When set, a successful host-inventory sync establishes (or refreshes) the reporting agent's canonical telemetry asset binding — the A3 mapping that telemetry ingest requires (see the Sync doc comment). Kept an optional setter (nil ⇒ no binding) so telemetry-less compositions are unchanged.
func (*Service) SetVulnerabilityRecorder ¶ added in v0.2.0
func (s *Service) SetVulnerabilityRecorder(r VulnerabilityRecorder)
SetVulnerabilityRecorder wires the recorder that correlates the reported packages with advisories. When set, every sync that carries packages records them as the host's SBOM and queues a vulnerability scan; a recorder failure is audited and reported in the result, never returned, so a host inventory is persisted even when the scan pipeline is unavailable.
func (*Service) Sync ¶
Sync persists the host as a Kind=host asset. It is idempotent: two syncs of an unchanged host reuse the asset id (keyed by the host's stable identity) and produce no churn. reporting_agent_id is stamped from actor, which the HTTP adapter obtains from the authenticated fleet credential; it is never read from Inventory. A3 uses this server-authored attribute to establish the canonical telemetry binding.
type SyncInput ¶
type SyncInput struct {
TenantID shared.ID
Inventory dhi.HostInventory
}
SyncInput describes one observation of a host.
type SyncResult ¶
type SyncResult struct {
AssetID shared.ID
Complete bool
Degraded bool
Coverage int
// VulnerabilityScan is nil when no recorder is wired.
VulnerabilityScan *VulnerabilityOutcome
}
SyncResult reports what a sync produced.
type VulnerabilityOutcome ¶ added in v0.2.0
type VulnerabilityOutcome struct {
EngagementID shared.ID `json:"engagement_id,omitempty"`
JobID string `json:"job_id,omitempty"`
Components int `json:"components"`
Skipped bool `json:"skipped"`
Failed bool `json:"failed,omitempty"`
Reason string `json:"reason,omitempty"`
}
VulnerabilityOutcome reports what a sync did with the host's package list. Skipped with a Reason is a normal outcome (no packages, or the package set is unchanged since the last recorded scan); Failed marks a recorder error that was audited and did not fail the inventory sync.
type VulnerabilityRecorder ¶ added in v0.2.0
type VulnerabilityRecorder interface {
Record(ctx context.Context, actor string, tenantID shared.ID, host *asset.Asset, inv dhi.HostInventory) (VulnerabilityOutcome, error)
}
VulnerabilityRecorder turns the packages a host reported into CVE findings for that host (#820). The concrete implementation lives in the hostvuln use case; this consumer-side interface keeps the inventory path free of the SCA pipeline's types.