From f296056360dd479b06847df89584b0c60337c48a Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Thu, 16 Jul 2026 22:37:26 +1000 Subject: [PATCH] Add pburl and pblastreport companion tools to the RPM (#15) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Why `node-lookup` output is handy for pivoting to Puppetboard, but there was no quick way to turn a list of hosts into Puppetboard node-page URLs, or to see when each host last ran Puppet. These two small tools close that gap and ship in the **same RPM** so they're available wherever `node-lookup` is. ## Changes - Add **`pburl`**: reads hostnames from args or piped `node-lookup` output (first field of each line, de-duped) and prints ` `. - Add **`pblastreport`**: prints `\t\t` using `report_timestamp` from the PuppetDB v4 `nodes` endpoint. Supports `--relative`/`-r` (relative age) and `--timezone`/`-z ` (default: local timezone). - Add **`internal/puppet`** package shared by both tools: config load, PuppetDB `nodes` query, Puppetboard URL construction (`/node/`), and no-TTY-safe stdin host reading. - Add **`puppetboard_url`** config key (env `NODE_LOOKUP_PUPPETBOARD_URL`, default `https://puppetboard.k8s.syd1.au.unkin.net`) to the shared config so `config init`/`config show` scaffold it for the whole tool family. `node-lookup`'s own query behaviour is unchanged. - Build all three binaries individually (each is its own `main` package — a single `go build ./...` can't emit multiple mains) and generate per-binary bash/zsh/fish completions in the Makefile, `build-rpm.sh`, and nfpm spec. - Cross-compile and attach all three tools per os/arch in the release pipeline; extend `.gitignore`; `go mod tidy` promotes cobra/yaml to direct deps. - Document the tools, config key, and env var in `AGENTS.md`. ## Testing - `go test -race ./...` passes (new tests cover config precedence, `nodes` endpoint derivation, host-page URLs, `LookupNode`, stdin host parsing, and the report-time formatting incl. timezone/relative/edge cases). - Built the RPM locally and confirmed it installs all 3 binaries + 9 completion files. - Smoke-tested both tools end-to-end against a mock PuppetDB (timezone conversion, relative time, and error handling all correct). No cross-repo changes needed: the release reuses the existing `default` ServiceAccount and the artifactapi `rpm-internal` upload. Reviewed-on: https://git.unkin.net/unkin/node-lookup/pulls/15 Co-authored-by: Ben Vincent Co-committed-by: Ben Vincent --- .gitignore | 9 +- .woodpecker/release.yaml | 26 +++-- AGENTS.md | 45 +++++++- Makefile | 28 +++-- cmd/pblastreport/main.go | 97 +++++++++++++++++ cmd/pblastreport/report.go | 53 ++++++++++ cmd/pblastreport/report_test.go | 84 +++++++++++++++ cmd/pburl/main.go | 63 ++++++++++++ go.mod | 11 +- go.sum | 1 + internal/puppet/board.go | 9 ++ internal/puppet/config.go | 90 ++++++++++++++++ internal/puppet/puppet_test.go | 177 ++++++++++++++++++++++++++++++++ internal/puppet/puppetdb.go | 71 +++++++++++++ internal/puppet/stdin.go | 66 ++++++++++++ main.go | 30 ++++-- packaging/nfpm.yaml | 38 ++++++- scripts/build-rpm.sh | 29 +++--- 18 files changed, 881 insertions(+), 46 deletions(-) create mode 100644 cmd/pblastreport/main.go create mode 100644 cmd/pblastreport/report.go create mode 100644 cmd/pblastreport/report_test.go create mode 100644 cmd/pburl/main.go create mode 100644 internal/puppet/board.go create mode 100644 internal/puppet/config.go create mode 100644 internal/puppet/puppet_test.go create mode 100644 internal/puppet/puppetdb.go create mode 100644 internal/puppet/stdin.go diff --git a/.gitignore b/.gitignore index d852eda..2ad83ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,9 @@ -node-lookup +# built binaries (repo root only — not the cmd/ source dirs) +/node-lookup +/pburl +/pblastreport +# cross-compiled release artifacts (e.g. node-lookup-linux-amd64) +/node-lookup-* +/pburl-* +/pblastreport-* dist/ diff --git a/.woodpecker/release.yaml b/.woodpecker/release.yaml index 14a24ef..040441c 100644 --- a/.woodpecker/release.yaml +++ b/.woodpecker/release.yaml @@ -17,16 +17,22 @@ steps: memory: 2Gi cpu: 2 - # Build the linux/amd64 binary into dist/ (consumed by the RPM step) plus the - # cross-platform binaries attached to the Gitea release. + # Build all binaries into dist/ (consumed by the RPM step) plus the + # cross-platform binaries attached to the Gitea release. Each tool is a + # separate main package, so they are built individually per os/arch. - name: build image: git.unkin.net/unkin/almalinux9-gobuilder:20260606 commands: - make build VERSION=${CI_COMMIT_TAG} - - GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X main.version=${CI_COMMIT_TAG}" -o node-lookup-linux-amd64 ./... - - GOOS=linux GOARCH=arm64 go build -ldflags="-s -w -X main.version=${CI_COMMIT_TAG}" -o node-lookup-linux-arm64 ./... - - GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w -X main.version=${CI_COMMIT_TAG}" -o node-lookup-darwin-amd64 ./... - - GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w -X main.version=${CI_COMMIT_TAG}" -o node-lookup-darwin-arm64 ./... + - | + for entry in "node-lookup:." "pburl:./cmd/pburl" "pblastreport:./cmd/pblastreport"; do + name="${entry%%:*}"; pkg="${entry##*:}" + for osarch in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64; do + GOOS="${osarch%/*}" GOARCH="${osarch#*/}" \ + go build -ldflags="-s -w -X main.version=${CI_COMMIT_TAG}" \ + -o "${name}-${osarch%/*}-${osarch#*/}" "${pkg}" + done + done depends_on: [test] backend_options: kubernetes: @@ -113,6 +119,14 @@ steps: node-lookup-linux-arm64 \ node-lookup-darwin-amd64 \ node-lookup-darwin-arm64 \ + pburl-linux-amd64 \ + pburl-linux-arm64 \ + pburl-darwin-amd64 \ + pburl-darwin-arm64 \ + pblastreport-linux-amd64 \ + pblastreport-linux-arm64 \ + pblastreport-darwin-amd64 \ + pblastreport-darwin-arm64 \ --login gitea --repo "${CI_REPO}" depends_on: [upload-rpm] backend_options: diff --git a/AGENTS.md b/AGENTS.md index 4cfa2ff..57321bf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,22 +2,39 @@ ## Project Overview -`node-lookup` is a Go CLI tool that queries a PuppetDB API to retrieve and filter node facts. +This repo ships three related Puppet CLIs in one RPM: + +- **`node-lookup`** — queries the PuppetDB API to retrieve and filter node facts. +- **`pburl`** — prints the Puppetboard node-page URL for each host (reads hosts + from args or piped `node-lookup` output). Output: ` `. +- **`pblastreport`** — prints each host's last Puppet report time and its + Puppetboard URL. Output: `\t