diff --git a/cmd/edgeguard-api/main.go b/cmd/edgeguard-api/main.go index 50eaf7c..8f28798 100644 --- a/cmd/edgeguard-api/main.go +++ b/cmd/edgeguard-api/main.go @@ -17,54 +17,54 @@ import ( "github.com/gin-gonic/gin" "github.com/jackc/pgx/v5/pgxpool" + "git.netcell-it.de/projekte/edgeguard-native/internal/aggregator" + chronyrender "git.netcell-it.de/projekte/edgeguard-native/internal/chrony" "git.netcell-it.de/projekte/edgeguard-native/internal/cluster" + "git.netcell-it.de/projekte/edgeguard-native/internal/cluster/clustertls" + "git.netcell-it.de/projekte/edgeguard-native/internal/cluster/jointoken" "git.netcell-it.de/projekte/edgeguard-native/internal/database" firewallrender "git.netcell-it.de/projekte/edgeguard-native/internal/firewall" - "git.netcell-it.de/projekte/edgeguard-native/internal/haproxy" - "git.netcell-it.de/projekte/edgeguard-native/internal/handlers" - "git.netcell-it.de/projekte/edgeguard-native/internal/license" - licsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/license" - chronyrender "git.netcell-it.de/projekte/edgeguard-native/internal/chrony" - squidrender "git.netcell-it.de/projekte/edgeguard-native/internal/squid" - unboundrender "git.netcell-it.de/projekte/edgeguard-native/internal/unbound" - wgrender "git.netcell-it.de/projekte/edgeguard-native/internal/wireguard" - kearender "git.netcell-it.de/projekte/edgeguard-native/internal/kea" radiusrender "git.netcell-it.de/projekte/edgeguard-native/internal/freeradius" + "git.netcell-it.de/projekte/edgeguard-native/internal/handlers" "git.netcell-it.de/projekte/edgeguard-native/internal/handlers/response" + "git.netcell-it.de/projekte/edgeguard-native/internal/haproxy" + kearender "git.netcell-it.de/projekte/edgeguard-native/internal/kea" + "git.netcell-it.de/projekte/edgeguard-native/internal/license" "git.netcell-it.de/projekte/edgeguard-native/internal/services/acme" "git.netcell-it.de/projekte/edgeguard-native/internal/services/alerts" + aptsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/apt" "git.netcell-it.de/projekte/edgeguard-native/internal/services/audit" "git.netcell-it.de/projekte/edgeguard-native/internal/services/backends" "git.netcell-it.de/projekte/edgeguard-native/internal/services/backendservers" "git.netcell-it.de/projekte/edgeguard-native/internal/services/backup" backupremote "git.netcell-it.de/projekte/edgeguard-native/internal/services/backup/remote" - dnssvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/dns" - "git.netcell-it.de/projekte/edgeguard-native/internal/aggregator" - "git.netcell-it.de/projekte/edgeguard-native/internal/cluster/clustertls" - "git.netcell-it.de/projekte/edgeguard-native/internal/cluster/jointoken" "git.netcell-it.de/projekte/edgeguard-native/internal/services/clusterjoin" - aptsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/apt" + dhcpsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/dhcp" + dnssvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/dns" "git.netcell-it.de/projekte/edgeguard-native/internal/services/domainheaders" "git.netcell-it.de/projekte/edgeguard-native/internal/services/domains" "git.netcell-it.de/projekte/edgeguard-native/internal/services/firewall" "git.netcell-it.de/projekte/edgeguard-native/internal/services/firewalllog" - "git.netcell-it.de/projekte/edgeguard-native/internal/services/syslogs" "git.netcell-it.de/projekte/edgeguard-native/internal/services/forwardproxy" "git.netcell-it.de/projekte/edgeguard-native/internal/services/ipaddresses" + licsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/license" "git.netcell-it.de/projekte/edgeguard-native/internal/services/networkifs" ntpsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/ntp" - "git.netcell-it.de/projekte/edgeguard-native/internal/services/routingrules" - "git.netcell-it.de/projekte/edgeguard-native/internal/services/secrets" - "git.netcell-it.de/projekte/edgeguard-native/internal/services/staticroutes" - "git.netcell-it.de/projekte/edgeguard-native/internal/services/session" - "git.netcell-it.de/projekte/edgeguard-native/internal/services/setup" - "git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts" - wgsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/wireguard" - dhcpsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/dhcp" oidcsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/oidc" radiussvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/radius" + "git.netcell-it.de/projekte/edgeguard-native/internal/services/routingrules" + "git.netcell-it.de/projekte/edgeguard-native/internal/services/secrets" + "git.netcell-it.de/projekte/edgeguard-native/internal/services/session" + "git.netcell-it.de/projekte/edgeguard-native/internal/services/setup" + "git.netcell-it.de/projekte/edgeguard-native/internal/services/staticroutes" + "git.netcell-it.de/projekte/edgeguard-native/internal/services/syslogs" + "git.netcell-it.de/projekte/edgeguard-native/internal/services/tlscerts" usersvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/users" wafsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/waf" + wgsvc "git.netcell-it.de/projekte/edgeguard-native/internal/services/wireguard" + squidrender "git.netcell-it.de/projekte/edgeguard-native/internal/squid" + unboundrender "git.netcell-it.de/projekte/edgeguard-native/internal/unbound" + wgrender "git.netcell-it.de/projekte/edgeguard-native/internal/wireguard" ) var version = "1.2.35" @@ -287,7 +287,7 @@ func main() { // reload haproxy. Wird in Domains/Backends/RoutingRules-Handler // injiziert, damit jede Änderung ohne expliziten render-config- // Aufruf live geht. Errors werden geloggt, nicht failed - // (Row schon committed, Operator kann manuell re-triggern). + // (Row schon committed, Operator kann manuell re-triggering). // Maintenance-Endpoints brauchen den Reloader — späte Wiring // nachdem haproxyReloader-closure existiert. haproxyReloaderForLater := func(ctx context.Context) error { @@ -296,18 +296,18 @@ func main() { systemHdl.WithMaintenance(setupStore, haproxyReloaderForLater) // Audit-Wiring (Phase Polish): Settings + Auth-Mutationen - // landen jetzt im audit_log. Nodes-id ist die persistente + // landen jetzt im audit_log. Nodes-id ist die persistence // /var/lib/edgeguard/node-id. systemHdl.WithAudit(auditRepo, nodeID) systemHdl.WithDB(pool) systemHdl.WithConfigPreviewers(map[string]func(context.Context) (string, error){ - "haproxy": haproxy.New(pool).RenderToString, - "nftables": firewallrender.New(pool).RenderToString, - "squid": squidrender.New(pool).RenderToString, - "unbound": unboundrender.New(pool).RenderToString, - "chrony": chronyrender.New(pool).RenderToString, - "wireguard": wgrender.New(pool, secretsBox).RenderToString, - }) + "haproxy": haproxy.New(pool).RenderToString, + "nftables": firewallrender.New(pool).RenderToString, + "squid": squidrender.New(pool).RenderToString, + "unbound": unboundrender.New(pool).RenderToString, + "chrony": chronyrender.New(pool).RenderToString, + "wireguard": wgrender.New(pool, secretsBox).RenderToString, + }) setupHdl.WithAudit(auditRepo, nodeID) setupHdl.WithClusterSupport(clusterStore, func(ctx context.Context) error { return firewallrender.New(pool).Render(ctx) @@ -411,7 +411,7 @@ func main() { // services whose state feeds the auto-FW-rule generator (DNS // listen-IPs, Squid ACL count, WG listen-port, NTP serve-clients). // Service-Reload-Errors propagieren; FW-Errors werden nur - // geloggt (DB-Row ist commited, FW kann nachgezogen werden). + // geloggt (DB-Row ist committed, FW kann nachgezogen werden). withFW := func(svc func(context.Context) error) func(context.Context) error { return func(ctx context.Context) error { if err := svc(ctx); err != nil { @@ -449,14 +449,14 @@ func main() { handlers.NewForwardProxyHandler(fwdProxyRepo, auditRepo, nodeID, withFW(squidReloader)).Register(authed) // Unbound DNS reload — re-render edgeguard.conf + restart - // unbound. Listen-IPs triggern Auto-FW-Rule für udp/tcp 53. + // unbound. Listen-IPs triggering Auto-FW-Rule für udp/tcp 53. unboundReloader := func(ctx context.Context) error { return unboundrender.New(pool).Render(ctx) } handlers.NewDNSHandler(dnsRepo, auditRepo, nodeID, withFW(unboundReloader)).Register(authed) // Chrony NTP reload — re-render edgeguard.conf + restart chrony. - // Listen-IPs + serve_clients triggern Auto-FW-Rule für udp/123. + // Listen-IPs + serve_clients triggering Auto-FW-Rule für udp/123. chronyReloader := func(ctx context.Context) error { return chronyrender.New(pool).Render(ctx) } @@ -502,7 +502,7 @@ func main() { // Startup-Render nftables: stellt sicher dass Template-Änderungen // aus einem Update (z.B. neue WireGuard forward-Chain-Auto-Regel) // sofort nach dem API-Restart aktiv werden — ohne dass der - // Operator manuell eine Mutation triggern müsste. nft -f ist + // Operator manuell eine Mutation triggering müsste. nft -f ist // idempotent und atomar; kein Dienst wird neu gestartet. go func() { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) diff --git a/cmd/edgeguard-ctl/render.go b/cmd/edgeguard-ctl/render.go index 2a16bb8..c7403a3 100644 --- a/cmd/edgeguard-ctl/render.go +++ b/cmd/edgeguard-ctl/render.go @@ -8,13 +8,13 @@ import ( "time" "git.netcell-it.de/projekte/edgeguard-native/internal/chrony" - "git.netcell-it.de/projekte/edgeguard-native/internal/freeradius" - "git.netcell-it.de/projekte/edgeguard-native/internal/kea" + "git.netcell-it.de/projekte/edgeguard-native/internal/cluster" "git.netcell-it.de/projekte/edgeguard-native/internal/configgen" "git.netcell-it.de/projekte/edgeguard-native/internal/database" "git.netcell-it.de/projekte/edgeguard-native/internal/firewall" + "git.netcell-it.de/projekte/edgeguard-native/internal/freeradius" "git.netcell-it.de/projekte/edgeguard-native/internal/haproxy" - "git.netcell-it.de/projekte/edgeguard-native/internal/cluster" + "git.netcell-it.de/projekte/edgeguard-native/internal/kea" "git.netcell-it.de/projekte/edgeguard-native/internal/keepalived" "git.netcell-it.de/projekte/edgeguard-native/internal/services/configorch" "git.netcell-it.de/projekte/edgeguard-native/internal/services/secrets" @@ -88,7 +88,7 @@ func cmdRenderConfig(args []string) int { } results, runErr := configorch.Run(ctx, gens, only) - fmt.Print(configorch.Summarise(results)) + fmt.Print(configorch.Summarize(results)) if runErr != nil { fmt.Fprintln(os.Stderr, "render-config aborted:", runErr) return 1 diff --git a/cmd/edgeguard-scheduler/main.go b/cmd/edgeguard-scheduler/main.go index 4e75a65..ea53b44 100644 --- a/cmd/edgeguard-scheduler/main.go +++ b/cmd/edgeguard-scheduler/main.go @@ -129,7 +129,7 @@ const ( // ntpSyncCheckInterval — alle 10 Minuten chronyc tracking aufrufen. // Keine Sync bedeutet: Uhr driftet → TLS-Cert-Prüfung schlägt fehl // wenn die Abweichung > Toleranz des Gegenstücks (i.d.R. ±1 min), - // JWT-Ablauf inkonsistent, Cluster-Split-Brain möglich. Dedupe 1h + // JWT-Ablauf inconsistent, Cluster-Split-Brain möglich. Dedupe 1h // damit ein kurzer Upstream-Ausfall (Reboot, DHCP-Pause) keinen // Alert-Regen produziert. ntpSyncCheckInterval = 10 * time.Minute @@ -140,7 +140,7 @@ const ( // ist der Tunnel effektiv tot — Traffic droht lautlos. Dedupe 30min // pro Tunnel damit schnell wiederhergestellte Tunnels nur einmal feuern. wgTunnelCheckInterval = 5 * time.Minute - wgStaleSec = int64(5 * 60) // 5 Minuten ohne Handshake = tot + wgStaleSec = int64(5 * 60) // 5 Minuten ohne Handshake = tot ) func main() { @@ -241,7 +241,7 @@ func main() { ntpSyncTick := time.NewTicker(ntpSyncCheckInterval) defer ntpSyncTick.Stop() // Kein Initial-Check bei Boot: chrony braucht nach dem Start - // einige Sekunden bis zur ersten Synchronisation — ein + // einige Sekunden bis zur ersten Synchronization — ein // sofortiger Check würde immer feuern. wgTunnelTick := time.NewTicker(wgTunnelCheckInterval) @@ -682,7 +682,10 @@ func runBackendDownCheck(ctx context.Context, pool *pgxpool.Pool, a *alerts.Serv return } - type srvEntry struct{ status string; hasCheck bool } + type srvEntry struct { + status string + hasCheck bool + } byBackend := map[string][]srvEntry{} colIdx := map[string]int{} scanner := bufio.NewScanner(conn) @@ -1071,7 +1074,7 @@ func runRenewer(ctx context.Context, r *certrenewer.Service, a *alerts.Service, _, _ = a.Fire(ctx, "cert.renew_failed", alerts.SeverityError, "Cert-Renewal fehlgeschlagen: "+domain, "Let's Encrypt Erneuerung für "+domain+" ist fehlgeschlagen. "+ - "Prüfe ACME-Konfiguration und DNS-Erreichbarkeit. "+ + "Prüfe ACME-Configuration und DNS-Erreichbarkeit. "+ "Nächster Versuch beim nächsten Renewer-Tick (alle 6h).") } } diff --git a/cmd/edgeguard-waf/main.go b/cmd/edgeguard-waf/main.go index 4f7f121..e7b4453 100644 --- a/cmd/edgeguard-waf/main.go +++ b/cmd/edgeguard-waf/main.go @@ -83,7 +83,7 @@ func main() { slog.Error("waf: SPOE agent stopped", "error", err) os.Exit(1) } - // Graceful shutdown (ctx cancelled): gepufferte Alerts flushen. + // Graceful shutdown (ctx canceled): gepufferte Alerts flushen. alertWriter.Close() } diff --git a/internal/chrony/chrony.go b/internal/chrony/chrony.go index a409ee2..5ebf67e 100644 --- a/internal/chrony/chrony.go +++ b/internal/chrony/chrony.go @@ -121,7 +121,7 @@ func splitCSV(s string) []string { // filterNonLoopback wirft 127.x / ::1 raus — wenn NUR localhost im // listen_addresses ist, lassen wir den bindaddress-Block weg und // chrony bindet auf alle Interfaces (default), was für eine reine -// Client-Konfiguration nicht stört. +// Client-Configuration nicht stört. func filterNonLoopback(in []string) []string { out := []string{} for _, ip := range in { diff --git a/internal/cluster/clustertls/clustertls.go b/internal/cluster/clustertls/clustertls.go index def94ce..ffdbc94 100644 --- a/internal/cluster/clustertls/clustertls.go +++ b/internal/cluster/clustertls/clustertls.go @@ -2,18 +2,19 @@ // für Node-to-Node mTLS-Kommunikation. // // Layout on disk: -// /var/lib/edgeguard/cluster-tls/ca.crt (0644) -// /var/lib/edgeguard/cluster-tls/ca.key (0600, edgeguard:edgeguard) -// /var/lib/edgeguard/cluster-tls/peer.crt (0644) — diese Node -// /var/lib/edgeguard/cluster-tls/peer.key (0600, edgeguard:edgeguard) +// +// /var/lib/edgeguard/cluster-tls/ca.crt (0644) +// /var/lib/edgeguard/cluster-tls/ca.key (0600, edgeguard:edgeguard) +// /var/lib/edgeguard/cluster-tls/peer.crt (0644) — diese Node +// /var/lib/edgeguard/cluster-tls/peer.key (0600, edgeguard:edgeguard) // // Workflow: -// * Erste Node (cluster founder): InitCA generiert CA, dann EnsureSelfSigned +// - Erste Node (cluster founder): InitCA generiert CA, dann EnsureSelfSigned // erstellt + signiert ihren eigenen peer.crt mit eigener CA. -// * Joining Node: lädt CA-Cert vom Primary, generiert lokal CSR, POSTet +// - Joining Node: lädt CA-Cert vom Primary, generiert lokal CSR, POSTet // ihn mit cluster-join-token zu /api/v1/cluster/issue-cert; Primary // signiert via SignCSR und liefert peer.crt zurück. (Phase 3.4.) -// * Single-Node: InitCA + EnsureSelfSigned werden beim API-Boot +// - Single-Node: InitCA + EnsureSelfSigned werden beim API-Boot // idempotent gerufen; Listener auf :8443 kann sofort hochfahren. // // Pattern 1:1 aus mail-gateway/internal/services/clustertls/clustertls.go, @@ -73,8 +74,8 @@ func (s *Store) HasPeer() bool { } // InitCA generiert die Cluster-CA falls noch keine existiert. Idempotent. -// organisation landet im Subject — typischerweise die FQDN-Domain. -func (s *Store) InitCA(organisation string, now func() time.Time) error { +// organization landet im Subject — typischerweise die FQDN-Domain. +func (s *Store) InitCA(organization string, now func() time.Time) error { if s.HasCA() { return nil } @@ -93,7 +94,7 @@ func (s *Store) InitCA(organisation string, now func() time.Time) error { SerialNumber: serial, Subject: pkix.Name{ CommonName: "EdgeGuard Cluster CA", - Organization: []string{organisation}, + Organization: []string{organization}, }, NotBefore: now().UTC(), NotAfter: now().Add(caValidity).UTC(), @@ -325,12 +326,12 @@ func (s *Store) CACertPEM() (string, error) { // CertInfo: zusammengefasste Cert-Metadata für UI-Status. days_remaining // kann negativ sein wenn der Cert schon abgelaufen ist. type CertInfo struct { - CommonName string `json:"common_name"` - NotBefore time.Time `json:"not_before"` - NotAfter time.Time `json:"not_after"` - DaysRemaining int `json:"days_remaining"` - IsCA bool `json:"is_ca"` - SerialHex string `json:"serial_hex"` + CommonName string `json:"common_name"` + NotBefore time.Time `json:"not_before"` + NotAfter time.Time `json:"not_after"` + DaysRemaining int `json:"days_remaining"` + IsCA bool `json:"is_ca"` + SerialHex string `json:"serial_hex"` } // PeerCertInfo liefert die Metadata des eigenen peer.crt. Wenn keiner diff --git a/internal/cluster/local_config.go b/internal/cluster/local_config.go index fdde8a9..a246d9b 100644 --- a/internal/cluster/local_config.go +++ b/internal/cluster/local_config.go @@ -1,7 +1,7 @@ package cluster // /etc/edgeguard/node.conf — node-lokale, NIEMALS zwischen Cluster- -// Peers replizierte Konfiguration. Hält die Identitäts-Werte die jeden +// Peers replizierte Configuration. Hält die Identitäts-Werte die jeden // Node einzigartig machen: // // NODE_ID eindeutige UUID (autogeneriert in EnsureNodeID; hier @@ -91,7 +91,7 @@ func LoadLocalConfig(path string) (*LocalConfig, error) { } // SaveLocalConfig schreibt die Datei atomic + 0644 root:root. -// Aufrufer ist normalerweise edgeguard-ctl unter Operator-Privilegien. +// Aufrufer ist normalerweise edgeguard-ctl unter Operator-Privilege. func SaveLocalConfig(path string, c *LocalConfig) error { if path == "" { path = DefaultLocalConfigPath diff --git a/internal/configgen/configgen.go b/internal/configgen/configgen.go index 254d78d..6865571 100644 --- a/internal/configgen/configgen.go +++ b/internal/configgen/configgen.go @@ -23,7 +23,7 @@ import ( // // Name returns a stable identifier ("haproxy", "nftables", …) // used in CLI output and audit logs. Render does the actual write + -// reload work; ctx may be cancelled (e.g. orchestrator timeout). +// reload work; ctx may be canceled (e.g. orchestrator timeout). type Generator interface { Name() string Render(ctx context.Context) error diff --git a/internal/crowdsec/service.go b/internal/crowdsec/service.go index 805ccfa..df52120 100644 --- a/internal/crowdsec/service.go +++ b/internal/crowdsec/service.go @@ -98,7 +98,7 @@ type HubItem struct { Type string `json:"type,omitempty"` } -// Status summarises the runtime state of the CrowdSec stack on this node. +// Status summarizes the runtime state of the CrowdSec stack on this node. type Status struct { Installed bool `json:"installed"` AgentRunning bool `json:"agent_running"` @@ -362,15 +362,7 @@ func Machines(ctx context.Context) ([]Machine, error) { } result := make([]Machine, len(raw)) for i, r := range raw { - result[i] = Machine{ - MachineID: r.MachineID, - CreatedAt: r.CreatedAt, - UpdatedAt: r.UpdatedAt, - LastPush: r.LastPush, - IsValidated: r.IsValidated, - Version: r.Version, - Status: r.Status, - } + result[i] = Machine(r) } return result, nil } diff --git a/internal/database/migrations_unique_test.go b/internal/database/migrations_unique_test.go index 1304cb1..0b84c07 100644 --- a/internal/database/migrations_unique_test.go +++ b/internal/database/migrations_unique_test.go @@ -8,7 +8,7 @@ import "testing" // startup, the API restart-looped, the cluster rolling-upgrade hung. // // Cheap assertion that runs as part of `go test ./...` — fails the -// build before `make deb` ever produces an artefact, so the bad +// build before `make deb` ever produces an artifact, so the bad // version never reaches the APT registry. Same logic also runs at // service start via Migrate() and via `edgeguard-ctl migrate check` // in postinst (defense in depth). diff --git a/internal/firewall/firewall.go b/internal/firewall/firewall.go index 000764e..7393da2 100644 --- a/internal/firewall/firewall.go +++ b/internal/firewall/firewall.go @@ -8,7 +8,7 @@ // + groups, policy rules, nat rules, ha_nodes peer IPs. // 2. Each rule and nat-rule is "resolved" — group references // replaced with their primitive members, FQDNs left as comments -// (Phase-3 DNS-resolution sidecar will materialise them). +// (Phase-3 DNS-resolution sidecar will materialize them). // 3. The template emits one nft file with: zone-iface sets, peer // sets, default-deny baseline, forward + input chains carrying // the resolved rules (priority-sorted), nat prerouting + @@ -150,12 +150,12 @@ type AutoFWRule struct { Proto string Port int DstIP string - L3 string // "ip"/"ip6" — gesetzt für DstIP-Rules (Familie); leer = agnostisch + L3 string // "ip"/"ip6" — gesetzt für DstIP-Rules (Familie); leer = agnostic Iface string // optional: scope auf ein iifname (z.B. DHCP udp/67 nur auf LAN) Comment string } -// RuleLeg is one materialised nft policy line. +// RuleLeg is one materialized nft policy line. type RuleLeg struct { RuleID int64 Action string @@ -166,7 +166,7 @@ type RuleLeg struct { DstIfaces []string SrcAddrs []string DstAddrs []string - // L3 ist "ip" (IPv4) oder "ip6" (IPv6) für das Adress-Matching — + // L3 ist "ip" (IPv4) oder "ip6" (IPv6) für das Address-Matching — // gesetzt, sobald SrcAddrs/DstAddrs nicht leer sind. Bei adresslosen // Regeln bleibt es "" (familienagnostisch, kein ip/ip6-Match). L3 string @@ -560,7 +560,7 @@ func splitByFamily(exprs []string) (v4, v6 []string) { return v4, v6 } -// serviceL3: icmp ist v4-only, icmpv6 v6-only, tcp/udp/leer agnostisch. +// serviceL3: icmp ist v4-only, icmpv6 v6-only, tcp/udp/leer agnostic. func serviceL3(svc ResolvedService) string { switch svc.Proto { case "icmp": @@ -608,7 +608,7 @@ func expandFamilyLegs(r ResolvedRule, svc ResolvedService, hasSvc bool) []RuleLe } if len(r.SrcAddrs) == 0 && len(r.DstAddrs) == 0 { - // Kein Adress-Match → eine Zeile, L3 leer. Die Proto-Render-Logik + // Kein Address-Match → eine Zeile, L3 leer. Die Proto-Render-Logik // im Template setzt icmp/icmpv6 selbst familienkorrekt. return []RuleLeg{base} } diff --git a/internal/firewall/firewall_ipv6_test.go b/internal/firewall/firewall_ipv6_test.go index 37e9f0d..4b30467 100644 --- a/internal/firewall/firewall_ipv6_test.go +++ b/internal/firewall/firewall_ipv6_test.go @@ -107,7 +107,7 @@ func renderView(t *testing.T) string { Legs: []RuleLeg{ {RuleID: 1, Action: "accept", L3: "ip", SrcAddrs: []string{"10.0.0.0/24"}, Service: ResolvedService{Proto: "tcp", PortStart: 443}}, {RuleID: 1, Action: "accept", L3: "ip6", SrcAddrs: []string{"fd00::/64"}, Service: ResolvedService{Proto: "tcp", PortStart: 443}}, - {RuleID: 2, Action: "accept", Service: ResolvedService{Proto: "icmpv6"}}, // adresslos, agnostisch + {RuleID: 2, Action: "accept", Service: ResolvedService{Proto: "icmpv6"}}, // adresslos, agnostic }, NATRules: []ResolvedNATRule{ {ID: 5, Kind: "dnat", L3: "ip6", DstCIDR: "2001:db8::/64", Proto: "tcp", DPortStart: 80, TargetAddr: "fd00::2", TargetHost: "[fd00::2]", TargetPortStart: 8080}, @@ -126,11 +126,11 @@ func renderView(t *testing.T) string { func TestTemplate_v6AndV4Render(t *testing.T) { out := renderView(t) mustContain := []string{ - "ip saddr { 10.0.0.0/24 }", // v4-Regel unverändert - "ip6 saddr { fd00::/64 }", // v6-Regel - "ip6 daddr 2001:db8::/64", // v6-DNAT-Match - "dnat to [fd00::2]:8080", // v6-DNAT-Target geklammert - "dnat to 10.0.0.5:80", // v4-DNAT-Target unverändert + "ip saddr { 10.0.0.0/24 }", // v4-Regel unverändert + "ip6 saddr { fd00::/64 }", // v6-Regel + "ip6 daddr 2001:db8::/64", // v6-DNAT-Match + "dnat to [fd00::2]:8080", // v6-DNAT-Target geklammert + "dnat to 10.0.0.5:80", // v4-DNAT-Target unverändert "ip6 saddr fd00::/64 snat to 2001:db8::99", `oifname "wg7" ip6 saddr fd00:99::/64 masquerade`, } diff --git a/internal/handlers/cluster.go b/internal/handlers/cluster.go index f58eca4..d612322 100644 --- a/internal/handlers/cluster.go +++ b/internal/handlers/cluster.go @@ -35,7 +35,7 @@ type ClusterHandler struct { Store *cluster.Store LocalID string Aggregator *aggregator.Aggregator - Version string // laufende Binary-Version, für Rolling-Update-Koordination + Version string // laufende Binary-Version, für Rolling-Update-Coordination // TLSStore + Tokens: optional, gesetzt bei Phase 3.4. Erlauben das // Generieren von Join-Tokens und das Issue-Cert für joining Peers. @@ -56,7 +56,7 @@ func NewClusterHandler(store *cluster.Store, localID string) *ClusterHandler { return &ClusterHandler{Store: store, LocalID: localID} } -// WithAggregator: optionale Aggregator-Konfiguration. Nur wenn vorhanden +// WithAggregator: optionale Aggregator-Configuration. Nur wenn vorhanden // wird /cluster/system/load die Peers via mTLS abklappern. func (h *ClusterHandler) WithAggregator(a *aggregator.Aggregator) *ClusterHandler { h.Aggregator = a @@ -104,7 +104,7 @@ func (h *ClusterHandler) Register(rg *gin.RouterGroup) { // DeleteNode entfernt einen Peer aus ha_nodes. Verweigert für die // lokale Node (LocalID) — die kannst du nicht via UI löschen, sonst // kommt der nächste Heartbeat-Tick die Row wieder anlegen oder -// die Cluster-Page wird inkonsistent. +// die Cluster-Page wird inconsistent. // // Nach erfolgreichem Delete triggert der PeerReloader (falls gesetzt) // einen Firewall-Render — peer_ipv4-Set verliert die IP, der entfernte @@ -159,7 +159,7 @@ func (h *ClusterHandler) GetVIPSettings(c *gin.Context) { response.OK(c, cs) } -// UpdateVIPSettings speichert die VIP/VRRP-Konfiguration und triggert +// UpdateVIPSettings speichert die VIP/VRRP-Configuration und triggert // einen Keepalived-Config-Render. Viewer-Schutz via RequireAdminForMutations- // Middleware auf der authed-Group — kein Extra-Check nötig. func (h *ClusterHandler) UpdateVIPSettings(c *gin.Context) { @@ -338,7 +338,7 @@ func (h *ClusterHandler) WithPeerReloader(r PeerReloader) *ClusterHandler { return h } -// WithVersion: setzt die laufende Binary-Version für Rolling-Update-Koordination. +// WithVersion: setzt die laufende Binary-Version für Rolling-Update-Coordination. func (h *ClusterHandler) WithVersion(v string) *ClusterHandler { h.Version = v return h @@ -359,7 +359,7 @@ type ClusterStatus struct { LocalID string `json:"local_id"` LocalNode *models.HANode `json:"local_node,omitempty"` Peers []models.HANode `json:"peers"` - Mode string `json:"mode"` // "single-node" | "cluster" + Mode string `json:"mode"` // "single-node" | "cluster" Health string `json:"health"` // "ok" | "degraded" | "split-brain" DriftFound bool `json:"drift_found"` UpdatedAt time.Time `json:"updated_at"` @@ -822,7 +822,7 @@ func (h *ClusterHandler) CertStatus(c *gin.Context) { // // Nach Renew muss edgeguard-api restartet werden damit der Agent- // Listener das neue Cert in seinen TLS-Config-Snapshot lädt — wir -// triggern das NICHT automatisch (würde die HTTP-Response abreißen); +// triggering das NICHT automatisch (würde die HTTP-Response abreißen); // stattdessen liefern wir einen Hinweis im Response. func (h *ClusterHandler) RenewSelf(c *gin.Context) { if !h.TLSStore.HasCA() { @@ -857,16 +857,16 @@ func (h *ClusterHandler) RenewSelf(c *gin.Context) { // die wir wirklich brauchen — sonst kann ein joining Peer beliebige // ha_nodes-Felder überschreiben. type registerPeerRequest struct { - ID string `json:"id"` // Joiner's eigene node-id - Name string `json:"name"` // hostname - FQDN string `json:"fqdn"` // sollte mit Client-Cert-CN matchen - APIURL string `json:"api_url"` // https:// - PublicIP string `json:"public_ip"` // optional - InternalIP string `json:"internal_ip"` // mTLS-Listener-IP (für peer_ipv4-Set) - MgmtIP string `json:"mgmt_ip"` // optional + ID string `json:"id"` // Joiner's eigene node-id + Name string `json:"name"` // hostname + FQDN string `json:"fqdn"` // sollte mit Client-Cert-CN matchen + APIURL string `json:"api_url"` // https:// + PublicIP string `json:"public_ip"` // optional + InternalIP string `json:"internal_ip"` // mTLS-Listener-IP (für peer_ipv4-Set) + MgmtIP string `json:"mgmt_ip"` // optional Version string `json:"version"` - ConfigHash *string `json:"config_hash"` // nil=absent (don't change), ""=no user config - Role string `json:"role"` // "" → "peer" (joining peer); "primary" beim Push des Primary + ConfigHash *string `json:"config_hash"` // nil=absent (don't change), ""=no user config + Role string `json:"role"` // "" → "peer" (joining peer); "primary" beim Push des Primary } // AgentRegisterPeer: vom Joiner nach issue-cert via mTLS aufgerufen. diff --git a/internal/handlers/cluster_rollingupdate.go b/internal/handlers/cluster_rollingupdate.go index c1bb720..23d130e 100644 --- a/internal/handlers/cluster_rollingupdate.go +++ b/internal/handlers/cluster_rollingupdate.go @@ -177,7 +177,7 @@ func (h *ClusterHandler) runRollingUpdate(secondary *models.HANode) { slog.Info("rolling-update: secondary already at target — skipping secondary step", "version", candidate) } else { - // 1. Secondary triggern + // 1. Secondary triggering slog.Info("rolling-update: posting trigger-update to secondary", "fqdn", secondary.FQDN) result := h.Aggregator.PostPeer(ctx, *secondary, "/agent/cluster/trigger-update") if !result.OK { diff --git a/internal/handlers/firewall.go b/internal/handlers/firewall.go index 37edb97..7a6664c 100644 --- a/internal/handlers/firewall.go +++ b/internal/handlers/firewall.go @@ -22,7 +22,7 @@ import ( // FirewallHandler exposes everything under /api/v1/firewall/*: // -// address-objects — primitive Adress-Definitionen (host/network/range/fqdn) +// address-objects — primitive Address-Definitionen (host/network/range/fqdn) // address-groups — Gruppen von address-objects (mit /members ops) // services — proto+port (Builtins lassen sich nicht editieren) // service-groups — Gruppen von services @@ -271,7 +271,7 @@ func zoneNamePattern(s string) bool { if s == "" || len(s) > 32 { return false } - if !(s[0] >= 'a' && s[0] <= 'z') { + if s[0] < 'a' || s[0] > 'z' { return false } for i := 1; i < len(s); i++ { @@ -352,7 +352,8 @@ func (h *FirewallHandler) CreateAddrObj(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.addr_obj.create", req.Name, out, h.NodeID) - response.Created(c, out); h.reload(c.Request.Context(), "create") + response.Created(c, out) + h.reload(c.Request.Context(), "create") } func (h *FirewallHandler) UpdateAddrObj(c *gin.Context) { @@ -379,7 +380,8 @@ func (h *FirewallHandler) UpdateAddrObj(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.addr_obj.update", req.Name, out, h.NodeID) - response.OK(c, out); h.reload(c.Request.Context(), "update") + response.OK(c, out) + h.reload(c.Request.Context(), "update") } func (h *FirewallHandler) DeleteAddrObj(c *gin.Context) { @@ -397,7 +399,8 @@ func (h *FirewallHandler) DeleteAddrObj(c *gin.Context) { } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.addr_obj.delete", strconv.FormatInt(id, 10), gin.H{"id": id}, h.NodeID) - response.NoContent(c); h.reload(c.Request.Context(), "delete") + response.NoContent(c) + h.reload(c.Request.Context(), "delete") } // ── Address Groups ───────────────────────────────────────────────────── @@ -440,7 +443,8 @@ func (h *FirewallHandler) CreateAddrGrp(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.addr_grp.create", req.Name, out, h.NodeID) - response.Created(c, out); h.reload(c.Request.Context(), "create") + response.Created(c, out) + h.reload(c.Request.Context(), "create") } func (h *FirewallHandler) UpdateAddrGrp(c *gin.Context) { @@ -463,7 +467,8 @@ func (h *FirewallHandler) UpdateAddrGrp(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.addr_grp.update", req.Name, out, h.NodeID) - response.OK(c, out); h.reload(c.Request.Context(), "update") + response.OK(c, out) + h.reload(c.Request.Context(), "update") } func (h *FirewallHandler) DeleteAddrGrp(c *gin.Context) { @@ -481,7 +486,8 @@ func (h *FirewallHandler) DeleteAddrGrp(c *gin.Context) { } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.addr_grp.delete", strconv.FormatInt(id, 10), gin.H{"id": id}, h.NodeID) - response.NoContent(c); h.reload(c.Request.Context(), "delete") + response.NoContent(c) + h.reload(c.Request.Context(), "delete") } // ── Services ─────────────────────────────────────────────────────────── @@ -524,7 +530,8 @@ func (h *FirewallHandler) CreateService(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.service.create", req.Name, out, h.NodeID) - response.Created(c, out); h.reload(c.Request.Context(), "create") + response.Created(c, out) + h.reload(c.Request.Context(), "create") } func (h *FirewallHandler) UpdateService(c *gin.Context) { @@ -547,7 +554,8 @@ func (h *FirewallHandler) UpdateService(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.service.update", req.Name, out, h.NodeID) - response.OK(c, out); h.reload(c.Request.Context(), "update") + response.OK(c, out) + h.reload(c.Request.Context(), "update") } func (h *FirewallHandler) DeleteService(c *gin.Context) { @@ -565,7 +573,8 @@ func (h *FirewallHandler) DeleteService(c *gin.Context) { } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.service.delete", strconv.FormatInt(id, 10), gin.H{"id": id}, h.NodeID) - response.NoContent(c); h.reload(c.Request.Context(), "delete") + response.NoContent(c) + h.reload(c.Request.Context(), "delete") } // ── Service Groups ───────────────────────────────────────────────────── @@ -608,7 +617,8 @@ func (h *FirewallHandler) CreateSvcGrp(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.svc_grp.create", req.Name, out, h.NodeID) - response.Created(c, out); h.reload(c.Request.Context(), "create") + response.Created(c, out) + h.reload(c.Request.Context(), "create") } func (h *FirewallHandler) UpdateSvcGrp(c *gin.Context) { @@ -631,7 +641,8 @@ func (h *FirewallHandler) UpdateSvcGrp(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.svc_grp.update", req.Name, out, h.NodeID) - response.OK(c, out); h.reload(c.Request.Context(), "update") + response.OK(c, out) + h.reload(c.Request.Context(), "update") } func (h *FirewallHandler) DeleteSvcGrp(c *gin.Context) { @@ -649,7 +660,8 @@ func (h *FirewallHandler) DeleteSvcGrp(c *gin.Context) { } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.svc_grp.delete", strconv.FormatInt(id, 10), gin.H{"id": id}, h.NodeID) - response.NoContent(c); h.reload(c.Request.Context(), "delete") + response.NoContent(c) + h.reload(c.Request.Context(), "delete") } // ── Rules ────────────────────────────────────────────────────────────── @@ -704,7 +716,8 @@ func (h *FirewallHandler) CreateRule(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.rule.create", strconv.FormatInt(out.ID, 10), out, h.NodeID) - response.Created(c, out); h.reload(c.Request.Context(), "create") + response.Created(c, out) + h.reload(c.Request.Context(), "create") } func (h *FirewallHandler) UpdateRule(c *gin.Context) { @@ -739,7 +752,8 @@ func (h *FirewallHandler) UpdateRule(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.rule.update", strconv.FormatInt(id, 10), out, h.NodeID) - response.OK(c, out); h.reload(c.Request.Context(), "update") + response.OK(c, out) + h.reload(c.Request.Context(), "update") } func (h *FirewallHandler) DeleteRule(c *gin.Context) { @@ -757,7 +771,8 @@ func (h *FirewallHandler) DeleteRule(c *gin.Context) { } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.rule.delete", strconv.FormatInt(id, 10), gin.H{"id": id}, h.NodeID) - response.NoContent(c); h.reload(c.Request.Context(), "delete") + response.NoContent(c) + h.reload(c.Request.Context(), "delete") } func (h *FirewallHandler) PatchRule(c *gin.Context) { @@ -850,7 +865,8 @@ func (h *FirewallHandler) CreateNAT(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.nat.create", strconv.FormatInt(out.ID, 10), out, h.NodeID) - response.Created(c, out); h.reload(c.Request.Context(), "create") + response.Created(c, out) + h.reload(c.Request.Context(), "create") } func (h *FirewallHandler) UpdateNAT(c *gin.Context) { @@ -881,7 +897,8 @@ func (h *FirewallHandler) UpdateNAT(c *gin.Context) { return } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.nat.update", strconv.FormatInt(id, 10), out, h.NodeID) - response.OK(c, out); h.reload(c.Request.Context(), "update") + response.OK(c, out) + h.reload(c.Request.Context(), "update") } func (h *FirewallHandler) DeleteNAT(c *gin.Context) { @@ -899,7 +916,8 @@ func (h *FirewallHandler) DeleteNAT(c *gin.Context) { } _ = h.Audit.Log(c.Request.Context(), actorOf(c), "fw.nat.delete", strconv.FormatInt(id, 10), gin.H{"id": id}, h.NodeID) - response.NoContent(c); h.reload(c.Request.Context(), "delete") + response.NoContent(c) + h.reload(c.Request.Context(), "delete") } func (h *FirewallHandler) PatchNAT(c *gin.Context) { diff --git a/internal/handlers/system.go b/internal/handlers/system.go index a1ac24a..0d3a84a 100644 --- a/internal/handlers/system.go +++ b/internal/handlers/system.go @@ -132,7 +132,7 @@ func (h *SystemHandler) Register(rg *gin.RouterGroup) { // Ergebnis für /cluster/system/load. // // Bewusst KEINE Mutations + KEIN /package-versions (würde apt-get update -// auf jedem Peer triggern), KEIN /upgrade. +// auf jedem Peer triggering), KEIN /upgrade. func (h *SystemHandler) RegisterAgent(rg *gin.RouterGroup) { g := rg.Group("/agent/system") g.GET("/health", h.Health) @@ -206,7 +206,7 @@ type serviceStatus struct { Label string `json:"label"` Unit string `json:"unit"` Active bool `json:"active"` - State string `json:"state"` // active|inactive|failed|activating|... + State string `json:"state"` // active|inactive|failed|activating|... Since string `json:"since,omitempty"` // ActiveEnterTimestamp } @@ -378,7 +378,7 @@ func (h *SystemHandler) Maintenance(c *gin.Context) { func (h *SystemHandler) ToggleMaintenance(c *gin.Context) { if h.Setup == nil { response.Err(c, http.StatusServiceUnavailable, - simpleErr("setup not initialised")) + simpleErr("setup not initialized")) return } var req struct { @@ -430,7 +430,7 @@ func (h *SystemHandler) BackupRetention(c *gin.Context) { // keep=0 → wieder Default, keep=1..365 → custom. func (h *SystemHandler) SetBackupRetention(c *gin.Context) { if h.Setup == nil { - response.Err(c, http.StatusServiceUnavailable, simpleErr("setup not initialised")) + response.Err(c, http.StatusServiceUnavailable, simpleErr("setup not initialized")) return } var req struct { @@ -466,7 +466,7 @@ func (h *SystemHandler) AuditRetention(c *gin.Context) { // SetAuditRetention setzt Audit-Retention in Tagen. 0..3650. func (h *SystemHandler) SetAuditRetention(c *gin.Context) { if h.Setup == nil { - response.Err(c, http.StatusServiceUnavailable, simpleErr("setup not initialised")) + response.Err(c, http.StatusServiceUnavailable, simpleErr("setup not initialized")) return } var req struct { @@ -513,7 +513,7 @@ func (h *SystemHandler) IPv6(c *gin.Context) { func (h *SystemHandler) SetIPv6(c *gin.Context) { if h.Setup == nil { - response.Err(c, http.StatusServiceUnavailable, simpleErr("setup not initialised")) + response.Err(c, http.StatusServiceUnavailable, simpleErr("setup not initialized")) return } var req struct { @@ -582,7 +582,7 @@ LIMIT 10`) // HAProxyReload zwingt ein systemctl reload haproxy.service — nützlich // wenn der Operator manuell in /etc/edgeguard/tls/ geschrieben hat // (z. B. eigenes PEM per SSH kopiert) und HAProxy das neue Cert sehen -// soll, ohne eine UI-Mutation zu triggern die das automatisch täte. +// soll, ohne eine UI-Mutation zu triggering die das automatisch täte. func (h *SystemHandler) HAProxyReload(c *gin.Context) { out, err := exec.Command("sudo", "-n", "/usr/bin/systemctl", "reload", "haproxy.service").CombinedOutput() if err != nil { @@ -600,12 +600,12 @@ func (h *SystemHandler) HAProxyReload(c *gin.Context) { // starten darf. edgeguard-api selbst ist bewusst ausgeschlossen (würde // die eigene HTTP-Response killen). postgresql ebenfalls (Datenpfad). var restartAllowlist = map[string]bool{ - "haproxy": true, - "squid": true, - "unbound": true, - "chrony": true, - "nftables": true, - "wireguard": true, // wireguard als Metadienst; einzelne wg-Ifaces über wg-quick@ + "haproxy": true, + "squid": true, + "unbound": true, + "chrony": true, + "nftables": true, + "wireguard": true, // wireguard als Metadienst; einzelne wg-Ifaces über wg-quick@ "edgeguard-scheduler": true, } @@ -920,7 +920,7 @@ func (h *SystemHandler) Upgrade(c *gin.Context) { // beiden Namespaces aus zugänglich. const scriptPath = "/var/lib/edgeguard/upgrade.sh" // Retry-Logik gegen Gitea-Packages.gz-Race: nach einem frischen - // Publish kann der Packages-Index für ein paar Sekunden inkonsistent + // Publish kann der Packages-Index für ein paar Sekunden inconsistent // sein (z. B. Meta uploaded, api/ui noch nicht in der regenerierten // Index-Datei) → apt-resolver-fail mit "no choices are installable". // Drei Versuche mit 15s/30s Backoff geben Gitea Zeit den Index @@ -1235,4 +1235,3 @@ func flagsToList(f net.Flags) []string { } return out } - diff --git a/internal/kea/kea.go b/internal/kea/kea.go index f5563dd..0bb0192 100644 --- a/internal/kea/kea.go +++ b/internal/kea/kea.go @@ -1,7 +1,7 @@ // Package kea renders the Kea DHCPv4 server config from the dhcp_* // tables and manages the kea-dhcp4-server service lifecycle. // -// The config is built as a Go struct and json-marshalled (NOT a text +// The config is built as a Go struct and json-marshaled (NOT a text // template) so the output is always syntactically valid JSON. Managed // at /etc/edgeguard/kea/kea-dhcp4.conf (edgeguard-owned); postinst // symlinks /etc/kea/kea-dhcp4.conf to it. diff --git a/internal/keepalived/keepalived_test.go b/internal/keepalived/keepalived_test.go index 767cf74..4561528 100644 --- a/internal/keepalived/keepalived_test.go +++ b/internal/keepalived/keepalived_test.go @@ -43,7 +43,7 @@ func TestTemplateNopreemptOnBothInstances(t *testing.T) { } } -// GARP muss forciert + periodisch aufgefrischt werden, sonst altert die +// GARP muss forciert + periodic aufgefrischt werden, sonst altert die // VIP-MAC am Upstream-Switch und die Failover-IP wird unerreichbar. func TestTemplateGARPRefresh(t *testing.T) { out := render(t, testView()) diff --git a/internal/models/cluster_settings.go b/internal/models/cluster_settings.go index 4d14eee..fc7d82e 100644 --- a/internal/models/cluster_settings.go +++ b/internal/models/cluster_settings.go @@ -3,7 +3,7 @@ package models import "time" // ClusterSettings ist die Singleton-Tabelle (id=1) für VIP/VRRP- -// und Replikations-Konfiguration. Angelegt in Migration 0029. +// und Replikations-Configuration. Angelegt in Migration 0029. // hb_* = zweite VRRP-Instanz für Split-Brain-Schutz (0033). // gw_check_ip = Gateway-IP für vrrp_script chk_gateway (0033). type ClusterSettings struct { diff --git a/internal/models/dhcp.go b/internal/models/dhcp.go index 8f2398f..ea36bff 100644 --- a/internal/models/dhcp.go +++ b/internal/models/dhcp.go @@ -2,7 +2,7 @@ package models import "time" -// DHCPSettings ist die node-lokale Singleton-Konfiguration des Kea-DHCPv4- +// DHCPSettings ist die node-lokale Singleton-Configuration des Kea-DHCPv4- // Servers (ob diese Node DHCP betreibt + globale Defaults). type DHCPSettings struct { ID int `gorm:"column:id;primaryKey" json:"id"` diff --git a/internal/models/oidc_settings.go b/internal/models/oidc_settings.go index 98c11de..830acde 100644 --- a/internal/models/oidc_settings.go +++ b/internal/models/oidc_settings.go @@ -2,7 +2,7 @@ package models import "time" -// OIDCSettings ist die Singleton-Konfiguration für OIDC/Keycloak-SSO. +// OIDCSettings ist die Singleton-Configuration für OIDC/Keycloak-SSO. // ClientSecretEnc trägt den verschlüsselten Client-Secret (secrets.Box) // und wird NIE serialisiert (json:"-"). type OIDCSettings struct { diff --git a/internal/models/radius.go b/internal/models/radius.go index a6b7460..ff649c1 100644 --- a/internal/models/radius.go +++ b/internal/models/radius.go @@ -2,7 +2,7 @@ package models import "time" -// RADIUSSettings ist die node-lokale Singleton-Konfiguration des +// RADIUSSettings ist die node-lokale Singleton-Configuration des // FreeRADIUS-Servers (ob diese Node RADIUS betreibt + Listen-Adressen). type RADIUSSettings struct { ID int `gorm:"column:id;primaryKey" json:"id"` diff --git a/internal/models/wireguard.go b/internal/models/wireguard.go index 0c5a9f7..bfa0782 100644 --- a/internal/models/wireguard.go +++ b/internal/models/wireguard.go @@ -26,7 +26,7 @@ type WireguardInterface struct { UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` // PrivateKeyEnc / PeerPSKEnc are loaded from the DB as raw bytes - // — handler never serialises them. JSON tag uses '-' so they + // — handler never serializes them. JSON tag uses '-' so they // don't leak into responses if a developer accidentally returns // the model directly. PrivateKeyEnc []byte `gorm:"column:private_key_enc" json:"-"` diff --git a/internal/services/apt/apt.go b/internal/services/apt/apt.go index 53ef08f..79b78f3 100644 --- a/internal/services/apt/apt.go +++ b/internal/services/apt/apt.go @@ -110,7 +110,7 @@ func refreshInternal(ctx context.Context, force bool) { } // StartBackgroundRefresh: Fire-and-Forget-Goroutine die einmal beim -// Start + dann periodisch apt-get update fährt, damit der Apt-Cache +// Start + dann periodic apt-get update fährt, damit der Apt-Cache // auch ohne UI-Traffic frisch bleibt. So zeigt der Banner kurz nach // `make publish` ein verfügbares Update, statt 5 min auf die nächste // UI-Poll-Welle zu warten. diff --git a/internal/services/configorch/configorch.go b/internal/services/configorch/configorch.go index 424fc8c..fd0a5ea 100644 --- a/internal/services/configorch/configorch.go +++ b/internal/services/configorch/configorch.go @@ -63,9 +63,9 @@ func Run(ctx context.Context, gens []configgen.Generator, only []string) ([]Resu return out, errors.Join(errs...) } -// Summarise turns the result slice into a human-readable multiline +// Summarize turns the result slice into a human-readable multiline // string. Used by `edgeguard-ctl render-config` to print to stdout. -func Summarise(results []Result) string { +func Summarize(results []Result) string { var b strings.Builder for _, r := range results { if r.Skipped { diff --git a/internal/services/diagnostics/diagnostics.go b/internal/services/diagnostics/diagnostics.go index 230b6d0..c626563 100644 --- a/internal/services/diagnostics/diagnostics.go +++ b/internal/services/diagnostics/diagnostics.go @@ -34,7 +34,7 @@ type Result struct { Took time.Duration `json:"-"` } -// validTarget ist eine konservative Erlaubnis: Buchstaben, Ziffern, +// validTarget ist eine conservative Erlaubnis: Buchstaben, Ziffern, // Punkt, Doppelpunkt (IPv6), Schrägstrich (Pfade in curl-URLs), Bindestrich, // Unterstrich. Whitespace, $, `, `;`, `&`, `|`, `>` etc. werden gesperrt. func validTarget(s string, max int) error { diff --git a/internal/services/oidc/client.go b/internal/services/oidc/client.go index c3a9a3a..5cb9e85 100644 --- a/internal/services/oidc/client.go +++ b/internal/services/oidc/client.go @@ -23,7 +23,7 @@ type Claims struct { } // Authenticator ist der testbare Seam: Aufbau der Auth-URL und der -// Code-Exchange inkl. ID-Token-Verifikation + Claim-Extraktion. Der +// Code-Exchange inkl. ID-Token-Verification + Claim-Extraktion. Der // Handler hängt nur hieran, sodass Tests einen Fake injizieren können. type Authenticator interface { // AuthCodeURL baut die Redirect-URL zum IdP (state + nonce + PKCE-Challenge). diff --git a/internal/services/oidc/settings.go b/internal/services/oidc/settings.go index 00f8ee3..f8a8e9d 100644 --- a/internal/services/oidc/settings.go +++ b/internal/services/oidc/settings.go @@ -1,4 +1,4 @@ -// Package oidc kapselt die OIDC/Keycloak-SSO-Konfiguration (Singleton- +// Package oidc kapselt die OIDC/Keycloak-SSO-Configuration (Singleton- // Settings + verschlüsseltes Client-Secret) und einen lazy aufgebauten // OIDC-Provider/Verifier. Login-Flow-State ist stateless (signiertes // Cookie im Handler), daher hält dieses Paket keinen Request-State. diff --git a/internal/services/secrets/secrets.go b/internal/services/secrets/secrets.go index da9e7b8..9425f3e 100644 --- a/internal/services/secrets/secrets.go +++ b/internal/services/secrets/secrets.go @@ -29,7 +29,7 @@ const masterKeyLen = 32 const DefaultMasterKeyPath = "/var/lib/edgeguard/.master_key" // Box uses AES-256-GCM with a static master key to seal/unseal -// values. Concurrency-safe; the cipher is initialised once. +// values. Concurrency-safe; the cipher is initialized once. type Box struct { once sync.Once aead cipher.AEAD diff --git a/internal/services/wireguard/import.go b/internal/services/wireguard/import.go index 67d96a9..c1b9aae 100644 --- a/internal/services/wireguard/import.go +++ b/internal/services/wireguard/import.go @@ -15,12 +15,12 @@ import ( "git.netcell-it.de/projekte/edgeguard-native/internal/services/secrets" ) -// ImportResult summarises what an Import call did so the CLI can +// ImportResult summarizes what an Import call did so the CLI can // report it back to the operator. type ImportResult struct { - IfacesAdded int `json:"ifaces_added"` - PeersAdded int `json:"peers_added"` - Skipped []string `json:"skipped,omitempty"` // ifaces already present, with reason + IfacesAdded int `json:"ifaces_added"` + PeersAdded int `json:"peers_added"` + Skipped []string `json:"skipped,omitempty"` // ifaces already present, with reason } // Importer takes existing /etc/wireguard/*.conf files and translates diff --git a/internal/waf/engine.go b/internal/waf/engine.go index bb84479..305925a 100644 --- a/internal/waf/engine.go +++ b/internal/waf/engine.go @@ -36,10 +36,10 @@ func buildDirectives(cfg models.WafConfig, crsDir string) string { sb.WriteString("SecRequestBodyAccess On\n") sb.WriteString("SecResponseBodyAccess Off\n") - sb.WriteString("SecRequestBodyLimit 13107200\n") // 12.5 MB + sb.WriteString("SecRequestBodyLimit 13107200\n") // 12.5 MB sb.WriteString("SecRequestBodyInMemoryLimit 131072\n") // 128 KB - sb.WriteString(fmt.Sprintf("SecRuleEngine %s\n", ruleEngineMode(cfg.Mode))) + fmt.Fprintf(&sb, "SecRuleEngine %s\n", ruleEngineMode(cfg.Mode)) if crsDir != "" && crsAvailable(crsDir) { // Paranoia level MUST be set before CRS rules are included. @@ -47,22 +47,20 @@ func buildDirectives(cfg models.WafConfig, crsDir string) string { if pl < 1 || pl > 4 { pl = 1 } - sb.WriteString(fmt.Sprintf( - "SecAction \"id:900000,phase:1,nolog,pass,t:none,setvar:tx.paranoia_level=%d\"\n", pl, - )) + fmt.Fprintf(&sb, "SecAction \"id:900000,phase:1,nolog,pass,t:none,setvar:tx.paranoia_level=%d\"\n", pl) setupConf := filepath.Join(crsDir, "crs-setup.conf") if _, err := os.Stat(setupConf); err == nil { - sb.WriteString(fmt.Sprintf("Include %s\n", setupConf)) + fmt.Fprintf(&sb, "Include %s\n", setupConf) } rulesGlob := filepath.Join(crsDir, "rules", "*.conf") - sb.WriteString(fmt.Sprintf("Include %s\n", rulesGlob)) + fmt.Fprintf(&sb, "Include %s\n", rulesGlob) } // Rule exclusions (applied after CRS load so they override CRS). for _, id := range cfg.RuleExclusions { id = strings.TrimSpace(id) if id != "" { - sb.WriteString(fmt.Sprintf("SecRuleRemoveById %s\n", id)) + fmt.Fprintf(&sb, "SecRuleRemoveById %s\n", id) } } diff --git a/internal/waf/spoe.go b/internal/waf/spoe.go index 32c2bd6..b583103 100644 --- a/internal/waf/spoe.go +++ b/internal/waf/spoe.go @@ -15,12 +15,12 @@ import ( // SPOEAgent wraps the haproxy-go SPOE server and dispatches each // inspected request to the appropriate per-domain Coraza engine. type SPOEAgent struct { - Manager *Manager - AlertWriter *AlertWriter - Addr string + Manager *Manager + AlertWriter *AlertWriter + Addr string } -// ListenAndServe starts the SPOE agent. Blocks until ctx is cancelled. +// ListenAndServe starts the SPOE agent. Blocks until ctx is canceled. func (a *SPOEAgent) ListenAndServe(ctx context.Context) error { agent := spop.Agent{ Addr: a.Addr,