Preserve Audita module selections in YAML output
This commit is contained in:
@@ -9,7 +9,12 @@ transcription review is retained below as historical context.
|
|||||||
|
|
||||||
## 1. Preserve omitted modules in direct YAML serialization
|
## 1. Preserve omitted modules in direct YAML serialization
|
||||||
|
|
||||||
Priority: P2. Status: Pending.
|
Priority: P2. Status: Complete.
|
||||||
|
|
||||||
|
The safe YAML projection now omits nil modules while retaining explicit empty
|
||||||
|
and ordered/repeated selections. A round-trip regression failed before the fix
|
||||||
|
and passes afterward. Config package tests, including credential-safety coverage,
|
||||||
|
and its race tests pass.
|
||||||
|
|
||||||
Location: `internal/config/credential_projection.go:25` (`AuditaConfig.MarshalYAML`),
|
Location: `internal/config/credential_projection.go:25` (`AuditaConfig.MarshalYAML`),
|
||||||
especially the plain slice field at line 30 and assignment at line 40.
|
especially the plain slice field at line 30 and assignment at line 40.
|
||||||
|
|||||||
@@ -24,20 +24,25 @@ func (cfg StorageS3Config) MarshalYAML() (any, error) {
|
|||||||
// MarshalYAML exposes only public Audita credential reference names.
|
// MarshalYAML exposes only public Audita credential reference names.
|
||||||
func (cfg AuditaConfig) MarshalYAML() (any, error) {
|
func (cfg AuditaConfig) MarshalYAML() (any, error) {
|
||||||
type safeAudita struct {
|
type safeAudita struct {
|
||||||
Binary string `yaml:"binary"`
|
Binary string `yaml:"binary"`
|
||||||
Timeout string `yaml:"timeout"`
|
Timeout string `yaml:"timeout"`
|
||||||
Credentials []string `yaml:"credentials,omitempty"`
|
Credentials []string `yaml:"credentials,omitempty"`
|
||||||
Modules []string `yaml:"modules"`
|
Modules *[]string `yaml:"modules,omitempty"`
|
||||||
Overlay string `yaml:"overlay"`
|
Overlay string `yaml:"overlay"`
|
||||||
ProposalProfile string `yaml:"proposal_profile"`
|
ProposalProfile string `yaml:"proposal_profile"`
|
||||||
ValidationProfile string `yaml:"validation_profile"`
|
ValidationProfile string `yaml:"validation_profile"`
|
||||||
TranscriptDescription string `yaml:"transcript_description"`
|
TranscriptDescription string `yaml:"transcript_description"`
|
||||||
ConfigPath string `yaml:"config_path"`
|
ConfigPath string `yaml:"config_path"`
|
||||||
OutputSchema string `yaml:"output_schema"`
|
OutputSchema string `yaml:"output_schema"`
|
||||||
|
}
|
||||||
|
// A nil pointer omits the override; a pointer to an empty slice disables modules.
|
||||||
|
var modules *[]string
|
||||||
|
if cfg.Modules != nil {
|
||||||
|
modules = &cfg.Modules
|
||||||
}
|
}
|
||||||
return safeAudita{
|
return safeAudita{
|
||||||
Binary: cfg.Binary, Timeout: cfg.Timeout, Credentials: secretReferenceNames(cfg.Credentials),
|
Binary: cfg.Binary, Timeout: cfg.Timeout, Credentials: secretReferenceNames(cfg.Credentials),
|
||||||
Modules: cfg.Modules, Overlay: cfg.Overlay, ProposalProfile: cfg.ProposalProfile,
|
Modules: modules, Overlay: cfg.Overlay, ProposalProfile: cfg.ProposalProfile,
|
||||||
ValidationProfile: cfg.ValidationProfile, TranscriptDescription: cfg.TranscriptDescription,
|
ValidationProfile: cfg.ValidationProfile, TranscriptDescription: cfg.TranscriptDescription,
|
||||||
ConfigPath: cfg.ConfigPath, OutputSchema: cfg.OutputSchema,
|
ConfigPath: cfg.ConfigPath, OutputSchema: cfg.OutputSchema,
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
33
internal/config/credential_projection_test.go
Normal file
33
internal/config/credential_projection_test.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAuditaYAMLPreservesModuleSelection(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
modules []string
|
||||||
|
}{
|
||||||
|
{name: "omitted"},
|
||||||
|
{name: "explicit empty", modules: []string{}},
|
||||||
|
{name: "ordered repetitions", modules: []string{"grammar", "names", "grammar"}},
|
||||||
|
} {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
data, err := yaml.Marshal(AuditaConfig{Modules: tc.modules})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
var decoded AuditaConfig
|
||||||
|
if err := yaml.Unmarshal(data, &decoded); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(decoded.Modules, tc.modules) {
|
||||||
|
t.Fatalf("modules = %#v, want %#v; YAML:\n%s", decoded.Modules, tc.modules, data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user