Add safe historical configuration explanations

This commit is contained in:
2026-09-06 22:14:54 +00:00
parent d4ec8607d1
commit 6ef240b1a0
17 changed files with 1032 additions and 141 deletions

52
load.go
View File

@@ -67,13 +67,16 @@ type Version struct {
type Result[T any] struct {
Config T
metadata Metadata
sources []SourceInfo
diagnostics []Diagnostic
final *document.Node
resolution []resolutionSnapshot
overlays []overlayRecord
secrets map[string]bool
metadata Metadata
sources []SourceInfo
diagnostics []Diagnostic
baseline *document.Node
input *document.Node
final *document.Node
resolution []resolutionSnapshot
applications []historyApplication
secrets map[string]bool
secretReferences map[string]string
}
// Metadata returns detached effective presence, origin, and history records.
@@ -239,6 +242,16 @@ func loadWithSecretLookup[T any](source Source, lookup secretLookup, supplied ..
resolutionSnapshots = resolved.snapshots
applyResolutionMetadata(&metadata, resolved)
}
applications := []historyApplication(nil)
if composition != nil {
applications = cloneHistoryApplications(composition.applications)
} else if inputDocument != nil {
applications = []historyApplication{{layer: LayerBase, value: inputDocument}}
}
if !historyNodesWithinLimit(decoded.baseline, decoded.final, final, applications, resolutionSnapshots) {
accumulator.add(Diagnostic{Code: CodeExplainLimitExceeded, Severity: SeverityError, Message: "retained configuration history exceeds the node limit"})
return nil, accumulator.loadError()
}
secretResolution := resolveSecretReferences(reflect.ValueOf(&configuration).Elem(), schema, inputDocument, lookup)
accumulator.add(secretResolution.diagnostics...)
if hasErrors(secretResolution.diagnostics) {
@@ -251,20 +264,19 @@ func loadWithSecretLookup[T any](source Source, lookup secretLookup, supplied ..
return nil, accumulator.loadError()
}
}
secrets := classifySecretPaths(schema, options.Definition.Secret, metadata, final)
var overlaySnapshots []overlayRecord
if composition != nil {
overlaySnapshots = cloneOverlayRecords(composition.overlays)
}
secrets := classifySecretPaths(schema, options.Definition.Secret, metadata, final, applications)
return &Result[T]{
Config: configuration,
metadata: metadata,
sources: cloneSourceInfos(accumulator.sources),
diagnostics: canonicalDiagnostics(accumulator.diagnostics),
final: document.Clone(final),
resolution: cloneResolutionSnapshots(resolutionSnapshots),
overlays: overlaySnapshots,
secrets: secrets,
Config: configuration,
metadata: metadata,
sources: cloneSourceInfos(accumulator.sources),
diagnostics: canonicalDiagnostics(accumulator.diagnostics),
baseline: decoded.baseline,
input: decoded.final,
final: final,
resolution: resolutionSnapshots,
applications: applications,
secrets: secrets,
secretReferences: cloneSecretReferences(secretResolution.references),
}, nil
}