Documentation
¶
Overview ¶
Package probe holds pure parsers for the OS-fingerprint commands the Discovery service runs over SSH. Each parser takes the raw stdout bytes of a single command and returns a typed fact struct.
Spec: specs/system/host-discovery.spec.yaml (C-01).
Pure: no SSH dial, no database, no HTTP, no time.Now. Parsers are trivially testable with bytes fixtures (see probe_test.go).
Index ¶
Constants ¶
const ( OutcomeDenied = "denied" // positive evidence of a sudo/permission refusal OutcomeFailed = "failed" // transport error or non-permission command failure OutcomeTimeout = "timeout" // the probe exceeded the run deadline )
Observation outcomes for a probe that did NOT yield a value on a run. Shared by Discovery (system-host-discovery) and the intelligence collector (system-os-intelligence) so the sudo-refusal signature list — a security-relevant classifier — lives in exactly one place and cannot drift between the two callers.
Variables ¶
This section is empty.
Functions ¶
func ClassifyOutcome ¶ added in v0.6.0
ClassifyOutcome maps a probe's (out, err) to a non-observed outcome. A context-deadline error is OutcomeTimeout; any other error is OutcomeFailed; a nil error whose output carries a sudo-refusal signature is OutcomeDenied; a nil error with a non-zero-exit output and no signature is OutcomeFailed. Positive-evidence only for denied — under-reporting a denial is safer than mislabeling an absent tool or a dropped connection as a permission problem.
func SudoDenied ¶ added in v0.6.0
SudoDenied reports whether the combined command output carries a recognizable sudo-refusal signature. Case-insensitive substring match.
Types ¶
type MemInfoFacts ¶
MemInfoFacts is the subset of /proc/meminfo OpenWatch surfaces. All fields are MB-rounded integers (kB / 1024 → MB). A field absent from the input yields zero, not an error — swap-disabled hosts have no SwapTotal line and must still parse cleanly (C-01, AC-04).
func ParseMemInfo ¶
func ParseMemInfo(b []byte) (MemInfoFacts, error)
ParseMemInfo parses /proc/meminfo and returns MB-rounded MemTotal, MemAvailable, SwapTotal. Each line is `Key: <value> kB`; integer division by 1024 produces MB. Missing keys yield zero (AC-04).
type OSFacts ¶
type OSFacts struct {
OSName string
OSVersion string // VERSION_ID, e.g. "9.4" or "24.04"
OSVersionFull string // VERSION, e.g. "9.4 (Plow)" or "24.04.3 LTS (Noble Numbat)"
OSID string
OSIDLike string
OSPrettyName string
PlatformIdentifier string // PLATFORM_ID, e.g. "platform:el9"
}
OSFacts is the structured form of /etc/os-release. Field semantics follow the FHS/os-release standard; both RHEL-family (quoted values) and Debian-family (mixed quoting) input is accepted.
func ParseOSRelease ¶
ParseOSRelease parses /etc/os-release contents into OSFacts.
Each line is KEY=VALUE; VALUE may or may not be quoted. Unknown keys are ignored. Empty input returns zero-value OSFacts and a nil error (a host with no os-release file is rare but not a probe failure).
type UnameFacts ¶
type UnameFacts struct {
KernelName string
KernelRelease string
KernelVersion string
Architecture string
}
UnameFacts is the structured form of `uname -srvm` output. Layout per coreutils: KernelName KernelRelease KernelVersion Architecture where KernelVersion is the long middle that contains build metadata.
func ParseUname ¶
func ParseUname(b []byte) (UnameFacts, error)
ParseUname parses `uname -srvm` output (one line, space-separated).
Layout: <kernel_name> <kernel_release> <... kernel_version ...> <arch> — KernelVersion is everything between KernelRelease and Architecture because it can contain spaces (e.g. "#1 SMP PREEMPT_DYNAMIC Wed Aug 23 ...").