Add per-subsystem config validation for wireguard, authelia, nftables, tunnel
- wireguard: ValidateConfig checks ListenPort range, Address/LanCIDR CIDR format. SaveConfig now validates before writing. - authelia: ValidateConfigOpts checks required fields (Domain, JWTSecret, SessionSecret) and StorageEncKey minimum length (20 chars). GenerateConfig now validates before generating. - nftables: ValidateWANInterface checks interface exists via net.InterfaceByName before generating rules that reference it. - tunnel: ValidateConfig checks TunnelID, PublicDomain, GatewayDomain are set and credentials file exists. WriteConfig now validates before generating.
This commit is contained in:
@@ -7,13 +7,17 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func testConfig() Config {
|
||||
func testConfig(t *testing.T) Config {
|
||||
t.Helper()
|
||||
credsDir := filepath.Join(t.TempDir(), "creds")
|
||||
os.MkdirAll(credsDir, 0755)
|
||||
os.WriteFile(filepath.Join(credsDir, "abc-123.json"), []byte(`{"AccountTag":"test"}`), 0600)
|
||||
return Config{
|
||||
Enabled: true,
|
||||
TunnelID: "abc-123",
|
||||
PublicDomain: "pub.payne.io",
|
||||
GatewayDomain: "payne.io",
|
||||
CredentialsDir: "/tmp/creds",
|
||||
CredentialsDir: credsDir,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +29,8 @@ func TestGenerateConfig_Basic(t *testing.T) {
|
||||
{Name: "dashboard"},
|
||||
}
|
||||
|
||||
out := m.GenerateConfig(testConfig(), services)
|
||||
cfg := testConfig(t)
|
||||
out := m.GenerateConfig(cfg, services)
|
||||
|
||||
if out == "" {
|
||||
t.Fatal("expected non-empty config")
|
||||
@@ -37,7 +42,7 @@ func TestGenerateConfig_Basic(t *testing.T) {
|
||||
}
|
||||
|
||||
// Check credentials file
|
||||
if !strings.Contains(out, "credentials-file: /tmp/creds/abc-123.json") {
|
||||
if !strings.Contains(out, "abc-123.json") {
|
||||
t.Errorf("expected credentials file, got:\n%s", out)
|
||||
}
|
||||
|
||||
@@ -75,7 +80,7 @@ func TestGenerateConfig_SubdomainOverride(t *testing.T) {
|
||||
{Name: "internal-name", Subdomain: "public-name"},
|
||||
}
|
||||
|
||||
out := m.GenerateConfig(testConfig(), services)
|
||||
out := m.GenerateConfig(testConfig(t), services)
|
||||
|
||||
if !strings.Contains(out, "hostname: public-name.pub.payne.io") {
|
||||
t.Errorf("expected subdomain override, got:\n%s", out)
|
||||
@@ -85,7 +90,7 @@ func TestGenerateConfig_SubdomainOverride(t *testing.T) {
|
||||
func TestGenerateConfig_Disabled(t *testing.T) {
|
||||
m := NewManager(t.TempDir())
|
||||
|
||||
cfg := testConfig()
|
||||
cfg := testConfig(t)
|
||||
cfg.Enabled = false
|
||||
|
||||
out := m.GenerateConfig(cfg, []PublicDomain{{Name: "my-api"}})
|
||||
@@ -96,7 +101,7 @@ func TestGenerateConfig_Disabled(t *testing.T) {
|
||||
|
||||
func TestGenerateConfig_NoServices(t *testing.T) {
|
||||
m := NewManager(t.TempDir())
|
||||
out := m.GenerateConfig(testConfig(), nil)
|
||||
out := m.GenerateConfig(testConfig(t), nil)
|
||||
if out != "" {
|
||||
t.Errorf("expected empty config with no services, got:\n%s", out)
|
||||
}
|
||||
@@ -104,7 +109,7 @@ func TestGenerateConfig_NoServices(t *testing.T) {
|
||||
|
||||
func TestGenerateConfig_MissingTunnelID(t *testing.T) {
|
||||
m := NewManager(t.TempDir())
|
||||
cfg := testConfig()
|
||||
cfg := testConfig(t)
|
||||
cfg.TunnelID = ""
|
||||
|
||||
out := m.GenerateConfig(cfg, []PublicDomain{{Name: "my-api"}})
|
||||
@@ -118,7 +123,7 @@ func TestWriteConfig(t *testing.T) {
|
||||
m := NewManager(tmpDir)
|
||||
|
||||
services := []PublicDomain{{Name: "my-api"}}
|
||||
if err := m.WriteConfig(testConfig(), services); err != nil {
|
||||
if err := m.WriteConfig(testConfig(t), services); err != nil {
|
||||
t.Fatalf("WriteConfig failed: %v", err)
|
||||
}
|
||||
|
||||
@@ -139,12 +144,12 @@ func TestWriteConfig_RemovesWhenDisabled(t *testing.T) {
|
||||
m := NewManager(tmpDir)
|
||||
|
||||
// Write config first
|
||||
if err := m.WriteConfig(testConfig(), []PublicDomain{{Name: "my-api"}}); err != nil {
|
||||
if err := m.WriteConfig(testConfig(t), []PublicDomain{{Name: "my-api"}}); err != nil {
|
||||
t.Fatalf("WriteConfig failed: %v", err)
|
||||
}
|
||||
|
||||
// Now disable and write again — should remove the file
|
||||
cfg := testConfig()
|
||||
cfg := testConfig(t)
|
||||
cfg.Enabled = false
|
||||
if err := m.WriteConfig(cfg, []PublicDomain{{Name: "my-api"}}); err != nil {
|
||||
t.Fatalf("WriteConfig (disable) failed: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user