fix: sécuriser shutdown, config par défaut et reconnexion socket

Co-authored-by: aider (openrouter/openai/gpt-5.3-codex) <aider@aider.chat>
This commit is contained in:
Jacquin Antoine
2026-02-25 21:44:40 +01:00
parent 617ecd2014
commit 6cd6c4c3b8
11 changed files with 394 additions and 56 deletions

View File

@ -3,6 +3,7 @@ package config
import (
"encoding/json"
"errors"
"fmt"
"os"
"strconv"
@ -28,13 +29,17 @@ func NewLoader(configPath string) *LoaderImpl {
func (l *LoaderImpl) Load() (api.AppConfig, error) {
config := api.DefaultConfig()
// Load from YAML file if path is provided
if l.configPath != "" {
fileConfig, err := l.loadFromFile(l.configPath)
if err != nil {
return config, fmt.Errorf("failed to load config file: %w", err)
}
path := l.configPath
explicit := path != ""
if !explicit {
path = "config.yml"
}
fileConfig, err := l.loadFromFile(path)
if err == nil {
config = mergeConfigs(config, fileConfig)
} else if !( !explicit && errors.Is(err, os.ErrNotExist)) {
return config, fmt.Errorf("failed to load config file: %w", err)
}
// Override with environment variables

View File

@ -2,6 +2,7 @@ package config
import (
"os"
"path/filepath"
"strings"
"testing"
@ -211,3 +212,51 @@ func TestToJSON(t *testing.T) {
t.Error("ToJSON() result doesn't contain 'eth0'")
}
}
func TestLoad_DefaultConfigFileAbsent_DoesNotFail(t *testing.T) {
t.Setenv("JA4SENTINEL_INTERFACE", "")
t.Setenv("JA4SENTINEL_PORTS", "")
t.Setenv("JA4SENTINEL_BPF_FILTER", "")
t.Setenv("JA4SENTINEL_FLOW_TIMEOUT", "")
tempDir := t.TempDir()
oldWD, err := os.Getwd()
if err != nil {
t.Fatalf("Getwd() error = %v", err)
}
defer func() {
_ = os.Chdir(oldWD)
}()
if err := os.Chdir(tempDir); err != nil {
t.Fatalf("Chdir() error = %v", err)
}
_ = os.Remove(filepath.Join(tempDir, "config.yml"))
loader := NewLoader("")
cfg, err := loader.Load()
if err != nil {
t.Fatalf("Load() error = %v", err)
}
if cfg.Core.Interface != api.DefaultInterface {
t.Errorf("Interface = %q, want %q", cfg.Core.Interface, api.DefaultInterface)
}
if len(cfg.Core.ListenPorts) == 0 || cfg.Core.ListenPorts[0] != api.DefaultPort {
t.Errorf("ListenPorts = %v, want first port %d", cfg.Core.ListenPorts, api.DefaultPort)
}
}
func TestLoad_ExplicitMissingConfig_Fails(t *testing.T) {
t.Setenv("JA4SENTINEL_INTERFACE", "")
t.Setenv("JA4SENTINEL_PORTS", "")
t.Setenv("JA4SENTINEL_BPF_FILTER", "")
t.Setenv("JA4SENTINEL_FLOW_TIMEOUT", "")
loader := NewLoader("/tmp/definitely-missing-ja4sentinel.yml")
_, err := loader.Load()
if err == nil {
t.Fatal("Load() should fail with explicit missing config path")
}
}