Audit scheduled import and inheritance lifecycles
This commit is contained in:
135
facade_import_lifecycle_test.go
Normal file
135
facade_import_lifecycle_test.go
Normal file
@@ -0,0 +1,135 @@
|
||||
package configkit
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
"testing/fstest"
|
||||
)
|
||||
|
||||
func TestDiscoveredItemHelpersPreserveNestedInheritedResourceEvidence(t *testing.T) {
|
||||
const canary = "PRIVATE-CONSUMED-HEADER-CANARY"
|
||||
filesystem := NewFilesystem("bundle", fstest.MapFS{
|
||||
"bundle/config/main.yml": {Data: []byte(`configkit:
|
||||
imports:
|
||||
- dir: records
|
||||
pattern: '*-item.yml'
|
||||
destination: [services, records]
|
||||
placement: sequence-item
|
||||
services:
|
||||
records:
|
||||
- id: authored
|
||||
version: authored
|
||||
`)},
|
||||
"bundle/config/records/a-item.yml": {Data: []byte(`configkit:
|
||||
imports:
|
||||
- path: helper.yml
|
||||
version: ` + canary + `
|
||||
entries:
|
||||
parent:
|
||||
resource: icon.txt
|
||||
child:
|
||||
extends: parent
|
||||
`)},
|
||||
"bundle/config/records/helper.yml": {Data: []byte("id: helper-supplied\n")},
|
||||
"bundle/config/records/icon.txt": {Data: []byte("icon payload")},
|
||||
})
|
||||
result, err := Load(filesystem.File("bundle/config/main.yml"), Options[map[string]any]{
|
||||
Imports: true,
|
||||
Filesystem: &FilesystemContext{Root: "bundle", FS: &filesystem},
|
||||
Definition: Definition[map[string]any]{
|
||||
Version: &VersionRule{Path: Keys("version"), Check: func(Version, *Validation) error { return nil }},
|
||||
SequenceCompositions: []SequenceComposition{{Path: Keys("services", "records"), IdentityField: "id"}},
|
||||
Secret: func(candidate Path) bool {
|
||||
return candidate.String() == "/services/records/0/version"
|
||||
},
|
||||
},
|
||||
SourceVersionMode: SourceVersionModeIfPresent,
|
||||
})
|
||||
if err != nil {
|
||||
var loadError *LoadError
|
||||
if errors.As(err, &loadError) {
|
||||
t.Fatalf("load discovered item: %v; diagnostics: %#v", err, loadError.Diagnostics())
|
||||
}
|
||||
t.Fatalf("load discovered item: %v", err)
|
||||
}
|
||||
services := result.Config["services"].(map[string]any)
|
||||
records := services["records"].([]any)
|
||||
if len(records) != 2 || records[0].(map[string]any)["id"] != "helper-supplied" || records[0].(map[string]any)["version"] != nil || records[1].(map[string]any)["version"] != "authored" {
|
||||
t.Fatalf("nested records = %#v", records)
|
||||
}
|
||||
childPath := Keys("services", "records").Index(0).Key("entries").Key("child").Key("resource")
|
||||
child := records[0].(map[string]any)["entries"].(map[string]any)["child"].(map[string]any)
|
||||
if child["resource"] != "icon.txt" {
|
||||
t.Fatalf("inherited relative resource = %#v", child)
|
||||
}
|
||||
|
||||
sources := result.Sources()
|
||||
filesByID := make(map[string]string, len(sources))
|
||||
for _, source := range sources {
|
||||
filesByID[source.ID] = source.Path
|
||||
}
|
||||
var itemSource SourceInfo
|
||||
for _, source := range sources {
|
||||
if source.Path == "bundle/config/records/a-item.yml" {
|
||||
itemSource = source
|
||||
}
|
||||
}
|
||||
if itemSource.VersionCheck == nil || !itemSource.VersionCheck.Version.Present || !itemSource.VersionCheck.Redacted || itemSource.VersionCheck.Version.Text != "" {
|
||||
t.Fatalf("consumed header inspection = %#v", itemSource.VersionCheck)
|
||||
}
|
||||
idInfo, ok := result.Metadata().Lookup(Keys("services", "records").Index(0).Key("id"))
|
||||
if !ok || len(idInfo.Origin.Locations) != 1 || filesByID[idInfo.Origin.Locations[0].SourceID] != "bundle/config/records/helper.yml" {
|
||||
t.Fatalf("assigned helper ID origin = %#v", idInfo)
|
||||
}
|
||||
resourceInfo, ok := result.Metadata().Lookup(childPath)
|
||||
if !ok || len(resourceInfo.Origin.Locations) != 1 || filesByID[resourceInfo.Origin.Locations[0].SourceID] != "bundle/config/records/a-item.yml" {
|
||||
t.Fatalf("inherited resource metadata = %#v", resourceInfo)
|
||||
}
|
||||
explanation, ok := result.Explain(childPath)
|
||||
if !ok || explanation.Effective.YAML != "icon.txt\n" || len(explanation.Origin.Locations) != 1 || explanation.Origin.Locations[0].SourceID != resourceInfo.Origin.Locations[0].SourceID {
|
||||
t.Fatalf("inherited resource explanation = %#v", explanation)
|
||||
}
|
||||
context, ok := result.SourceContext(resourceInfo.Origin.Locations[0].SourceID)
|
||||
if !ok || context.FS == nil || context.BaseDir != "config/records" {
|
||||
t.Fatalf("inherited resource context = %#v, %v", context, ok)
|
||||
}
|
||||
contents, err := fs.ReadFile(context.FS, path.Join(context.BaseDir, child["resource"].(string)))
|
||||
if err != nil || string(contents) != "icon payload" {
|
||||
t.Fatalf("inherited resource read = %q, %v", contents, err)
|
||||
}
|
||||
|
||||
_, err = Load(filesystem.File("bundle/config/main.yml"), Options[map[string]any]{
|
||||
Imports: true,
|
||||
Filesystem: &FilesystemContext{Root: "bundle", FS: &filesystem},
|
||||
Definition: Definition[map[string]any]{
|
||||
Version: &VersionRule{Path: Keys("version"), Check: func(Version, *Validation) error { return nil }},
|
||||
SequenceCompositions: []SequenceComposition{{Path: Keys("services", "records"), IdentityField: "version"}},
|
||||
Secret: func(candidate Path) bool {
|
||||
return candidate.String() == "/services/records/0/version"
|
||||
},
|
||||
},
|
||||
SourceVersionMode: SourceVersionModeIfPresent,
|
||||
})
|
||||
loadError, ok := err.(*LoadError)
|
||||
if !ok || len(loadError.Diagnostics()) != 1 || loadError.Diagnostics()[0].Code != CodeComposeInvalid {
|
||||
t.Fatalf("consumed header supplied an identity: %v", err)
|
||||
}
|
||||
if strings.Contains(err.Error(), canary) {
|
||||
t.Fatalf("diagnostic exposed the consumed secret header: %v", err)
|
||||
}
|
||||
var failedItemSource SourceInfo
|
||||
foundFailedItem := false
|
||||
for _, source := range loadError.Sources() {
|
||||
if source.Path == "bundle/config/records/a-item.yml" {
|
||||
failedItemSource = source
|
||||
foundFailedItem = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !foundFailedItem || failedItemSource.VersionCheck == nil || failedItemSource.VersionCheck.Version.Text != "" || !failedItemSource.VersionCheck.Redacted {
|
||||
t.Fatalf("failed-load source inspection exposed or omitted header evidence: %#v", failedItemSource)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user