Enforce the retained history node limit

This commit is contained in:
2026-10-25 22:04:54 +00:00
parent 4fcff5f453
commit 12d350a292
9 changed files with 395 additions and 84 deletions

View File

@@ -148,6 +148,10 @@ func Load[T any](source Source, secrets SecretBinding, supplied ...Options[T]) (
}
func loadWithSecretLookup[T any](source Source, secrets SecretBinding, lookup secretLookup, supplied ...Options[T]) (*Loaded[T], error) {
return loadWithSecretLookupLimit(source, secrets, lookup, historyNodeLimit, supplied...)
}
func loadWithSecretLookupLimit[T any](source Source, secrets SecretBinding, lookup secretLookup, historyLimit int, supplied ...Options[T]) (*Loaded[T], error) {
if len(supplied) > 1 {
return nil, (&diagnosticAccumulator{diagnostics: []Diagnostic{optionDiagnostic(CodeOptionsInvalid, "Load accepts at most one options value")}}).loadError()
}
@@ -174,10 +178,10 @@ func loadWithSecretLookup[T any](source Source, secrets SecretBinding, lookup se
sourceVersionMode: options.SourceVersionMode,
effectiveVersion: effectiveSourceVersionRuleForPlacement(options.Definition.Version, input.destination, options.SourceVersionMode, input.placementMode),
}
return executeLoadRequest(request, secrets, lookup)
return executeLoadRequest(request, secrets, lookup, historyLimit)
}
func executeLoadRequest[T any](request loadRequest[T], secrets SecretBinding, lookup secretLookup) (*Loaded[T], error) {
func executeLoadRequest[T any](request loadRequest[T], secrets SecretBinding, lookup secretLookup, historyLimit int) (*Loaded[T], error) {
accumulator := diagnosticAccumulator{}
accounting := &importAccounting{}
policy := acquisitionPolicy{
@@ -341,11 +345,16 @@ func executeLoadRequest[T any](request loadRequest[T], secrets SecretBinding, lo
if hasErrors(diagnostics) {
return nil, accumulator.loadError()
}
inspection := prepareInspectionHistory(resolved)
counter := newRetainedNodeCounter(historyLimit)
inspection, admitted := prepareInspectionHistory(resolved, counter)
if !admitted {
accumulator.add(Diagnostic{Code: CodeExplainLimitExceeded, Severity: SeverityError, Message: "retained configuration history exceeds the node limit"})
return nil, accumulator.loadError()
}
historyApplications := make([]historyApplication, 0, len(inspection.applications)+len(inspection.postDecodeApps))
historyApplications = append(historyApplications, inspection.applications...)
historyApplications = append(historyApplications, inspection.postDecodeApps...)
if !historyNodesWithinLimit(inspection.baseline, inspection.input, inspection.final, historyApplications, inspection.resolution, input.inheritance) {
if !addInspectionHistory(counter, inspection) {
accumulator.add(Diagnostic{Code: CodeExplainLimitExceeded, Severity: SeverityError, Message: "retained configuration history exceeds the node limit"})
return nil, accumulator.loadError()
}