go-facter

Puppet's Facter system-inventory engine in pure Go โ€” no cgo.

pure Go ยท zero cgo Facter schema structured + legacy facts lazy ยท cached custom facts external facts ยท facts.d virtual / container detect linux ยท darwin ยท windows 100% coverage 6 arches
Documentation GitHub
Documentation (MkDocs Material + mike) License: BSD-3-Clause Go 1.26.4+ Coverage 100%

go-facter is a pure-Go (no cgo) reimplementation of Facter, Puppet's system-inventory engine. It discovers structured facts about the host โ€” os, kernel, networking, processors, memory, filesystems, virtual, system_uptime, identity and more โ€” and exposes them through a small, stable API designed to be bound onto Ruby's Facter interface (Facter.value, Facter[], Facter.add, Facter.to_hash). Fact names and structure follow Facter's schema โ€” the aggregate facts with the flat legacy aliases (operatingsystem, osfamily, ipaddress) alongside โ€” so it is a drop-in for Puppet manifests that reference either shape. Every OS probe runs through an injectable seam, so the per-OS collectors and their error branches are covered deterministically โ€” 100% coverage, CI green on Linux, macOS and Windows across 6 arches. It imports only the Go standard library.

Resolver framework ready

Lazy, per-run-cached facts with a dotted-path Value query, ToHash aggregate, and Add / AddFunc custom-fact registration โ€” the stable surface a Ruby binding maps onto Facter.value / Facter[] / Facter.add / Facter.to_hash.

OS, kernel & identity ready

os (name/family/release/distro, os.macosx on Darwin, architecture) from /etc/os-release, sw_vers and the Windows version banner; kernel*; identity (user/group/uid/gid/privileged); timezone; path; facterversion.

Networking ready

networking with hostname / fqdn / domain and a per-interface map โ€” ip/ip6/mac/mtu/netmask/network plus the bindings / bindings6 arrays and the elected primary โ€” mirrored to the legacy ipaddress / macaddress / interfaces aliases.

Hardware & storage ready

processors (count/physicalcount/models/isa), memory (system + swap, bytes and human sizes), mountpoints, filesystems and disks โ€” parsed from /proc, sysctl / vm_stat, df and /sys/block, skipped gracefully where a platform can’t provide one.

Virtualization & uptime ready

virtual / is_virtual โ€” hypervisor detection via DMI and the CPU hypervisor flag, container detection via docker/podman markers and cgroups โ€” plus system_uptime and its uptime* aliases.

DMI, SSH, security & cloud ready

Facter 4 parity facts: dmi (bios / board / chassis / product, with the bios_* / productname / serialnumber / uuid aliases), ssh host keys with pure-Go SSHFP fingerprints, selinux, load_averages, cloud / ec2_metadata (bounded, non-blocking probe), ruby, fips_enabled, aio_agent_version, augeasversion.

Custom & external facts ready

In-process custom facts through the Go registration API, and out-of-process external facts from facts.d directories โ€” JSON, YAML and key=value .txt, plus executable facts. This is the seam the Ruby custom-fact DSL binds onto.

Ruby surface planned

Downstream, not part of this engine module: the sibling go-ruby-facter binds Ruby’s Facter API (Facter.value / [] / add / to_hash, the custom-fact DSL) onto this engine so Puppet manifests and Ruby code under rbgo can resolve facts.

The engine layer of the go-facter org: a stable Go API a Ruby binding maps directly onto Facter.value / Facter.add / Facter.to_hash, with the facter CLI as a thin consumer. Faithful to Facter's fact names and structure, dependency-free (standard library only), and built so Puppet manifests and Ruby code under the sibling org github.com/go-embedded-ruby can resolve facts.