Files
puppet-catalog-tools/internal/config/config.go
T
unkin-agent 53007a9257
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was canceled
ci/woodpecker/pr/test Pipeline was canceled
add repo scaffold and the catalog-diff CLI
Compile a host's catalog in a base and a test environment over the
puppetserver API, then diff the two.

- add catalog-diff CLI with cobra flags, config precedence and exit codes
- add puppetserver mTLS client for POST /puppet/v4/catalog
- add pdbmux fact client
- add catalog normalisation, diff engine and text/JSON renderers
- add Makefile, nfpm RPM packaging and woodpecker pipelines
2026-09-12 15:54:25 +10:00

113 lines
3.3 KiB
Go

// Package config loads the shared configuration for the puppet-catalog-tools
// binaries. Precedence (lowest to highest): defaults < config file < env vars
// < CLI flags (applied by the caller).
package config
import (
"fmt"
"os"
"path/filepath"
"gopkg.in/yaml.v3"
)
const (
appName = "puppet-catalog-tools"
configFileName = "config.yaml"
// DefaultServerURL is the k8s OpenVoxServer compiler pool. The legacy VM
// masters behind puppet.query.consul remain reachable via --server.
DefaultServerURL = "https://puppet.k8s.syd1.au.unkin.net:8140"
// DefaultPDBURL is pdbmux, the PuppetDB-compatible merging proxy.
DefaultPDBURL = "https://pdbmux.k8s.syd1.au.unkin.net"
// DefaultBaseEnvironment is the environment branches are diffed against.
DefaultBaseEnvironment = "develop"
)
// Config holds every configurable value. Fields map 1:1 to config file keys.
type Config struct {
ServerURL string `yaml:"server_url"`
PDBURL string `yaml:"pdb_url"`
Cert string `yaml:"cert"`
Key string `yaml:"key"`
CACert string `yaml:"cacert"`
BaseEnvironment string `yaml:"base_environment"`
}
// Default returns the built-in configuration.
func Default() Config {
return Config{
ServerURL: DefaultServerURL,
PDBURL: DefaultPDBURL,
BaseEnvironment: DefaultBaseEnvironment,
}
}
// Dir returns the XDG config directory for these tools.
func Dir() string {
base := os.Getenv("XDG_CONFIG_HOME")
if base == "" {
home, _ := os.UserHomeDir()
base = filepath.Join(home, ".config")
}
return filepath.Join(base, appName)
}
// Path returns the full path to the config file.
func Path() string { return filepath.Join(Dir(), configFileName) }
// Load reads the config file (if present), then applies env var overrides.
func Load() (Config, error) {
cfg := Default()
path := Path()
data, err := os.ReadFile(path)
if err != nil && !os.IsNotExist(err) {
return cfg, fmt.Errorf("reading config %s: %w", path, err)
}
if err == nil {
if err := yaml.Unmarshal(data, &cfg); err != nil {
return cfg, fmt.Errorf("parsing config %s: %w", path, err)
}
}
env := map[string]*string{
"CATALOG_DIFF_SERVER": &cfg.ServerURL,
"CATALOG_DIFF_PDB": &cfg.PDBURL,
"CATALOG_DIFF_CERT": &cfg.Cert,
"CATALOG_DIFF_KEY": &cfg.Key,
"CATALOG_DIFF_CACERT": &cfg.CACert,
"CATALOG_DIFF_BASE_ENVIRONMENT": &cfg.BaseEnvironment,
}
for name, field := range env {
if v := os.Getenv(name); v != "" {
*field = v
}
}
return cfg, nil
}
// WriteDefault creates the config directory and writes a default config file.
// It refuses to overwrite an existing file.
func WriteDefault() (string, error) {
if err := os.MkdirAll(Dir(), 0o755); err != nil {
return "", fmt.Errorf("creating config dir: %w", err)
}
path := Path()
if _, err := os.Stat(path); err == nil {
return "", fmt.Errorf("config already exists at %s", path)
}
data, err := yaml.Marshal(Default())
if err != nil {
return "", err
}
header := "# puppet-catalog-tools configuration\n" +
"# Overridable with CATALOG_DIFF_SERVER, CATALOG_DIFF_PDB, CATALOG_DIFF_CERT,\n" +
"# CATALOG_DIFF_KEY, CATALOG_DIFF_CACERT, CATALOG_DIFF_BASE_ENVIRONMENT.\n\n"
if err := os.WriteFile(path, append([]byte(header), data...), 0o644); err != nil {
return "", fmt.Errorf("writing config: %w", err)
}
return path, nil
}