Files
edgeguard-native/internal/services/configorch/configorch.go
Debian 02096c8ad8 chore(lint): golangci-lint --fix — misspell + staticcheck-Autofixes (Backlog 142→~98)
Erster Schritt des golangci-lint-Rollouts (non-blocking): 44 misspell + 4
staticcheck automatisch behoben (32 Dateien, nur Tippfehler/mechanisch).
build+test grün. Kein Runtime-Change → kein Deploy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 23:25:22 +02:00

79 lines
2.4 KiB
Go

// Package configorch fans Render() out across every per-service
// renderer in a stable order (haproxy → nftables → squid →
// wireguard → unbound). The orchestrator stops on the first hard
// error; ErrNotImplemented stubs are logged but do NOT abort the
// run (squid/wireguard/unbound are stubs in Phase 2).
package configorch
import (
"context"
"errors"
"fmt"
"strings"
"git.netcell-it.de/projekte/edgeguard-native/internal/configgen"
)
type Result struct {
Name string
Skipped bool
Err error
DurationS float64 // populated by callers if they care; orchestrator leaves it 0
}
func (r Result) Status() string {
switch {
case r.Err == nil:
return "ok"
case errors.Is(r.Err, configgen.ErrNotImplemented):
return "skipped (stub)"
default:
return "error: " + r.Err.Error()
}
}
// Run invokes Render on every generator in `gens`, returning a per-
// generator Result slice. Stops on the first hard error so a broken
// HAProxy config doesn't bleed into a partial nftables rewrite.
//
// only: optional whitelist of generator names — empty slice means
// "all". Useful for `render-config --only=haproxy` debugging.
func Run(ctx context.Context, gens []configgen.Generator, only []string) ([]Result, error) {
whitelist := map[string]bool{}
for _, n := range only {
whitelist[n] = true
}
out := make([]Result, 0, len(gens))
var errs []error
for _, g := range gens {
if len(whitelist) > 0 && !whitelist[g.Name()] {
out = append(out, Result{Name: g.Name(), Skipped: true})
continue
}
err := g.Render(ctx)
out = append(out, Result{Name: g.Name(), Err: err})
if err != nil && !errors.Is(err, configgen.ErrNotImplemented) {
// Weitermachen: die Generatoren sind unabhängig und reloaden
// inline (nft/Service-Reload sind atomar). Abbrechen würde die
// restlichen Dienste auf altem Stand lassen → halb angewandt.
// Stattdessen alle versuchen und Fehler gesammelt zurückgeben.
errs = append(errs, fmt.Errorf("%s: %w", g.Name(), err))
}
}
return out, errors.Join(errs...)
}
// Summarize turns the result slice into a human-readable multiline
// string. Used by `edgeguard-ctl render-config` to print to stdout.
func Summarize(results []Result) string {
var b strings.Builder
for _, r := range results {
if r.Skipped {
fmt.Fprintf(&b, " %-10s skipped (filtered)\n", r.Name)
continue
}
fmt.Fprintf(&b, " %-10s %s\n", r.Name, r.Status())
}
return b.String()
}