Documentation
¶
Overview ¶
yamlkit is a package for parsing, traversing, and updating lists of configuration elements, called resources, represented as yaml doc lists.
Index ¶
- Constants
- Variables
- func AddMutations(mutations, newMutations api.ResourceMutationList) (api.ResourceMutationList, bool)
- func AppendCommentLines(result []string, indent string, text string) []string
- func ApplyLinePatch(target, patch string) (string, bool)
- func ApplyScalarPatch(target, patch string) (string, bool)
- func AssociativePathSegment(mergeKey string, mergeKeyValue string, index int) string
- func AttributeDetailsEqual(details1, details2 *api.AttributeDetails, compareFunctions bool) bool
- func AttributeValueForPath(resourceProvider ResourceProvider, path api.ResolvedPath, ...) api.AttributeValue
- func CommentKey(ct CommentType, targetKey string) string
- func CommentKeysForDataKey(targetKey string) []string
- func ComputeLinePatch(previous, modified string) string
- func ComputeMutations(previousParsedData, modifiedParsedData gaby.Container, functionIndex int64, ...) (api.ResourceMutationList, error)
- func ComputeMutationsForDocs(rootPath string, previousDoc *gaby.YamlDoc, modifiedDoc *gaby.YamlDoc, ...)
- func ComputeScalarPatch(previous, modified string) string
- func DeletePaths(parsedData gaby.Container, ...) error
- func DiffPatch(original, modified, targetData []byte, resourceProvider ResourceProvider) ([]byte, bool, error)
- func DiffPatchWithOptions(original, modified, targetData []byte, resourceProvider ResourceProvider, ...) ([]byte, bool, error)
- func EnrichMergeKeysFromDoc(doc *gaby.YamlDoc, resourceProvider ResourceProvider, attr *api.AttributeValue)
- func EscapeDotsInPathSegment(segment string) string
- func ExtractCommentKeys(data map[string]any) map[string]string
- func ExtractCommentsFromData(data any) (any, map[string]string)
- func FindMutationIndex(mutationSources api.ResourceMutationList, resource api.ResourceInfo, ...) (int64, bool)
- func FindResourceDoc(parsedData gaby.Container, resourceProvider ResourceProvider, ...) (*gaby.YamlDoc, *api.ResourceInfo)
- func FindYAMLPathsByValue(parsedData gaby.Container, resourceProvider ResourceProvider, ...) api.AttributeValueList
- func FunctionInvocationsEqual(fi1, fi2 *api.FunctionInvocation) bool
- func GetMutationOptions(doc *gaby.YamlDoc, resourceProvider ResourceProvider) []string
- func GetNeededPaths[T api.Scalar](parsedData gaby.Container, ...) (api.AttributeValueList, error)
- func GetNeededStringPaths(parsedData gaby.Container, ...) (api.AttributeValueList, error)
- func GetPathRegistryForAttributeName(resourceProvider ResourceProvider, attributeName api.AttributeName) api.ResourceTypeToPathToVisitorInfoType
- func GetPathVisitorInfo(resourceProvider ResourceProvider, resourceType api.ResourceType, ...) *api.PathVisitorInfo
- func GetPaths[T api.Scalar](parsedData gaby.Container, ...) (api.AttributeValueList, error)
- func GetPathsAnyType(parsedData gaby.Container, ...) (api.AttributeValueList, error)
- func GetRegisteredNeededPaths(resourceProvider ResourceProvider) api.ResourceTypeToPathToVisitorInfoType
- func GetRegisteredNeededPathsByProperty(resourceProvider ResourceProvider, neededRequired []string) api.ResourceTypeToPathToVisitorInfoType
- func GetRegisteredNeededStringPaths(parsedData gaby.Container, resourceProvider ResourceProvider, ...) (api.AttributeValueList, error)
- func GetRegisteredProvidedPaths(resourceProvider ResourceProvider) api.ResourceTypeToPathToVisitorInfoType
- func GetRegisteredProvidedStringPaths(parsedData gaby.Container, resourceProvider ResourceProvider, ...) (api.AttributeValueList, error)
- func GetResourceCategoryTypeName(doc *gaby.YamlDoc, resourceProvider ResourceProvider) (api.ResourceCategory, api.ResourceType, api.ResourceName, error)
- func GetResourceInfo(doc *gaby.YamlDoc, resourceProvider ResourceProvider) (*api.ResourceInfo, error)
- func GetStringPaths(parsedData gaby.Container, ...) (api.AttributeValueList, error)
- func GetToolchainPath(rp ResourceProvider) string
- func GetVisitorMapForPath(resourceProvider ResourceProvider, rt api.ResourceType, ...) api.ResourceTypeToPathToVisitorInfoType
- func GetVisitorOptions(doc *gaby.YamlDoc, resourceProvider ResourceProvider) []string
- func InjectCommentKeys(data map[string]any, comments map[string]string)
- func IsCommentKey(key string) bool
- func IsEmptyOrPlaceHolder(s string) bool
- func IsIntPlaceHolderValue(v int) bool
- func IsMultiLineString(s string) bool
- func IsNumber(s string) bool
- func IsNumeric(c rune) bool
- func IsPatchableString(s string) bool
- func IsPlaceholderValue(value any) bool
- func IsStringPlaceHolderValue(v string) bool
- func JoinPathSegments(segments []string) string
- func LeadingWhitespace(line string) string
- func LowerFirst(s string) string
- func MatchesWhereResourceExpressions(doc *gaby.YamlDoc, resourceInfo *api.ResourceInfo, ...) (bool, error)
- func MergeCommentsIntoData(data any, comments map[string]string) any
- func PatchMutations(parsedData gaby.Container, ...) (gaby.Container, api.MutationConflictList, error)
- func PathIsResolved(path string, includeAt bool) bool
- func RegisterPathsByAttributeName(resourceProvider ResourceProvider, attributeName api.AttributeName, ...)
- func ReplaceStringPlaceholder(s, replacement string) string
- func Reset(parsedData gaby.Container, mutationsPredicates api.ResourceMutationList, ...) error
- func ResolveAssociativeSegments(doc *gaby.YamlDoc, path string) (string, bool)
- func ResolveConfigHubPath(path string, resourceInfo *api.ResourceInfo) (any, error)
- func ResourceAndCategoryTypeMaps(parsedData gaby.Container, resourceProvider ResourceProvider) (resourceMap ResourceNameToCategoryTypesMap, ...)
- func ResourceTypesForAttribute(attributeName api.AttributeName, resourceProvider ResourceProvider) []api.ResourceType
- func ResourceTypesForPathMap(pathMap map[api.ResourceType][]string) []api.ResourceType
- func SetPredicates(parsedData gaby.Container, mutations api.ResourceMutationList, ...) (api.ResourceMutationList, []api.ResolvedPath)
- func SplitInlineComment(value string) (string, string)
- func StripAssociativeSegments(path string) string
- func StripCommentKeys(data any) any
- func StripComments(yamlData []byte) ([]byte, error)
- func SubtractMutations(mutations, subtractMutations api.ResourceMutationList) (api.ResourceMutationList, api.MutationConflictList)
- func TransformConfig(originalData []byte, resourceProvider ResourceProvider, ...) ([]byte, bool, error)
- func UpdatePathsFunction[T api.Scalar](parsedData gaby.Container, ...) error
- func UpdatePathsFunctionDoc(parsedData gaby.Container, ...) error
- func UpdatePathsSetterArgument(parsedData gaby.Container, ...) error
- func UpdatePathsValue[T api.Scalar](parsedData gaby.Container, ...) error
- func UpdateStringPaths(parsedData gaby.Container, ...) error
- func UpdateStringPathsFunction(parsedData gaby.Container, ...) error
- func VetPathsSetterArgument(parsedData gaby.Container, ...) (api.ValidationResult, error)
- func VisitPaths[T api.Scalar](parsedData gaby.Container, ...) (any, error)
- func VisitPathsAnyType(parsedData gaby.Container, ...) (any, error)
- func VisitPathsDoc(parsedData gaby.Container, ...) (any, error)
- func VisitResources(parsedData gaby.Container, output any, resourceProvider ResourceProvider, ...) (any, error)
- func VisitResourcesFiltered(parsedData gaby.Container, output any, resourceProvider ResourceProvider, ...) (any, error)
- func VisitorInfoEqual(pathVisitorInfo1, pathVisitorInfo2 *api.PathVisitorInfo, compareFunctions bool) bool
- func YamlSafePathGetDoc(doc *gaby.YamlDoc, resolvedPath api.ResolvedPath, notFoundOk bool) (*gaby.YamlDoc, bool, error)
- func YamlSafePathGetValue[T api.Scalar](doc *gaby.YamlDoc, resolvedPath api.ResolvedPath, notFoundOk bool) (T, bool, error)
- func YamlSafePathGetValueAnyType(doc *gaby.YamlDoc, resolvedPath api.ResolvedPath, notFoundOk bool) (any, bool, error)
- type AttributeEnricher
- type AttributeRegistrationDetails
- type CommentType
- type EmbeddedAccessor
- type ExactValueMatcher
- type JSONAccessor
- func (ja *JSONAccessor) Data(scalarYamlDoc *gaby.YamlDoc, path string) (any, error)
- func (ja *JSONAccessor) ExistsP(scalarYamlDoc *gaby.YamlDoc, path string) bool
- func (ja *JSONAccessor) Extract(currentFieldValue, path string) (any, error)
- func (ja *JSONAccessor) Replace(currentFieldValue string, value any, path string) (string, error)
- func (ja *JSONAccessor) SetP(scalarYamlDoc *gaby.YamlDoc, value any, path string) error
- type LineAccessor
- func (la *LineAccessor) Data(scalarYamlDoc *gaby.YamlDoc, path string) (any, error)
- func (la *LineAccessor) ExistsP(scalarYamlDoc *gaby.YamlDoc, path string) bool
- func (la *LineAccessor) Extract(currentFieldValue, path string) (any, error)
- func (la *LineAccessor) Replace(currentFieldValue string, value any, path string) (string, error)
- func (la *LineAccessor) SetP(scalarYamlDoc *gaby.YamlDoc, value any, path string) error
- type LintConfig
- type LintFinding
- type MergeKeyEntry
- type MergeKeyLookup
- type RegexpAccessor
- func (ra *RegexpAccessor) Data(scalarYamlDoc *gaby.YamlDoc, path string) (any, error)
- func (ra *RegexpAccessor) ExistsP(scalarYamlDoc *gaby.YamlDoc, path string) bool
- func (ra *RegexpAccessor) Extract(currentFieldValue, path string) (any, error)
- func (ra *RegexpAccessor) Replace(currentFieldValue string, value any, path string) (string, error)
- func (ra *RegexpAccessor) SetP(scalarYamlDoc *gaby.YamlDoc, value any, path string) error
- type RegexpMatcher
- type ResolvedPathInfo
- type ResourceCategoryTypeToNamesMap
- type ResourceInfoToDocMap
- type ResourceNameToCategoryTypesMap
- type ResourceProvider
- type ResourceProviderRegistry
- type ResourceTypeToPathPrefixSetType
- type ResourceVisitorFunc
- type StringContainsMatcher
- type ValueMatcher
- type VisitorContext
- type VisitorFunc
- type VisitorFuncAnyType
- type VisitorFuncDoc
- type YAMLAccessor
- func (ya *YAMLAccessor) Data(scalarYamlDoc *gaby.YamlDoc, path string) (any, error)
- func (ya *YAMLAccessor) ExistsP(scalarYamlDoc *gaby.YamlDoc, path string) bool
- func (ya *YAMLAccessor) Extract(currentFieldValue, path string) (any, error)
- func (ya *YAMLAccessor) Replace(currentFieldValue string, value any, path string) (string, error)
- func (ya *YAMLAccessor) SetP(scalarYamlDoc *gaby.YamlDoc, value any, path string) error
Constants ¶
const ( PatchFormatJSON = "json" PatchFormatYAML = "yaml" )
Patch format constants used as the "format" field in structural patches.
const ( PlaceHolderBlockApplyString = "confighubplaceholder" PlaceHolderBlockApplyInt = 999999999 )
PlaceHolderBlockApply We will need placeholders for different data types and that fit with different validation rules The string value is all lowercase to comply with DNS label requirements.
const CommentKeyPrefix = "$comment$"
CommentKeyPrefix is the prefix for all comment keys in the data structure. Comment keys encode comments from native config formats (TOML, INI, HCL, etc.) as map entries so they survive conversion through formats like JSON that don't support comments natively.
const EmbeddedAccessorSeparator = "#"
const VisitorSetterInvocationFunctionName = "$visitor"
VisitorSetterInvocationFunctionName is a special function name used to indicate that the setter invocation value should be used directly by the visitor, rather than invoking a real function. It is not a valid function name.
Variables ¶
var EmbeddedPathNotFound = errors.New("embedded path not found")
var NoSubexpressions = errors.New("no capturing subexpressions")
var UnsupportedAccessorType = errors.New("accessor type not supported")
var UnsupportedValueType = errors.New("only string values supported currently")
Functions ¶
func AddMutations ¶
func AddMutations(mutations, newMutations api.ResourceMutationList) (api.ResourceMutationList, bool)
AddMutations merges newMutations into mutations and returns the result, accumulating changes over sequential edits to produce a compiled history of all modifications. The accumulated form is what's stored as a Unit's MutationSources and what feeds the Predicate map passed into PatchMutations.
Algorithm:
Resource matching: by current ResourceTypeAndName, then by AliasesWithoutScopes (handling renames). Unmatched new mutations are appended as new resource entries.
Resource-level merge:
| Existing Type | New Type | Result | |------------------|-----------------------|---------------------| | Any | None | Keep existing | | Any | Delete or Replace | Replace with new | | None | Any (non-None) | Replace with new | | Delete | Any (non-Delete) | Change to Replace | | Add/Update | Add/Update | Merge path mutations|
Path-level merge: process newMutations' paths sorted least-specific to most-specific so parent paths land before children. For each new path:
- Exact match in existing: replace the existing entry, taking the new MutationType (so a later edit's intent — e.g., an Update on a previously-Added field — is reflected). Exception: Delete → non-Delete becomes Replace, since the field was previously erased and is now being re-set. - Existing path is a child of the new path AND new path is Delete or Replace: drop the now-superseded child paths. - Otherwise: insert the new path verbatim, dropping any existing children it supersedes.
Because the new MutationType replaces the existing one on exact match, when this accumulated record is later used as a patch, PatchMutations sees the latest intent (e.g., Update to merge with the target's value rather than wholesale Replace).
Alias tracking: union of both sides' Aliases / AliasesWithoutScopes so a resource can still be matched after another rename.
Key behaviors:
- Accumulative: designed to be called repeatedly as changes occur.
- Last-write-wins for values and types on exact-path matches.
- Alias awareness: handles resources renamed between mutation sets.
func AppendCommentLines ¶ added in v0.1.25
AppendCommentLines appends comment text as #-prefixed lines to the result slice, using the given indentation prefix to match surrounding lines.
func ApplyLinePatch ¶ added in v0.1.14
ApplyLinePatch applies a line-level patch (produced by ComputeLinePatch) to a target string. Returns the patched string and true if all hunks applied cleanly. If any hunk fails to apply, returns the partially patched string and false.
func ApplyScalarPatch ¶ added in v0.1.14
ApplyScalarPatch applies a patch (produced by ComputeScalarPatch) to a target string. It auto-detects the patch format: structural patches (JSON-encoded, start with '{') are applied structurally; line-level text patches (unified diff) are applied with fuzzy context matching.
Returns the patched string and true if the patch applied cleanly. On failure, returns the original target string and false.
func AssociativePathSegment ¶
AssociativePathSegment builds a path segment encoding both the merge key value and the positional index, using the syntax ?key=value;@index. The merge key value is escaped to handle dots.
func AttributeDetailsEqual ¶
func AttributeDetailsEqual(details1, details2 *api.AttributeDetails, compareFunctions bool) bool
AttributeDetailsEqual reports whether two sets of attribute details, optionally including getter and setter invocations, match.
func AttributeValueForPath ¶
func AttributeValueForPath(resourceProvider ResourceProvider, path api.ResolvedPath, resourceInfo *api.ResourceInfo, value any) api.AttributeValue
func CommentKey ¶ added in v0.1.25
func CommentKey(ct CommentType, targetKey string) string
CommentKey builds a comment map key from a comment type and target key name. For example, CommentKey(CommentHead, "server") returns "$comment$head$server". An empty targetKey refers to the containing object/document itself.
func CommentKeysForDataKey ¶ added in v0.1.25
CommentKeysForDataKey returns the $comment$ keys that could be associated with a given data key (head, line, and foot).
func ComputeLinePatch ¶ added in v0.1.14
ComputeLinePatch computes a line-level diff between two multi-line strings and returns a patch in unified diff text format. The patch can be serialized as a string in MutationInfo.Patch and later applied with ApplyLinePatch.
This uses the Myers diff algorithm via go-diff's DiffLinesToChars to tokenize at line boundaries, producing a minimal edit script that correctly identifies inserted, deleted, and unchanged lines.
func ComputeMutations ¶
func ComputeMutations(previousParsedData, modifiedParsedData gaby.Container, functionIndex int64, resourceProvider ResourceProvider) (api.ResourceMutationList, error)
ComputeMutations performs a kind of diff between two configuration Units where it determines what modifications were made at the resource/element level and at the path level. They are recorded in a way that can be accumulated and updated over subsequent edits and transformations.
func ComputeMutationsForDocs ¶
func ComputeMutationsForDocs(rootPath string, previousDoc *gaby.YamlDoc, modifiedDoc *gaby.YamlDoc, functionIndex int64, pathMutationMap api.MutationMap, mergeKeyLookup MergeKeyLookup, arrayOrders api.ArrayOrderMap, arrayElementAliases api.ArrayElementAliasMap)
ComputeMutationsForDocs determines the edits that have been performed to transform the previousDoc into modifiedDoc and records them in pathMutationMap (modified in place), associated with the provided functionIndex.
mergeKeyLookup, if non-nil, is called with array paths to determine whether the array is merge-keyed associative. If so, elements are matched by merge-key value (not positional index) and paths use the ?key=value;@index syntax. The positional index is retained as a fallback hint, but PatchMutations only uses it when the element at that index has no merge-key field (legacy data) or the index is out of bounds (append).
Design notes:
- Removed paths are not tombstoned. If an element in the downstream is then modified by upstream, the corresponding path will be present in mutationsPatch and absent from the target's data; the upstream path's child will not be re-added because PatchMutations honors the target's removal via mutationsToSubtract.
- The reciprocal case — a field modified downstream while the surrounding block is removed upstream — is reconciled in PatchMutations / SubtractMutations.
TODO: Decide what to do about embedded accessors
arrayOrders, if non-nil, is populated with the desired merge-key sequence for every merge-keyed array we descend into whose modified-side order or element set differs from the previous side. PatchMutations consumes these to reorder the target array after path mutations are applied, so positional associative arrays preserve source-side ordering.
arrayElementAliases, if non-nil, is populated with element-level renames detected inside merge-keyed arrays. When an unmatched modified element and an unmatched previous element are similar enough, the pair is treated as a rename: child paths are emitted under the previous merge-key value (so they align with target-side paths in SubtractMutations) and the alias is recorded so PatchMutations rewrites the merge-key field at apply time.
func ComputeScalarPatch ¶ added in v0.1.14
ComputeScalarPatch computes a patch for a changed multi-line scalar string value. It tries to parse both values as JSON, then YAML, and computes a structural patch (sub-path mutations) for those formats. Falls back to a line-level text diff.
Structural patches give true three-way merge for embedded JSON/YAML: individual field changes are tracked by path, so independent changes to different fields merge correctly. Line-level patches handle unstructured text (markdown, config files, etc.) with context-based fuzzy matching.
func DeletePaths ¶
func DeletePaths( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, options *api.FunctionOptions, ) error
func DiffPatch ¶
func DiffPatch(original, modified, targetData []byte, resourceProvider ResourceProvider) ([]byte, bool, error)
DiffPatch compares original and modified YAML content, generates a patch, and applies it to target data
func DiffPatchWithOptions ¶
func DiffPatchWithOptions(original, modified, targetData []byte, resourceProvider ResourceProvider, omitAdditions bool, options *api.FunctionOptions) ([]byte, bool, error)
DiffPatchWithOptions compares original and modified YAML content, generates a patch, and applies it to target data If omitAdditions is true, mutations of type MutationTypeAdd are filtered out before applying the patch
func EnrichMergeKeysFromDoc ¶ added in v0.1.15
func EnrichMergeKeysFromDoc(doc *gaby.YamlDoc, resourceProvider ResourceProvider, attr *api.AttributeValue)
EnrichMergeKeysFromDoc extracts merge keys from the resolved path of an AttributeValue and adds them as NeededPreferred properties. For each numeric array index in the path, it looks up the merge key via MergeKeyForPath and reads the value from the document. For example, path "spec.template.spec.volumes.1.configMap.name" with merge key "name"="config" at volumes[1] yields NeededPreferred["Name"] = "config".
func EscapeDotsInPathSegment ¶
EscapeDotsInPathSegment escapes any dots in a path segment for use in whole-path searches because path segments are separated by dots. TODO: Escape more special characters?
func ExtractCommentKeys ¶ added in v0.1.25
ExtractCommentKeys removes comment keys from the top level of a map, returning them as a separate map from comment key to comment text. The input map is modified in place.
func ExtractCommentsFromData ¶ added in v0.1.25
ExtractCommentsFromData recursively extracts all comment keys from a data tree, returning the cleaned data and a flat map of dot-path to comment text.
func FindMutationIndex ¶
func FindMutationIndex(mutationSources api.ResourceMutationList, resource api.ResourceInfo, path api.ResolvedPath) (int64, bool)
FindMutationIndex looks up the mutation index for a specific resource and path in a ResourceMutationList. It matches the resource by ResourceTypeAndName, handling aliases and scope changes (same pattern as AddMutations). For the path, it walks up parent paths to find the most specific mutation index, falling back to the resource-level index if no path-level match is found. Returns the mutation index and true if found.
func FindResourceDoc ¶ added in v0.1.15
func FindResourceDoc( parsedData gaby.Container, resourceProvider ResourceProvider, target *api.ResourceInfo, ) (*gaby.YamlDoc, *api.ResourceInfo)
FindResourceDoc finds the document in parsedData that best matches the given target ResourceInfo. It uses the same matching hierarchy as ComputeMutations:
- Exact ResourceName or ResourceNameWithoutScope match
- ResourceTypesAreSimilar as a prerequisite for any match
Returns the matching doc and its ResourceInfo, or (nil, nil) if no match is found.
func FindYAMLPathsByValue ¶
func FindYAMLPathsByValue(parsedData gaby.Container, resourceProvider ResourceProvider, matcher ValueMatcher, options *api.FunctionOptions) api.AttributeValueList
FindYAMLPathsByValue searches for all paths whose scalar value is matched by matcher in a YAML structure and returns an api.AttributeValueList. The matched value stored in each AttributeValue is the actual value found at the path, so callers (e.g. search-replace) can transform it.
func FunctionInvocationsEqual ¶
func FunctionInvocationsEqual(fi1, fi2 *api.FunctionInvocation) bool
FunctionInvocationsEqual reports whether two function invocations match.
func GetMutationOptions ¶
func GetMutationOptions(doc *gaby.YamlDoc, resourceProvider ResourceProvider) []string
GetMutationOptions reads the MutationOptions value from a YAML document using the resource provider's context path.
func GetNeededPaths ¶
func GetNeededPaths[T api.Scalar]( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, options *api.FunctionOptions, ) (api.AttributeValueList, error)
GetNeededPaths traverses the specified path patterns of the specified resource types and returns an api.AttributeValueList containing the values and registered information about all of the found attributes matching the path patterns that Need values. Currently "Need" is determined using placeholder values, 999999999 (9 9s) for integers. Use only for ints. Bools have no placeholder value. Use GetNeededStringPaths for strings.
func GetNeededStringPaths ¶
func GetNeededStringPaths( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, options *api.FunctionOptions, ) (api.AttributeValueList, error)
GetNeededStringPaths traverses the specified path patterns of the specified resource types and returns an api.AttributeValueList containing the values and registered information about all of the found string attributes matching the path patterns that Need values. Currently "Need" is determined using placeholder values, "confighubplaceholder" for strings. It can also extract fields embedded in strings using registered embedded accessors.
func GetPathRegistryForAttributeName ¶
func GetPathRegistryForAttributeName( resourceProvider ResourceProvider, attributeName api.AttributeName, ) api.ResourceTypeToPathToVisitorInfoType
GetPathRegistryForAttributeName returns the registry for the specified attribute to pass to a visitor function. If the attribute has a non-empty AttributeGroup, the registries for all attributes in the group are combined and returned.
func GetPathVisitorInfo ¶
func GetPathVisitorInfo(resourceProvider ResourceProvider, resourceType api.ResourceType, path api.UnresolvedPath) *api.PathVisitorInfo
GetPathVisitorInfo returns the path visitor specification for the specified path within the specified resource type to pass to a visitor function. It searches all attribute names in the path registry for the normalized path. GetPathVisitorInfo returns the PathVisitorInfo for the specified path. It searches all attribute names in the path registry, checking the specific resource type across all attributes first, then falling back to ResourceTypeAny. This ensures a specific resource type match always takes priority. The first match provides the base Details (getter/setter invocations). IsNeeded/IsProvided flags and Enricher are collected from all matches. Getter/setter invocations are NOT merged across attribute names because they carry resource-type-specific arguments.
func GetPaths ¶
func GetPaths[T api.Scalar]( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, options *api.FunctionOptions, ) (api.AttributeValueList, error)
GetPaths traverses the specified path patterns of the specified resource types and returns an api.AttributeValueList containing the values and registered information about all of the found attributes matching the path patterns. Use only for int and bool attributes. Use GetStringPaths for string attributes.
func GetPathsAnyType ¶
func GetPathsAnyType( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, dataType api.DataType, neededValuesOnly bool, providedValuesOnly bool, options *api.FunctionOptions, ) (api.AttributeValueList, error)
GetPathsAnyType traverses the specified path patterns of the specified resource types and returns an api.AttributeValueList containing the values and registered information about all of the found attributes matching the path patterns.
func GetRegisteredNeededPaths ¶
func GetRegisteredNeededPaths(resourceProvider ResourceProvider) api.ResourceTypeToPathToVisitorInfoType
GetRegisteredNeededPaths returns a combined registry of all paths marked as IsNeeded across all attributes in the path registry.
func GetRegisteredNeededPathsByProperty ¶ added in v0.1.42
func GetRegisteredNeededPathsByProperty(resourceProvider ResourceProvider, neededRequired []string) api.ResourceTypeToPathToVisitorInfoType
GetRegisteredNeededPathsByProperty returns a combined registry of all paths marked as IsNeeded whose Details.NeededRequired map contains every key listed in neededRequired. Values of those required keys are not checked — only presence. This is useful for finding paths that participate in a particular kind of match (e.g., all resource references via the "ResourceType" key) regardless of whether the current value at the path is a placeholder.
func GetRegisteredNeededStringPaths ¶
func GetRegisteredNeededStringPaths( parsedData gaby.Container, resourceProvider ResourceProvider, options *api.FunctionOptions, ) (api.AttributeValueList, error)
GetRegisteredNeededStringPaths retrieves Needed values by scanning all attributes for paths marked as IsNeeded.
func GetRegisteredProvidedPaths ¶
func GetRegisteredProvidedPaths(resourceProvider ResourceProvider) api.ResourceTypeToPathToVisitorInfoType
GetRegisteredProvidedPaths returns a combined registry of all paths marked as IsProvided across all attributes in the path registry.
func GetRegisteredProvidedStringPaths ¶
func GetRegisteredProvidedStringPaths( parsedData gaby.Container, resourceProvider ResourceProvider, options *api.FunctionOptions, ) (api.AttributeValueList, error)
GetRegisteredProvidedStringPaths retrieves Provided values by scanning all attributes for paths marked as IsProvided. Resources with IgnoreProvided annotation are skipped.
func GetResourceCategoryTypeName ¶
func GetResourceCategoryTypeName(doc *gaby.YamlDoc, resourceProvider ResourceProvider) (api.ResourceCategory, api.ResourceType, api.ResourceName, error)
func GetResourceInfo ¶
func GetResourceInfo(doc *gaby.YamlDoc, resourceProvider ResourceProvider) (*api.ResourceInfo, error)
func GetStringPaths ¶
func GetStringPaths( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, options *api.FunctionOptions, ) (api.AttributeValueList, error)
GetStringPaths traverses the specified path patterns of the specified resource types and returns an api.AttributeValueList containing the values and registered information about all of the found string attributes matching the path patterns. It can also extract fields embedded in strings using registered embedded accessors.
func GetToolchainPath ¶
func GetToolchainPath(rp ResourceProvider) string
func GetVisitorMapForPath ¶
func GetVisitorMapForPath(resourceProvider ResourceProvider, rt api.ResourceType, path api.UnresolvedPath) api.ResourceTypeToPathToVisitorInfoType
GetVisitorMapForPath is used to get visitor info for a resolved path.
func GetVisitorOptions ¶ added in v0.1.15
func GetVisitorOptions(doc *gaby.YamlDoc, resourceProvider ResourceProvider) []string
GetVisitorOptions reads the VisitorOptions value from a YAML document using the resource provider's context path.
func InjectCommentKeys ¶ added in v0.1.25
InjectCommentKeys adds comment entries into a map.
func IsCommentKey ¶ added in v0.1.25
IsCommentKey returns true if the key matches the $comment$TYPE$TARGET pattern where TYPE is head, line, or foot. Equivalent to gaby.IsCommentKey.
func IsEmptyOrPlaceHolder ¶ added in v0.1.25
func IsIntPlaceHolderValue ¶ added in v0.1.32
func IsMultiLineString ¶ added in v0.1.14
IsMultiLineString returns true if the string contains embedded newlines (not just a trailing newline), indicating it is a multi-line string value that may benefit from line-level diffing. YAML scalar serialization via gaby appends a trailing newline, so a single-line value like "alice" becomes "alice\n" — this function correctly returns false for such values.
func IsPatchableString ¶ added in v0.1.14
IsPatchableString returns true if the string may benefit from structured or line-level patching rather than wholesale replacement. This includes:
- Multi-line strings (for line-level text diff)
- JSON objects or arrays (for structural JSON diff)
- Strings with YAML structure (for structural YAML diff)
func IsPlaceholderValue ¶ added in v0.1.32
IsPlaceholderValue returns true if the value is a placeholder that should be replaced with a default.
func IsStringPlaceHolderValue ¶ added in v0.1.32
func JoinPathSegments ¶
JoinPathSegments escapes any dots in path segments and joins them for use in whole-path searches.
func LeadingWhitespace ¶ added in v0.1.25
LeadingWhitespace returns the leading whitespace prefix of a line.
func LowerFirst ¶
LowerFirst lowercases the first character, which is useful for converting PascalCase to camelCase
func MatchesWhereResourceExpressions ¶
func MatchesWhereResourceExpressions(doc *gaby.YamlDoc, resourceInfo *api.ResourceInfo, expressions []*api.VisitorRelationalExpression) (bool, error)
MatchesWhereResourceExpressions evaluates each expression against a resource. For paths with the "ConfigHub." prefix, values are resolved from ResourceInfo metadata. For other paths, values are resolved from the resource's YAML document using YamlSafePathGetValueAnyType. Returns false if any expression doesn't match. Keep consistent with ValidWhereResourcePaths.
func MergeCommentsIntoData ¶ added in v0.1.25
MergeCommentsIntoData walks a parsed data tree and inserts comment keys at the corresponding map levels based on a flat comment map. The flat map uses dot-separated paths to indicate where in the nested structure the comment belongs. For example, "database.$comment$head$server" places the comment key "$comment$head$server" inside the "database" map.
func PatchMutations ¶
func PatchMutations(parsedData gaby.Container, mutationsPredicates, mutationsPatch, mutationsToSubtract api.ResourceMutationList, resourceProvider ResourceProvider, options *api.FunctionOptions) (gaby.Container, api.MutationConflictList, error)
PatchMutations applies a set of mutations to configuration data, effectively "replaying" recorded changes onto a YAML document. It's the inverse of ComputeMutations: whereas ComputeMutations determines what changed, PatchMutations applies the recorded changes.
In typical usage mutationsPatch is the diff produced by ComputeMutations against a different (or earlier) version of the same configuration — e.g., the diff between an upstream Unit's old and new revisions, applied to a downstream Unit. Because of that, mutationsPatch may reference resource names, alias names, or paths that don't match parsedData verbatim; PatchMutations does its own resource lookup (with alias fallback) and path resolution.
Three-way merge: pass mutationsToSubtract to subtract another mutation set (typically the diff between the merge base and the current target) from mutationsPatch first. This is how target-side changes are preserved against the upstream patch (see SubtractMutations). Pass nil (or an empty list) to skip subtraction.
Predicates: mutationsPredicates is the accumulated MutationSources of the data being patched (see AddMutations). When a Predicate is false at the resource or any ancestor path, that part of mutationsPatch is filtered out. Default Predicate=true means all changes are eligible. mutationsPredicates may be nil.
Algorithm:
Resource matching (per document in parsedData): look up the corresponding patch entry by ResourceTypeAndName, then by predicate aliases (so a renamed resource is still matched to its upstream patch entry).
Resource-level mutation:
| MutationType | Action | |------------------|--------------------------------------------------| | Add / Replace | Replace entire document with the mutation's Value| | Delete | Set document to nil (filtered on serialization) | | None | Skip (no changes) | | Update | Process path-level mutations |
Path-level mutation (for Update): sorted by api.SortedMutationMapEntries (numeric segments compared as integers, parents before children), then partitioned so all Deletes run before all non-Deletes. Deletes-first prevents a Delete with positional fallback from clobbering an Add at the same array parent.
Each path is resolved through ResolveAssociativeSegments, which honors merge keys and only falls back to a positional index when the element at that index has no merge-key field (legacy data) or the index is out of bounds. If the path can't be fully resolved, the operation is skipped — except for Add/Replace, which appends to the parent array (so a new merge-keyed element can be introduced even when its desired index is occupied by a different element). The append-on-clash rule trades position fidelity for data preservation; positional associative arrays such as initContainers will require an additional reorder pass to fully restore source-side ordering.
Predicate filtering: a path or any ancestor with Predicate=false in mutationsPredicates causes the path to be skipped.
Apply by type:
| MutationType | Action | |------------------|-------------------------------------------------------| | Add / Replace | Set value at the resolved path (overwrites) | | Update (scalar) | If MutationInfo.Patch is set, three-way text merge. | | | Otherwise replace (preserving YAML comments). | | Update (complex) | Recursive merge with the existing value (preserves | | | nested comments and unset fields). | | Delete | Remove the path from document (no-op if missing) |
After visiting all existing documents, any unmatched Add/Replace patch entries are parsed and appended as new documents to parsedData. Their per-path mutations are applied to the new document (no subtraction, no predicate filtering).
Errors are accumulated and joined; PatchMutations does its best to apply every patch it can rather than aborting on the first problem.
PatchMutations also returns a MutationConflictList recording every part of the patch that was not applied: SubtractMutations conflicts (forwarded from the subtract step), PredicateFiltered (resource-level and path-level), and UnresolvedPath (when an associative segment couldn't be matched against the target). The conflicts are advisory — the returned data already reflects the drops.
func PathIsResolved ¶
func RegisterPathsByAttributeName ¶
func RegisterPathsByAttributeName( resourceProvider ResourceProvider, attributeName api.AttributeName, resourceType api.ResourceType, pathInfos api.PathToVisitorInfoType, details *AttributeRegistrationDetails, isNeeded bool, isProvided bool, )
RegisterPathsByAttributeName registers the specified path visitor specifications under the designated attribute name and resource type, and adds the provided getter and setter invocations, merging with existing registrations at the same paths, if any. If requested, the registered paths will be normalized so that associative lookups and array indices will be converted to wildcards, which is desired when matching all paths to the attribute. AttributeNameResourceName is used for references to resource names. Other attribute names are used for specific setters and/or getters, especially for attributes that appear in multiple resource types and/or locations. Provided values are special in that they represent sources of values for attributes of the specified attribute name, though they are logically distinct kinds of attributes.
func ReplaceStringPlaceholder ¶ added in v0.1.76
ReplaceStringPlaceholder replaces all occurrences of the placeholder string PlaceHolderBlockApplyString in s with replacement, including named placeholders that consist of the placeholder string followed by additional alphabetic characters. Surrounding text is preserved, so "confighubplaceholder-http" becomes replacement + "-http" and "confighubplaceholdersubdomain.test.example.com" becomes replacement + ".test.example.com".
func Reset ¶
func Reset(parsedData gaby.Container, mutationsPredicates api.ResourceMutationList, resourceProvider ResourceProvider, options *api.FunctionOptions) error
Reset walks each path in mutationsPredicates and, where Predicate=true and the value at the corresponding location in parsedData is a string or int, sets the value back to the toolchain's placeholder marker (PlaceHolderBlockApplyString / PlaceHolderBlockApplyInt). Used by the "reset" function to revert the leaves last touched by a chosen subset of historical mutations to their unset state, leaving everything else alone.
func ResolveAssociativeSegments ¶
ResolveAssociativeSegments resolves ?key=value;@index segments in a path to numeric indices by looking up elements in the document. It tries key=value match first; if no element matches by merge-key value, it considers the positional index:
- Out of bounds: the index is used as-is. This preserves Add-as-append semantics (e.g., a new element being appended to an array) and is harmless for Delete since the caller checks existence before deleting.
- In bounds, element has no merge-key field: legacy data — fall back positionally.
- In bounds, element has a different merge-key value: a different element. The segment is left unresolved so the caller can skip the operation.
Returns the resolved path and a bool that is true only when every associative segment was resolved (by merge-key match, by out-of-bounds index, or by legacy fallback).
func ResolveConfigHubPath ¶ added in v0.1.28
func ResolveConfigHubPath(path string, resourceInfo *api.ResourceInfo) (any, error)
ResolveConfigHubPath resolves a ConfigHub.* metadata path against a ResourceInfo struct. Returns the resolved value, or an error if the path is unsupported. Keep consistent with ValidWhereResourcePaths in api.go.
func ResourceAndCategoryTypeMaps ¶
func ResourceAndCategoryTypeMaps(parsedData gaby.Container, resourceProvider ResourceProvider) ( resourceMap ResourceNameToCategoryTypesMap, categoryTypeMap ResourceCategoryTypeToNamesMap, err error, )
ResourceAndCategoryTypeMaps returns maps of all resources in the provided list of parsed YAML documents, from from names to categories+types and categories+types to names.
func ResourceTypesForAttribute ¶
func ResourceTypesForAttribute(attributeName api.AttributeName, resourceProvider ResourceProvider) []api.ResourceType
ResourceTypesForAttribute returns a list of resource types associated with the specified attribute.
func ResourceTypesForPathMap ¶
func ResourceTypesForPathMap(pathMap map[api.ResourceType][]string) []api.ResourceType
ResourceTypesForPathMap returns a list of resource types from a path map.
func SetPredicates ¶ added in v0.1.77
func SetPredicates(parsedData gaby.Container, mutations api.ResourceMutationList, resource api.ResourceInfo, predicates map[api.ResolvedPath]bool, resourceProvider ResourceProvider) (api.ResourceMutationList, []api.ResolvedPath)
SetPredicates sets the Predicate flag on path-level mutations of a single resource in mutations (typically a Unit's accumulated MutationSources), returning the updated list and the paths that could not be resolved.
The Predicate flag records whether the path is eligible to be overwritten by a merge: true means a merge may patch it, false marks it a protected local override. SetMutationPredicates consumes these stored values when no WhereMutation filter is supplied, so editing them changes what a subsequent upgrade/merge will overwrite.
For each (path, value) in predicates:
- Exact match: the entry at path has its Predicate set to value; its other fields (including Value) are left intact.
- No exact match: the closest ancestor present in the resource's PathMutationMap (or, failing that, the resource-level mutation) supplies the MutationType and Index, so the new, more-specific entry keeps the same provenance. The entry's Value is taken from the data at path (via YamlSafePathGetDoc) — NOT copied from the ancestor, whose Value is a broader block — and Patch is left empty (it is a line-diff that does not apply to a freshly-set value). Because predicate lookup during PatchMutations walks to the most specific ancestor, this scopes the predicate to path without disturbing the ancestor. This mirrors the parent-splitting in SubtractMutations' Case 3.
A path is returned in unresolved (and left unchanged) when its resource is absent, when it has neither an ancestor path nor a resource-level mutation to inherit from, or when it does not exist in the resource's data (so no Value can be extracted). parsedData and resourceProvider are used to locate the resource's document and read the value at each path. mutations is modified in place and also returned for convenience.
func SplitInlineComment ¶ added in v0.1.25
SplitInlineComment splits a value string into the clean value and inline comment. An inline comment is text after " #" (space-hash). Quoted values are not split. Returns the clean value and the comment text (without the # prefix). If there is no inline comment, comment is empty.
func StripAssociativeSegments ¶
StripAssociativeSegments converts ?key=value;@index segments to just the numeric index. For ?key=@index (direct index), extracts just the index. Non-associative segments are passed through as-is.
func StripCommentKeys ¶ added in v0.1.25
StripCommentKeys returns a deep copy of data with all comment keys removed. Works recursively on map[string]any and []any. Non-map, non-slice values are returned as-is.
func StripComments ¶
StripComments removes all comments from YAML data while preserving the structure and values. This is useful when comparing YAML documents where comments should be ignored.
func SubtractMutations ¶
func SubtractMutations(mutations, subtractMutations api.ResourceMutationList) (api.ResourceMutationList, api.MutationConflictList)
SubtractMutations removes from mutations any changes that overlap with subtractMutations, implementing the "preserve target-side changes" half of three-way merging. Typically invoked from PatchMutations via its mutationsToSubtract argument.
Use case:
source : ComputeMutations(base, sourceEnd) // upstream changes target : ComputeMutations(base, target) // local customizations patch : SubtractMutations(source, target) // source changes that don't conflict
When PatchMutations applies patch to target, target-side customizations remain because the source paths that would have overwritten them have been removed.
Both operands are expected to be diffs produced by ComputeMutations: Add, Delete, Update, or None at the resource level. (Replace, which AddMutations may produce when accumulating, is handled here defensively but not expected.) Update at the resource level has an empty Value — all changes live in PathMutationMap.
Algorithm:
Resource matching: by ResourceTypeAndName, then AliasesWithoutScopes from either side (so renamed resources subtract correctly).
Resource-level subtraction:
| Subtract Type | Mutation Type | Result | |---------------|---------------|-------------------------------------------------| | Delete | Any | Drop (target removed the resource) | | Replace | Any | Drop (target redefined the resource) | | None | Any | Keep (target didn't change it) | | Any | None | Keep (source didn't change it) | | Update/Add | Delete | Keep source Delete; emit DeleteShadowed for | | | | each target mutation under it (the target's | | | | edits have nowhere to live once the resource | | | | is gone) | | Update/Add | Update/Add | Path-level subtraction |
Path-level subtraction: paths are walked using a NewPathPrefixIndex (binary search over a sorted path list) so prefix relationships are O(log n + k):
- Case 1 (exact match): subtract has the same path → drop the source path. - Case 2 (subtract is ancestor): subtract has spec.containers.0 and source has spec.containers.0.image → drop the source path (parent was changed in target). - Case 3 (subtract is descendant): subtract has spec.containers.0.image and source has spec.containers.0 (whole block). If the source path is a Delete, keep it and emit a DeleteShadowed conflict for each target child path that's being erased — once the parent is gone the child changes can't apply. Otherwise keep the source path and splice in subtract's more-specific paths so PatchMutations' parent-before-child processing lets target's change win.
If subtraction empties an Update's PathMutationMap, the resource-level type downgrades to None.
Returns the patch with subtractions applied, plus a MutationConflictList recording every drop (resource-level and path-level) so callers can surface them as merge conflicts. The conflicts are advisory — the returned ResourceMutationList already reflects the drops.
Key behaviors:
- Target precedence: subtractMutations always wins where it overlaps.
- Alias awareness: matches resources across renames.
- Partial expansion: only splits a parent path when subtract has finer-grained conflicts under it; unaffected branches stay whole.
func TransformConfig ¶
func TransformConfig( originalData []byte, resourceProvider ResourceProvider, transform func(parsedData gaby.Container) ([]byte, error), options *api.FunctionOptions, ) ([]byte, bool, error)
TransformConfig applies a mutation function to configuration data, preserving YAML comments by diffing the changes and patching them onto the original data. This is a general-purpose mechanism that can be reused for any config transformation that operates on comment-stripped data (Starlark, CEL, etc.).
The transform function receives comment-stripped parsed YAML and returns modified YAML bytes. If the transform function returns nil bytes, the original data is returned unchanged.
func UpdatePathsFunction ¶
func UpdatePathsFunction[T api.Scalar]( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, updater func(T, VisitorContext) T, upsert bool, options *api.FunctionOptions, ) error
UpdatePathsFunction traverses the specified path patterns of the specified resource types. The updater function simply needs to return the new attribute value, which must be of the type of the generic type parameter.
func UpdatePathsFunctionDoc ¶
func UpdatePathsFunctionDoc( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, updater func(*gaby.YamlDoc, VisitorContext) *gaby.YamlDoc, upsert bool, options *api.FunctionOptions, ) error
UpdatePathsFunctionDoc traverses the specified path patterns of the specified resource types. The updater function simply needs to return the new attribute value, which must be a YamlDoc.
func UpdatePathsSetterArgument ¶
func UpdatePathsSetterArgument( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, upsert bool, options *api.FunctionOptions, ) error
UpdatePathsSetterArgument traverses the specified path patterns of the specified resource types. For each path, if the visitor context has Details with a SetterInvocation using VisitorSetterInvocationFunctionName, the value at the path is set to the first argument's Value. Supports string, int, and bool values. Skips paths where the current value is already set to a non-placeholder value. Otherwise, the path is not updated.
func UpdatePathsValue ¶
func UpdatePathsValue[T api.Scalar]( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, newValue T, upsert bool, options *api.FunctionOptions, ) error
UpdatePathsValue traverses the specified path patterns of the specified resource types and updates the attributes with the provided value.
func UpdateStringPaths ¶
func UpdateStringPaths( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, newValue string, upsert bool, options *api.FunctionOptions, ) error
UpdateStringPaths traverses the specified path patterns of the specified resource types and updates the attributes with the provided value. It can also inject fields embedded in strings using registered embedded accessors.
func UpdateStringPathsFunction ¶
func UpdateStringPathsFunction( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, updater func(string) string, upsert bool, options *api.FunctionOptions, ) error
UpdateStringPathsFunction traverses the specified path patterns of the specified resource types. The updater function simply needs to return the new attribute value. It can also inject fields embedded in strings using registered embedded accessors.
func VetPathsSetterArgument ¶
func VetPathsSetterArgument( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, resourceProvider ResourceProvider, options *api.FunctionOptions, ) (api.ValidationResult, error)
VetPathsSetterArgument traverses the specified path patterns and validates that current values match the expected default values from $visitor setter invocations. Returns a ValidationResult with Passed=false and FailedAttributes listing any mismatched paths.
func VisitPaths ¶
func VisitPaths[T api.Scalar]( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, output any, resourceProvider ResourceProvider, visitor VisitorFunc[T], upsert bool, options *api.FunctionOptions, ) (any, error)
VisitPaths is a simple wrapper of the base visitor function. It traverses the specified path patterns of the specified resource types within the parsed configuration YAML document list.
func VisitPathsAnyType ¶
func VisitPathsAnyType( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, output any, resourceProvider ResourceProvider, visitor VisitorFuncAnyType, upsert bool, options *api.FunctionOptions, ) (any, error)
VisitPathsAnyType is a simple wrapper of the base visitor function. It traverses the specified path patterns of the specified resource types within the parsed configuration YAML document list.
func VisitPathsDoc ¶
func VisitPathsDoc( parsedData gaby.Container, resourceTypeToPaths api.ResourceTypeToPathToVisitorInfoType, keys []any, output any, resourceProvider ResourceProvider, visitor VisitorFuncDoc, upsert bool, options *api.FunctionOptions, ) (any, error)
VisitPathsDoc is the base visitor function. It traverses the specified path patterns of the specified resource types within the parsed configuration YAML document list.
func VisitResources ¶
func VisitResources(parsedData gaby.Container, output any, resourceProvider ResourceProvider, visitor ResourceVisitorFunc) (any, error)
VisitResources iterates over all of the resources/elements in a configuration unit and passes metadata about the resource as well as the document itself to a visitor function.
func VisitResourcesFiltered ¶
func VisitResourcesFiltered(parsedData gaby.Container, output any, resourceProvider ResourceProvider, options *api.FunctionOptions, visitor ResourceVisitorFunc) (any, error)
VisitResourcesFiltered iterates over resources, skipping those that don't match the WhereResourceExpressions in options or that fall outside its ResourceIndexes. The two restrictions are AND-ed. When options has neither, it behaves identically to VisitResources.
func VisitorInfoEqual ¶
func VisitorInfoEqual(pathVisitorInfo1, pathVisitorInfo2 *api.PathVisitorInfo, compareFunctions bool) bool
VisitorInfoEqual reports whether two path visitor specifications, optionally including getter and setter invocations, match.
func YamlSafePathGetDoc ¶
func YamlSafePathGetDoc( doc *gaby.YamlDoc, resolvedPath api.ResolvedPath, notFoundOk bool, ) (*gaby.YamlDoc, bool, error)
YamlSafePathGetDoc returns a document node at a fully resolved path and whether it was found. An error indicates a parsing error. An error is also returned if the path is expected to exist.
func YamlSafePathGetValue ¶
func YamlSafePathGetValue[T api.Scalar]( doc *gaby.YamlDoc, resolvedPath api.ResolvedPath, notFoundOk bool, ) (T, bool, error)
YamlSafePathGetValue returns a value at a fully resolved path and whether it was found. An error indicates a parsing error or that the value was not of the expected type.
func YamlSafePathGetValueAnyType ¶
func YamlSafePathGetValueAnyType( doc *gaby.YamlDoc, resolvedPath api.ResolvedPath, notFoundOk bool, ) (any, bool, error)
YamlSafePathGetValueAnyType returns a value at a fully resolved path and whether it was found. An error indicates a parsing error.
Types ¶
type AttributeEnricher ¶ added in v0.1.15
AttributeEnricher is a function that enriches an AttributeValue with properties after it is extracted by a visitor. It receives the resource doc for context and a flag indicating whether the value is a provided value. It populates ProvidedProperties, NeededRequired, and/or NeededPreferred on the attribute's Details.
type AttributeRegistrationDetails ¶ added in v0.1.15
type AttributeRegistrationDetails struct {
GetterInvocation *api.FunctionInvocation
SetterInvocation *api.FunctionInvocation
api.AttributeNeedsProvidesDetails
Enricher AttributeEnricher
}
AttributeRegistrationDetails specifies getter/setter invocations and an optional Enricher function for use when registering paths via RegisterPathsByAttributeName.
type CommentType ¶ added in v0.1.25
type CommentType string
CommentType represents the position of a comment relative to its anchor element.
const ( // CommentHead is a comment that appears on the line(s) above its anchor. CommentHead CommentType = "head" // CommentLine is an inline comment on the same line as its anchor. CommentLine CommentType = "line" // CommentFoot is a comment that appears on the line(s) below its anchor. CommentFoot CommentType = "foot" )
func ParseCommentKey ¶ added in v0.1.25
func ParseCommentKey(key string) (CommentType, string, bool)
ParseCommentKey extracts the comment type and target key from a comment map key. Returns ("", "", false) if the key is not a comment key.
type EmbeddedAccessor ¶
type EmbeddedAccessor interface {
// ExistsP reports whether the specified attribute or subpart exists within
// the string at the specified YAML document node.
ExistsP(scalarYamlDoc *gaby.YamlDoc, path string) bool
// SetP sets the specified attribute or subpart within the string at the
// specified YAML document node.
SetP(scalarYamlDoc *gaby.YamlDoc, value any, path string) error
// Data returns the value of the specified attribute or subpart embedded
// within the string at the specified YAML document node.
Data(scalarYamlDoc *gaby.YamlDoc, path string) (any, error)
// Replace replaces the value of the specified attribute or subpart within
// the provided string.
Replace(currentFieldValue string, value any, path string) (string, error)
// Extract returns the value of the specified attribute or subpart within the
// provided string.
Extract(currentFieldValue, path string) (any, error)
}
EmbeddedAccessor is used to access attributes embedded in data formats encoded within string values within a YAML document. For instance, YAML might be encoded within a YAML value. Or it could be as simple as a structured string with distinct sections and separators, such as a container image or URL.
func GetEmbeddedAccessor ¶
func GetEmbeddedAccessor(embeddedAccessorType api.EmbeddedAccessorType, config string) (EmbeddedAccessor, error)
type ExactValueMatcher ¶ added in v0.1.76
type ExactValueMatcher struct {
Value any
}
ExactValueMatcher matches values that are equal to Value. It is used for non-string values such as the integer placeholder, where substring or regular expression matching does not apply.
func (ExactValueMatcher) Matches ¶ added in v0.1.76
func (m ExactValueMatcher) Matches(value any) bool
type JSONAccessor ¶ added in v0.1.14
type JSONAccessor struct{}
JSONAccessor is an EmbeddedAccessor that accesses fields within a JSON string value embedded in a YAML scalar. The path uses dot-separated segments to navigate the parsed JSON structure.
For example, given a YAML field containing the JSON string '{"a":{"b":"hello"}}':
- Extract(jsonStr, "a.b") returns "hello"
- Replace(jsonStr, "world", "a.b") returns '{"a":{"b":"world"}}'
The config string is not used (pass "" when creating).
func (*JSONAccessor) ExistsP ¶ added in v0.1.14
func (ja *JSONAccessor) ExistsP(scalarYamlDoc *gaby.YamlDoc, path string) bool
func (*JSONAccessor) Extract ¶ added in v0.1.14
func (ja *JSONAccessor) Extract(currentFieldValue, path string) (any, error)
type LineAccessor ¶ added in v0.1.14
type LineAccessor struct{}
LineAccessor is an EmbeddedAccessor that accesses individual lines of a multi-line string value by line number. The path is a 1-based line number (as a string).
For example, given a multi-line string "line one\nline two\nline three\n":
- ExistsP(doc, "2") returns true
- Data(doc, "2") returns "line two"
- SetP(doc, "new line two", "2") replaces line 2
- Extract("line one\nline two\n", "1") returns "line one"
The config string is not used (pass "" when creating).
func (*LineAccessor) ExistsP ¶ added in v0.1.14
func (la *LineAccessor) ExistsP(scalarYamlDoc *gaby.YamlDoc, path string) bool
func (*LineAccessor) Extract ¶ added in v0.1.14
func (la *LineAccessor) Extract(currentFieldValue, path string) (any, error)
type LintConfig ¶ added in v0.1.25
type LintConfig struct {
NoAnchors bool // Ban anchors (&anchor) and aliases (*alias)
NoEmptyValues bool // Ban implicit null values (key: with no value)
NoDuplicateKeys bool // Ban duplicate keys in mappings
NoTruthy bool // Ban unquoted yes/no/on/off/y/n (YAML 1.1 booleans)
NoOctalValues bool // Ban old-style octal integers (0755, 010)
}
LintConfig controls which lint rules are enabled.
func DefaultLintConfig ¶ added in v0.1.25
func DefaultLintConfig() LintConfig
DefaultLintConfig returns a LintConfig with all rules enabled.
type LintFinding ¶ added in v0.1.25
type LintFinding struct {
Rule string // Rule identifier, e.g., "no-anchors", "no-truthy"
Message string // Human-readable description of the violation
Path string // Dot-notation path to the offending node, e.g., "spec.containers.0.image"
Line int // 1-based line number from the source YAML
Column int // 1-based column number from the source YAML
}
LintFinding represents a single lint rule violation found in a YAML document.
func LintBytes ¶ added in v0.1.25
func LintBytes(data []byte) ([]LintFinding, error)
LintBytes parses raw YAML bytes into a yaml.Node tree and lints it. This is a convenience function for standalone use outside of gaby. It handles a single YAML document; for multi-document YAML, use LintNode with each document's node separately.
func LintNode ¶ added in v0.1.25
func LintNode(node *yaml.Node, config LintConfig) []LintFinding
LintNode walks a yaml.Node tree and returns all lint findings. The node may be a DocumentNode (from yaml.Unmarshal) or a MappingNode/SequenceNode (from kyaml's Parse or gaby's YNode).
type MergeKeyEntry ¶ added in v0.1.15
type MergeKeyEntry struct {
Key string // merge key field name (e.g., "name")
Value string // merge key value (e.g., "config")
}
MergeKeyEntry represents a merge key/value pair extracted from an associative path segment.
func ExtractMergeKeysFromPath ¶ added in v0.1.15
func ExtractMergeKeysFromPath(path string) []MergeKeyEntry
ExtractMergeKeysFromPath extracts merge key/value pairs from associative path segments. Path segments of the form ?key=value;@index yield {Key: key, Value: value}.
type MergeKeyLookup ¶
MergeKeyLookup is a function that returns the merge key field name for a given array path, if one exists. It is used by ComputeMutationsForDocs to match array elements by merge key value instead of positional index.
type RegexpAccessor ¶
RegexpAccessor is an EmbeddedAccessor that uses regular expressions to extract and insert subparts of a structured string value.
func (*RegexpAccessor) ExistsP ¶
func (ra *RegexpAccessor) ExistsP(scalarYamlDoc *gaby.YamlDoc, path string) bool
func (*RegexpAccessor) Extract ¶
func (ra *RegexpAccessor) Extract(currentFieldValue, path string) (any, error)
type RegexpMatcher ¶ added in v0.1.76
RegexpMatcher matches string values for which Regexp finds a match, providing sed-like regular expression matching.
func (RegexpMatcher) Matches ¶ added in v0.1.76
func (m RegexpMatcher) Matches(value any) bool
type ResolvedPathInfo ¶
type ResolvedPathInfo struct {
Path api.ResolvedPath
PathArguments []api.FunctionArgument
}
ResolvedPathInfo contains a fully resolved path and any named path parameters specified in the unresolved path expression (using ?, *?, or *@).
func ResolveAssociativePaths ¶
func ResolveAssociativePaths( doc *gaby.YamlDoc, unresolvedPath api.UnresolvedPath, resolvedPath api.ResolvedPath, upsert bool, accessor EmbeddedAccessor, ) ([]ResolvedPathInfo, error)
ResolveAssociativePaths resolves an associative path with associative lookups (?) and wildcards (*, *?, *@) into specific resolved paths and discovered path parameters. See the documentation for api.UnresolvedPath for more details. If accessor is non-nil, it is used as a fallback for associative lookups on scalar array elements where the element has no map fields (e.g., pflags like "--key=value").
type ResourceCategoryTypeToNamesMap ¶
type ResourceCategoryTypeToNamesMap map[api.ResourceCategoryType][]api.ResourceName
type ResourceInfoToDocMap ¶
type ResourceInfoToDocMap map[api.ResourceInfo]int
func ResourceToDocMap ¶
func ResourceToDocMap(parsedData gaby.Container, resourceProvider ResourceProvider) (resourceMap ResourceInfoToDocMap, err error)
ResourceToDocMap returns a map of all resources in the provided list of parsed YAML documents to their document index.
type ResourceNameToCategoryTypesMap ¶
type ResourceNameToCategoryTypesMap map[api.ResourceName][]api.ResourceCategoryType
type ResourceProvider ¶
type ResourceProvider interface {
DefaultResourceCategory() api.ResourceCategory
ResourceCategoryGetter(doc *gaby.YamlDoc) (api.ResourceCategory, error)
ResourceTypeGetter(doc *gaby.YamlDoc) (api.ResourceType, error)
ResourceNameGetter(doc *gaby.YamlDoc) (api.ResourceName, error)
// ResourceNameStableCoreGetter returns the stable core of the resource name, with
// generated prefixes and suffixes stripped. Returns empty string if not present.
ResourceNameStableCoreGetter(doc *gaby.YamlDoc) (api.ResourceName, error)
RemoveScopeFromResourceName(resourceName api.ResourceName) api.ResourceName
ScopelessResourceNamePath() api.ResolvedPath
SetResourceName(doc *gaby.YamlDoc, name string) error
ResourceTypesAreSimilar(resourceTypeA, resourceTypeB api.ResourceType) bool
TypeDescription() string
NormalizeName(name string) string
NameSeparator() string
ContextPath(contextField string) string
GetPathRegistry() api.AttributeNameToResourceTypeToPathToVisitorInfoType
GetAttributeRegistry() api.AttributeNameToAttributeDescriptor
GetRegistry() *ResourceProviderRegistry
// MergeKeyForPath returns the merge key field name for the given resource type
// and array path, if one exists. The path should use dot-separated segments
// where array indices may be numeric or wildcards. The implementation normalizes
// numeric indices to wildcards for lookup. Returns ("", false) if no merge key
// is defined for the path.
MergeKeyForPath(resourceType api.ResourceType, path string) (string, bool)
// IsMapKeyPath returns true if the given path is a freeform map (e.g., labels,
// annotations) whose children are dynamic keys rather than schema fields.
// During path normalization, child segments of map paths are converted to wildcards.
IsMapKeyPath(resourceType api.ResourceType, path string) bool
GetToolchainType() workerapi.ToolchainType
}
The ResourceProvider interface is used to perform toolchain-specific operations.
type ResourceProviderRegistry ¶ added in v0.1.15
type ResourceProviderRegistry struct {
PathRegistry api.AttributeNameToResourceTypeToPathToVisitorInfoType
AttributeRegistry api.AttributeNameToAttributeDescriptor
}
ResourceProviderRegistry holds the path and attribute registries common to all ResourceProvider implementations.
func NewResourceProviderRegistry ¶ added in v0.1.15
func NewResourceProviderRegistry() ResourceProviderRegistry
NewResourceProviderRegistry creates a new ResourceProviderRegistry with initialized maps.
func (*ResourceProviderRegistry) GetAttributeRegistry ¶ added in v0.1.15
func (r *ResourceProviderRegistry) GetAttributeRegistry() api.AttributeNameToAttributeDescriptor
func (*ResourceProviderRegistry) GetPathRegistry ¶ added in v0.1.15
func (r *ResourceProviderRegistry) GetPathRegistry() api.AttributeNameToResourceTypeToPathToVisitorInfoType
func (*ResourceProviderRegistry) GetRegistry ¶ added in v0.1.15
func (r *ResourceProviderRegistry) GetRegistry() *ResourceProviderRegistry
type ResourceTypeToPathPrefixSetType ¶
type ResourceTypeToPathPrefixSetType map[api.ResourceType]map[string]struct{}
type ResourceVisitorFunc ¶
type ResourceVisitorFunc func(doc *gaby.YamlDoc, output any, index int, resourceInfo *api.ResourceInfo) (any, []error)
ResourceVisitorFunc defines the signature of functions invoked by the resource visitor function.
type StringContainsMatcher ¶ added in v0.1.76
type StringContainsMatcher struct {
Substring string
}
StringContainsMatcher matches string values that contain Substring.
func (StringContainsMatcher) Matches ¶ added in v0.1.76
func (m StringContainsMatcher) Matches(value any) bool
type ValueMatcher ¶ added in v0.1.76
type ValueMatcher interface {
// Matches reports whether the given scalar value (string, int, float64,
// bool, etc.) matches.
Matches(value any) bool
}
ValueMatcher decides whether a scalar value found while traversing a YAML structure should be collected by FindYAMLPathsByValue.
type VisitorContext ¶
type VisitorContext struct {
api.AttributeInfo // includes Path and Info
Arguments []api.FunctionArgument
EmbeddedPath string
Accessor EmbeddedAccessor
PathVisitorInfo *api.PathVisitorInfo
}
VisitorContext contains information passed to visitor functions for each path traversed.
type VisitorFunc ¶
type VisitorFunc[T api.Scalar] func(doc *gaby.YamlDoc, output any, context VisitorContext, currentValue T) (any, error)
VisitorFunc defines the signature of functions invoked by the visitor functions.
type VisitorFuncAnyType ¶
type VisitorFuncAnyType func(doc *gaby.YamlDoc, output any, context VisitorContext, currentValue any) (any, error)
VisitorFuncAnyType defines the signature of functions invoked by the visitor functions.
type VisitorFuncDoc ¶
type VisitorFuncDoc func(doc *gaby.YamlDoc, output any, context VisitorContext, currentDoc *gaby.YamlDoc) (any, error)
VisitorFuncDoc defines the signature of functions invoked by the visitor function.
type YAMLAccessor ¶ added in v0.1.14
type YAMLAccessor struct{}
YAMLAccessor is an EmbeddedAccessor that accesses fields within a YAML string value embedded in a YAML scalar. The path uses dot-separated segments to navigate the parsed YAML structure.
For example, given a YAML field containing the string "a:\n b: hello\n":
- Extract(yamlStr, "a.b") returns "hello"
- Replace(yamlStr, "world", "a.b") returns "a:\n b: world\n"
The config string is not used (pass "" when creating).
func (*YAMLAccessor) ExistsP ¶ added in v0.1.14
func (ya *YAMLAccessor) ExistsP(scalarYamlDoc *gaby.YamlDoc, path string) bool
func (*YAMLAccessor) Extract ¶ added in v0.1.14
func (ya *YAMLAccessor) Extract(currentFieldValue, path string) (any, error)