Sanitize duplicate allowed_nodes blocks

This commit is contained in:
rcourtman 2025-11-18 19:33:26 +00:00
parent 2e7f693c8b
commit 936894a5fe
2 changed files with 100 additions and 0 deletions

View file

@ -6,6 +6,7 @@ import (
"fmt"
"net"
"os"
"regexp"
"strconv"
"strings"
"time"
@ -85,6 +86,10 @@ func loadConfig(configPath string) (*Config, error) {
return nil, fmt.Errorf("failed to read config file: %w", err)
}
if sanitized, newData := sanitizeDuplicateAllowedNodesBlocks(configPath, data); sanitized {
data = newData
}
if err := yaml.Unmarshal(data, cfg); err != nil {
return nil, fmt.Errorf("failed to parse config file: %w", err)
}
@ -518,6 +523,49 @@ func detectHostCIDRs() []string {
return cidrs
}
var allowedNodesBlockPattern = regexp.MustCompile(`(?m)(?:^[ \t]*#.*\n)*^[ \t]*allowed_nodes:\n(?:^[ \t]+-.*\n?)+`)
func sanitizeDuplicateAllowedNodesBlocks(path string, data []byte) (bool, []byte) {
matches := allowedNodesBlockPattern.FindAllIndex(data, -1)
if len(matches) <= 1 {
return false, data
}
var buf bytes.Buffer
last := 0
for idx, match := range matches {
start, end := match[0], match[1]
if idx == 0 {
buf.Write(data[last:end])
} else {
buf.Write(data[last:start])
}
last = end
}
buf.Write(data[last:])
cleaned := buf.Bytes()
if path != "" {
if err := os.WriteFile(path, cleaned, 0600); err != nil {
log.Warn().
Err(err).
Str("config_file", path).
Msg("Failed to rewrite sanitized configuration; using in-memory copy only")
} else {
log.Warn().
Str("config_file", path).
Int("removed_duplicate_blocks", len(matches)-1).
Msg("Detected duplicate allowed_nodes blocks and sanitized configuration automatically")
}
} else {
log.Warn().
Int("removed_duplicate_blocks", len(matches)-1).
Msg("Detected duplicate allowed_nodes blocks and sanitized configuration (in-memory only)")
}
return true, cleaned
}
// parseAllowedSubnets validates and normalizes subnet specifications
func parseAllowedSubnets(cfg []string) ([]string, error) {
seen := make(map[string]struct{})

View file

@ -0,0 +1,52 @@
package main
import (
"strings"
"testing"
)
func TestSanitizeDuplicateAllowedNodesBlocks_RemovesExtraBlocks(t *testing.T) {
raw := `
allowed_nodes:
- delly
- minipc
# Cluster nodes (auto-discovered during installation)
# These nodes are allowed to request temperature data when cluster IPC validation is unavailable
allowed_nodes:
- delly
- minipc
- extra
`
sanitized, out := sanitizeDuplicateAllowedNodesBlocks("", []byte(raw))
if !sanitized {
t.Fatalf("expected sanitization to occur")
}
result := string(out)
if strings.Count(result, "allowed_nodes:") != 1 {
t.Fatalf("expected only one allowed_nodes block, got %q", result)
}
if strings.Contains(result, "extra") {
t.Fatalf("duplicate entries should be removed, got %q", result)
}
if strings.Contains(result, "Cluster nodes (auto-discovered during installation)") {
t.Fatalf("duplicate comment block should be removed")
}
}
func TestSanitizeDuplicateAllowedNodesBlocks_NoChangeWhenUnique(t *testing.T) {
raw := `
metrics_address: 127.0.0.1:9127
allowed_nodes:
- delly
`
sanitized, out := sanitizeDuplicateAllowedNodesBlocks("", []byte(raw))
if sanitized {
t.Fatalf("unexpected sanitization for unique config")
}
if string(out) != raw {
t.Fatalf("expected config to remain unchanged")
}
}