- rename internal/pdbmux to internal/puppetdb - fetch facts with one GET /pdb/query/v4/facts AST query per node - drop the per-node fallback route and its two response shapes - rename --pdb to --puppetdb, CATALOG_DIFF_PDB to CATALOG_DIFF_PUPPETDB and pdb_url to puppetdb_url - describe the fact source generically in the README and AGENTS.md
5.5 KiB
puppet-catalog-tools
CLI tooling for the Puppet estate. Currently one binary:
catalog-diff— compiles a host's catalog in a base environment and in the environment built from the branch under test, then diffs the two.
Catalogs are compiled over the puppetserver API (POST /puppet/v4/catalog)
with facts read from PuppetDB. Nothing is compiled locally and nothing is
persisted on the server.
Install
dnf install puppet-catalog-tools # from the artifactapi rpm-internal repo
# or
make build # -> dist/catalog-diff
Usage
catalog-diff web01.example.net --branch benvin/motd-change
catalog-diff web01.example.net --environment benvin_motd_change --json
catalog-diff web01.example.net --branch benvin/motd-change --testonly
| Flag | Description |
|---|---|
-b, --branch |
branch under test (required unless --environment is given) |
--environment |
explicit environment name, bypasses branch name conversion |
--base |
base environment to diff against (default develop) |
--testonly |
compile the test environment only; result via exit code |
--json |
machine-readable output |
--server |
puppetserver base URL (default https://puppet.k8s.syd1.au.unkin.net:8140) |
--puppetdb |
PuppetDB base URL (default https://pdbmux.k8s.syd1.au.unkin.net) |
--cert / --key / --cacert |
client mTLS material |
--timeout |
per-compile timeout (default 10m; must be positive) |
--retry |
retries for transient compile or transport failures (default 2, range 0-20; a failed compiler-side PuppetDB query counts, a manifest error does not) |
--include-classes |
diff Class resources (ignored by default; they manage nothing) |
--ignore |
ignore resources matching Type[Title] (glob), repeatable |
--ignore-attr |
ignore a parameter on every resource, repeatable |
--display-datatype-changes |
report changes where only the datatype differs (28 vs "28") |
--display-detail-add |
expand the parameters of added resources |
--display-source-file-line |
print the manifest file and line each change came from |
Both compilations run concurrently, so a diff costs roughly one compile.
Exit codes
| Code | Meaning |
|---|---|
| 0 | catalogs compiled, no differences |
| 1 | catalog compilation failed in one or both environments |
| 2 | catalogs compiled, differences present |
| 3 | transport, auth, environment-mismatch or usage error |
--testonly prints nothing on success and returns 0, 1 or 3 — never 2.
Configuration
Precedence (lowest to highest): defaults < config file < env vars < flags.
Config file: $XDG_CONFIG_HOME/puppet-catalog-tools/config.yaml
(~/.config/puppet-catalog-tools/config.yaml). Write a default with
catalog-diff config init; print the active values with catalog-diff config show.
server_url: https://puppet.k8s.syd1.au.unkin.net:8140
puppetdb_url: https://pdbmux.k8s.syd1.au.unkin.net
cert: /etc/puppetlabs/puppet/ssl/certs/catalog-diff.pem
key: /etc/puppetlabs/puppet/ssl/private_keys/catalog-diff.pem
cacert: /etc/puppetlabs/puppet/ssl/certs/ca.pem
base_environment: develop
| Env var | Config key |
|---|---|
CATALOG_DIFF_SERVER |
server_url |
CATALOG_DIFF_PUPPETDB |
puppetdb_url |
CATALOG_DIFF_CERT |
cert |
CATALOG_DIFF_KEY |
key |
CATALOG_DIFF_CACERT |
cacert |
CATALOG_DIFF_BASE_ENVIRONMENT |
base_environment |
catalog-diff needs a client certificate whose certname is allowed to
POST /puppet/v4/catalog in the puppetserver auth.conf. PuppetDB is queried
without credentials.
Branch to environment name
Puppet environment names must match \A[a-z0-9_]+\Z, so a branch name is
converted the way g10k deploys it: every character outside [0-9A-Za-z_]
becomes _ (benvin/foo-bar -> benvin_foo_bar). Case is preserved, because
g10k preserves it — a branch with capitals therefore deploys to a directory
Puppet rejects, and catalog-diff fails fast telling you to rename the branch
or pass --environment. --environment bypasses the conversion entirely.
Environment override
Classification runs through an exec ENC (encapic -> encapi), and an
ENC-supplied environment outranks the requested one. Every request sets
options.prefer_requested_environment, and the returned catalog's own
environment is always compared against the one requested. A mismatch between
two named environments is a hard error (exit 3) rather than a silent diff of an
environment against itself. A response that decodes without an environment name
at all is reported as a protocol mismatch instead, because that is a client/
server problem rather than a classification one.
What a catalog diff cannot see
- Facts come from PuppetDB's last report, not a live agent run, so changes to custom facts are not tested.
- Provider changes and order-of-operations problems (dependency cycles) do not appear in a catalog.
- Catalogs are fetched over the API rather than compiled from a checkout, so a
change to a static file's content — without its
sourcepath changing — produces no readable text diff.
Puppet catalogs can contain unencrypted secrets. Parameters the catalog marks as sensitive are replaced with a digest so a change is still visible without the plaintext reaching stdout or a CI log; anything Puppet does not mark stays in the clear.
Development
make build test lint fmt pre-commit
make rpm # build + package into dist/*.rpm via nfpm
Golden-file tests: go test ./internal/catalog -update rewrites them.