Add pburl and pblastreport companion tools to the RPM (#15)
ci/woodpecker/tag/release Pipeline failed
ci/woodpecker/tag/release Pipeline failed
## 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 `<host> <puppetboard-node-page-url>`. - Add **`pblastreport`**: prints `<host>\t<last-report-time>\t<url>` using `report_timestamp` from the PuppetDB v4 `nodes` endpoint. Supports `--relative`/`-r` (relative age) and `--timezone`/`-z <IANA>` (default: local timezone). - Add **`internal/puppet`** package shared by both tools: config load, PuppetDB `nodes` query, Puppetboard URL construction (`<base>/node/<certname>`), 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: #15 Co-authored-by: Ben Vincent <ben@unkin.net> Co-committed-by: Ben Vincent <ben@unkin.net>
This commit was merged in pull request #15.
This commit is contained in:
@@ -19,10 +19,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
defaultPuppetDBURL = "http://puppetdbapi.service.consul:8080/pdb/query/v4/facts"
|
||||
defaultRoleFact = "enc_role"
|
||||
configFileName = "config.yaml"
|
||||
appName = "node-lookup"
|
||||
defaultPuppetDBURL = "http://puppetdbapi.service.consul:8080/pdb/query/v4/facts"
|
||||
defaultRoleFact = "enc_role"
|
||||
defaultPuppetboardURL = "https://puppetboard.k8s.syd1.au.unkin.net"
|
||||
configFileName = "config.yaml"
|
||||
appName = "node-lookup"
|
||||
)
|
||||
|
||||
var version = "dev"
|
||||
@@ -32,12 +33,17 @@ var version = "dev"
|
||||
type config struct {
|
||||
PuppetDBURL string `yaml:"puppetdb_url"`
|
||||
RoleFact string `yaml:"role_fact"`
|
||||
// PuppetboardURL is not used by node-lookup itself; it is scaffolded here so
|
||||
// the shared config file also configures the companion tools (pburl,
|
||||
// pblastreport) that read this same file.
|
||||
PuppetboardURL string `yaml:"puppetboard_url"`
|
||||
}
|
||||
|
||||
func defaultConfig() config {
|
||||
return config{
|
||||
PuppetDBURL: defaultPuppetDBURL,
|
||||
RoleFact: defaultRoleFact,
|
||||
PuppetDBURL: defaultPuppetDBURL,
|
||||
RoleFact: defaultRoleFact,
|
||||
PuppetboardURL: defaultPuppetboardURL,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +84,9 @@ func loadConfig() (config, error) {
|
||||
if v := os.Getenv("NODE_LOOKUP_ROLE_FACT"); v != "" {
|
||||
cfg.RoleFact = v
|
||||
}
|
||||
if v := os.Getenv("NODE_LOOKUP_PUPPETBOARD_URL"); v != "" {
|
||||
cfg.PuppetboardURL = v
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
@@ -96,7 +105,7 @@ func writeDefaultConfig() error {
|
||||
|
||||
cfg := defaultConfig()
|
||||
data, _ := yaml.Marshal(cfg)
|
||||
header := []byte("# node-lookup configuration\n# Fields can be overridden with env vars: NODE_LOOKUP_URL, NODE_LOOKUP_ROLE_FACT\n\n")
|
||||
header := []byte("# node-lookup configuration\n# Fields can be overridden with env vars: NODE_LOOKUP_URL, NODE_LOOKUP_ROLE_FACT, NODE_LOOKUP_PUPPETBOARD_URL\n# puppetboard_url is used by the companion tools (pburl, pblastreport).\n\n")
|
||||
if err := os.WriteFile(path, append(header, data...), 0o644); err != nil {
|
||||
return fmt.Errorf("writing config: %w", err)
|
||||
}
|
||||
@@ -493,9 +502,10 @@ func main() {
|
||||
Use: "show",
|
||||
Short: "Print the active configuration",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf("config file : %s\n", configPath())
|
||||
fmt.Printf("puppetdb_url: %s\n", cfg.PuppetDBURL)
|
||||
fmt.Printf("role_fact : %s\n", cfg.RoleFact)
|
||||
fmt.Printf("config file : %s\n", configPath())
|
||||
fmt.Printf("puppetdb_url : %s\n", cfg.PuppetDBURL)
|
||||
fmt.Printf("role_fact : %s\n", cfg.RoleFact)
|
||||
fmt.Printf("puppetboard_url: %s\n", cfg.PuppetboardURL)
|
||||
return nil
|
||||
},
|
||||
SilenceUsage: true,
|
||||
|
||||
Reference in New Issue
Block a user