Sanitize duplicate allowed_nodes blocks
This commit is contained in:
parent
2e7f693c8b
commit
936894a5fe
2 changed files with 100 additions and 0 deletions
|
|
@ -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{})
|
||||
|
|
|
|||
52
cmd/pulse-sensor-proxy/config_test.go
Normal file
52
cmd/pulse-sensor-proxy/config_test.go
Normal 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")
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue