diff --git a/pkg/bootstrap/write.go b/pkg/bootstrap/write.go index afcecd07c..4eb450b0b 100644 --- a/pkg/bootstrap/write.go +++ b/pkg/bootstrap/write.go @@ -34,9 +34,42 @@ func WriteConfig(cfg *probodconfig.FullConfig, path string) error { return fmt.Errorf("marshal config: %w", err) } + var tree any + if err := yaml.Unmarshal(data, &tree); err != nil { + return fmt.Errorf("unmarshal config: %w", err) + } + + pruned := pruneEmptyStrings(tree) + + data, err = yaml.Marshal(pruned) + if err != nil { + return fmt.Errorf("marshal pruned config: %w", err) + } + if err := os.WriteFile(path, data, 0600); err != nil { return fmt.Errorf("write config file: %w", err) } return nil } + +func pruneEmptyStrings(value any) any { + switch v := value.(type) { + case map[string]any: + for key, child := range v { + if s, ok := child.(string); ok && s == "" { + delete(v, key) + continue + } + v[key] = pruneEmptyStrings(child) + } + return v + case []any: + for i, child := range v { + v[i] = pruneEmptyStrings(child) + } + return v + default: + return v + } +} diff --git a/pkg/bootstrap/write_test.go b/pkg/bootstrap/write_test.go index a27984d5f..273e91e64 100644 --- a/pkg/bootstrap/write_test.go +++ b/pkg/bootstrap/write_test.go @@ -85,6 +85,74 @@ func TestWriteConfig_FilePermissions(t *testing.T) { assert.Equal(t, os.FileMode(0600), info.Mode().Perm()) } +func TestWriteConfig_DropsEmptyStrings(t *testing.T) { + tmpDir := t.TempDir() + configPath := filepath.Join(tmpDir, "probod.yml") + + cfg := &probodconfig.FullConfig{ + Unit: probodconfig.UnitConfig{ + Metrics: probodconfig.MetricsConfig{Addr: "localhost:9090"}, + Tracing: probodconfig.TracingConfig{Addr: ""}, + }, + Probod: probodconfig.Config{ + BaseURL: "http://localhost:8080", + EncryptionKey: "", + ChromeDPAddr: "", + Pg: probodconfig.PgConfig{ + Addr: "localhost:5432", + Username: "postgres", + Password: "", + Database: "", + PoolSize: 100, + }, + }, + } + + err := WriteConfig(cfg, configPath) + require.NoError(t, err) + + data, err := os.ReadFile(configPath) + require.NoError(t, err) + + var tree map[string]any + + err = yaml.Unmarshal(data, &tree) + require.NoError(t, err) + + probod, ok := tree["probod"].(map[string]any) + require.True(t, ok) + + assert.Equal(t, "http://localhost:8080", probod["base-url"]) + assert.NotContains(t, probod, "encryption-key") + assert.NotContains(t, probod, "chrome-dp-addr") + + pg, ok := probod["pg"].(map[string]any) + require.True(t, ok) + + assert.Equal(t, "localhost:5432", pg["addr"]) + assert.Equal(t, "postgres", pg["username"]) + assert.NotContains(t, pg, "password") + assert.NotContains(t, pg, "database") + assert.Contains(t, pg, "pool-size") + + unit, ok := tree["unit"].(map[string]any) + require.True(t, ok) + + metrics, ok := unit["metrics"].(map[string]any) + require.True(t, ok) + assert.Equal(t, "localhost:9090", metrics["addr"]) + + tracing, ok := unit["tracing"].(map[string]any) + require.True(t, ok) + assert.NotContains(t, tracing, "addr") + + loaded := probodconfig.FullConfig{} + err = yaml.Unmarshal(data, &loaded) + require.NoError(t, err) + assert.Equal(t, cfg.Probod.BaseURL, loaded.Probod.BaseURL) + assert.Empty(t, loaded.Probod.EncryptionKey) +} + func TestWriteConfig_CompleteConfig(t *testing.T) { tmpDir := t.TempDir() configPath := filepath.Join(tmpDir, "probod.yml")