Files
terraform-infra/tools/backfill/emit_test.go
T
unkinben 585d32b15c
ci/woodpecker/pr/plan Pipeline failed
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/backfill-test Pipeline was successful
Backfill NetBox reality from pdbmux
Automate the PuppetDB reality import (issue #1) by querying pdbmux — the
PuppetDB multiplexer whose HTTPS gateway is reachable from CI/workstations,
unlike raw PuppetDB — instead of PuppetDB directly, and shaping the result to
the NetBox reality side the devices module reconciles.

- Add tools/backfill (Go): query pdbmux /pdb/query/v4/facts for the 13 existing
  physicals and emit per-host reality YAML — serial/model/UUID, every recordable
  interface (real NICs plus overlay/loopback/kube-lb) with MAC and CIDR IPs, and
  CPU/RAM/disk inventory. Filter ephemeral Calico veths and Ceph RBD volumes;
  take interface names from Facter, never assume them.
- Emit deterministic, idempotent, yamllint-clean output into
  config/au/syd1/reality/<host>.yaml, generated for prodnxsr0001-0013.
- Extend modules/infra with a reality variable and reality.tf creating
  netbox_device_interface/netbox_mac_address/netbox_ip_address/
  netbox_inventory_item and device serial; wire reality only for hosts that also
  have an intent device.
- Load reality/*.yaml in the terragrunt env; add `make backfill`; add a
  go vet/test woodpecker job; drop the in-cluster-only Python script.

Closes #1

Claude-Session: https://claude.ai/code/session_01JUoARVdmhxKQHyyyp1pxeT
2026-08-06 23:15:21 +10:00

80 lines
2.2 KiB
Go

package main
import "testing"
func sampleReality() Reality {
return Reality{
Device: "prodnxsr0001",
Serial: "4RW6QM2",
Model: "OptiPlex 3050",
UUID: "4c4c4544-0052-5710-8036-b4c04f514d32",
Interfaces: []Interface{
{Name: "enp2s0", MAC: "d8:9e:f3:75:c3:60", MTU: 1500, Physical: true,
IPs: []string{"198.18.15.1/24", "198.18.19.1/32"}},
{Name: "loopback0", MAC: "f2:3d:ef:64:42:51", Physical: false,
IPs: []string{"198.18.19.1/32"}},
},
Inventory: &Inventory{
CPU: &CPU{Model: "Intel(R) Core(TM) i5-7500T CPU @ 2.70GHz", Cores: 4, Count: 4},
MemoryBytes: 33260900352,
Disks: []Disk{
{Name: "sda", Model: "SSDSC2BX012T4N", Serial: "BTHC651303WB1P2OGN", SizeBytes: 1200243695616},
},
},
}
}
const wantYAML = `# Generated by tools/backfill from pdbmux - do not edit by hand.
# source: URL certname=prodnxsr0001.main.unkin.net
device: "prodnxsr0001"
serial: "4RW6QM2"
model: "OptiPlex 3050"
uuid: "4c4c4544-0052-5710-8036-b4c04f514d32"
interfaces:
- name: "enp2s0"
mac: "d8:9e:f3:75:c3:60"
mtu: 1500
physical: true
ips:
- "198.18.15.1/24"
- "198.18.19.1/32"
- name: "loopback0"
mac: "f2:3d:ef:64:42:51"
physical: false
ips:
- "198.18.19.1/32"
inventory:
cpu:
model: "Intel(R) Core(TM) i5-7500T CPU @ 2.70GHz"
cores: 4
count: 4
memory_bytes: 33260900352
disks:
- name: "sda"
model: "SSDSC2BX012T4N"
serial: "BTHC651303WB1P2OGN"
size_bytes: 1200243695616
`
func TestEmitYAMLGolden(t *testing.T) {
got := emitYAML(sampleReality(), "source: URL certname=prodnxsr0001.main.unkin.net")
if got != wantYAML {
t.Errorf("emit mismatch:\n--- got ---\n%s\n--- want ---\n%s", got, wantYAML)
}
}
func TestEmitYAMLDeterministic(t *testing.T) {
src := "source: URL certname=x"
if emitYAML(sampleReality(), src) != emitYAML(sampleReality(), src) {
t.Error("emit is not deterministic")
}
}
func TestEmitYAMLEmptyCollections(t *testing.T) {
got := emitYAML(Reality{Device: "d"}, "s")
want := "# Generated by tools/backfill from pdbmux - do not edit by hand.\n# s\ndevice: \"d\"\ninterfaces: []\n"
if got != want {
t.Errorf("empty emit = %q, want %q", got, want)
}
}