Documentation
¶
Index ¶
- Constants
- Variables
- func AdjacentDefaultsPath(bundleDir string) (string, error)
- func DeployViolations(ctx context.Context, streams iostreams.IOStreams, b *spec.UDSBundle, ...) (map[string][]string, error)
- func FilterLevels(levels [][]*spec.Package, filterNames []string) ([][]*spec.Package, error)
- func MaterializeDefaultsFile(path string) ([]byte, error)
- func RemovalViolations(ctx context.Context, streams iostreams.IOStreams, b *spec.UDSBundle, ...) (map[string][]string, error)
- func ResolveBundlePath(ref string) string
- func ValidateConfig(cfg *UDSBundleConfig) error
- func ValidatePackageNames(names []string, packages []spec.Package) error
- type ConfigOptions
- type CyclicLocalDependencyError
- type DAG
- type DuplicateLocalError
- type EmptyParameterError
- type HCLParser
- func (p *HCLParser) ParseAndMaterializeBundleFile(ctx context.Context, path string) (*spec.UDSBundle, []byte, error)
- func (p *HCLParser) ParseBundleBytes(ctx context.Context, src []byte) (*spec.UDSBundle, error)
- func (p *HCLParser) ParseBundleConfig(_ context.Context, filePath string) (*UDSBundleConfig, error)
- func (p *HCLParser) ParseBundleFile(ctx context.Context, filePath string) (*spec.UDSBundle, error)
- type KeylessVerification
- type LocalEvaluationError
- type LocalsAttributeError
- type LocalsBlockError
- type PackageTraversal
- type Parser
- type SignatureVerification
- type UDSBundleConfig
- type UndefinedLocalDependencyError
- type Variables
Constants ¶
const ( // BundleDefaultsFileName is the name of the optional bundle-level defaults file. BundleDefaultsFileName = "defaults.uds.hcl" // MaxConcurrency is the upper bound for parallel package deploys within a level. MaxConcurrency = 25 )
const BundleFileName = "bundle.uds.hcl"
BundleFileName is the name of the bundle definition file.
Variables ¶
var ( ErrConfigRequired = errors.New("config is required") ErrConfigGlobalRequired = errors.New("config.Global is required") ErrConfigOptionsRequired = errors.New("config.Options is required") ErrInvalidConcurrency = errors.New("invalid concurrency") ErrInvalidTemporaryDirectory = errors.New("invalid temporary directory") ErrReadBundleFile = errors.New("cannot read bundle file") ErrParseHCL = errors.New("failed to parse HCL") ErrDecodeBundle = errors.New("failed to decode bundle") ErrDecodePackageMetadata = errors.New("failed to decode package metadata") ErrDecodePackageDependencies = errors.New("failed to decode package dependencies") ErrReadFile = errors.New("reading file") ErrInvalidFile = errors.New("invalid file") ErrUnexpectedHCLBody = errors.New("unexpected HCL body type") ErrReadDefaultsFile = errors.New("cannot read defaults file") ErrExtractLocals = errors.New("failed to extract locals") ErrEvaluateHCLExpression = errors.New("failed to evaluate HCL expression") ErrReadPackageDependencies = errors.New("failed to read depends_on") ErrInvalidPackageDependencies = errors.New("invalid package dependencies") ErrInvalidPackageReference = errors.New("invalid package reference") ErrReadConfigFile = errors.New("cannot read config file") ErrParseConfig = errors.New("failed to parse config HCL") ErrDecodeConfig = errors.New("failed to decode config") ErrReadVariables = errors.New("failed to read variables") ErrEvaluateVariables = errors.New("failed to evaluate variables") ErrConvertVariables = errors.New("failed to convert variables") ErrInvalidVariables = errors.New("invalid variables") ErrUnsupportedVariableType = errors.New("unsupported variable type") ErrParseDefaults = errors.New("failed to parse defaults HCL") ErrInvalidDefaults = errors.New("invalid defaults file") ErrUnknownPackageDependency = errors.New("unknown package dependency") ErrDependencyCycle = errors.New("dependency cycle detected") ErrPackageNotInBundle = errors.New("package is not in the bundle") ErrUnknownPackages = errors.New("unknown packages") ErrBuildDependencyGraph = errors.New("failed to build dependency graph") )
Functions ¶
func AdjacentDefaultsPath ¶
AdjacentDefaultsPath returns the optional defaults file next to bundleDir. Missing files are represented by an empty path; other filesystem errors are returned to the caller.
func DeployViolations ¶
func DeployViolations(ctx context.Context, streams iostreams.IOStreams, b *spec.UDSBundle, packageNames []string) (map[string][]string, error)
DeployViolations returns each selected package's dependencies that are not selected. An empty result means the deployment is safe.
func FilterLevels ¶
FilterLevels keeps only packages whose names appear in filterNames, preserving the topological level structure. When filterNames is empty, all levels are returned unchanged. Empty levels (after filtering) are dropped. Duplicate names are deduped. Returns an error if any requested name is not in the bundle.
func MaterializeDefaultsFile ¶
MaterializeDefaultsFile resolves file() calls in a defaults file.
func RemovalViolations ¶
func RemovalViolations(ctx context.Context, streams iostreams.IOStreams, b *spec.UDSBundle, packageNames []string) (map[string][]string, error)
RemovalViolations returns packages that would retain a dependency on each selected package after removal. An empty result means the removal is safe.
func ResolveBundlePath ¶
ResolveBundlePath resolves a user-provided bundle reference to the path of the bundle.uds.hcl file. If ref is a directory, the bundle file inside it is returned; otherwise ref is returned as-is.
Assumes the path has already been validated with ValidateBundlePath.
func ValidateConfig ¶
func ValidateConfig(cfg *UDSBundleConfig) error
ValidateConfig is the single entry point for validating a fully-resolved UDSBundleConfig. It runs nil-checks on the structure and then delegates field-level checks to focused sub-validators.
Call this once at the boundary where config is produced (e.g. from the ConfigResolver). Downstream consumers should trust the config and skip re-validation.
Types ¶
type ConfigOptions ¶
type ConfigOptions struct {
LogLevel string `hcl:"log_level,optional"`
Architecture string `hcl:"architecture,optional"`
PlainHTTP bool `hcl:"plain_http,optional"`
SkipTLSVerify bool `hcl:"skip_tls_verify,optional"`
TmpDir string `hcl:"tmp_dir,optional"`
Concurrency int `hcl:"concurrency,optional"`
}
ConfigOptions holds bundle-component CLI options from the options block. All fields are optional; unset values use the operation defaults.
type CyclicLocalDependencyError ¶
type CyclicLocalDependencyError struct {
Cycle []string
}
CyclicLocalDependencyError occurs when 2 or more variables reference each other resulting in a dependency cycle
func (*CyclicLocalDependencyError) Error ¶
func (e *CyclicLocalDependencyError) Error() string
type DAG ¶
type DAG struct {
// contains filtered or unexported fields
}
DAG represents a directed acyclic graph of package dependencies. Edges point from a package to the packages it depends on.
func BuildDependencyGraph ¶
func BuildDependencyGraph(ctx context.Context, streams iostreams.IOStreams, bundle *spec.UDSBundle) (*DAG, error)
BuildDependencyGraph constructs a DAG from bundle packages using hcl.Traversal. Each package is represented as a traversal "package.<name>", and dependencies are taken from the already-parsed PackageRef values in the Package struct. The graph is validated for missing references and cycles before being returned.
func (*DAG) Level ¶
Level returns the deployment level (wave) for a specific package. Level 0 packages have no dependencies, level 1 depends only on level 0, etc. Returns -1 if the package is not found or if levels cannot be computed.
func (*DAG) TopologicalLevels ¶
TopologicalLevels returns packages grouped by deployment "waves" or "levels". Packages within the same level have no dependencies on each other and CAN be deployed in parallel. Levels must be deployed sequentially (level 0 before level 1, etc.).
Uses Kahn's algorithm with level tracking. In-degree counts the number of unmet dependencies for each package. Packages with in-degree 0 form the current level and are "removed" from the graph by decrementing dependents' in-degrees.
Example for diamond pattern (A has no deps, B and C depend on A, D depends on B and C):
Level 0: [A] - deploy first, no dependencies Level 1: [B, C] - can deploy B and C in parallel after A completes Level 2: [D] - deploy after both B and C complete
func (*DAG) TopologicalSort ¶
TopologicalSort returns packages in deployment order (dependencies first). It flattens the levels from TopologicalLevels into a single slice.
type DuplicateLocalError ¶
DuplicateLocalError occurs when a local variable is declared twice in a single evaluation context
func (*DuplicateLocalError) Error ¶
func (e *DuplicateLocalError) Error() string
type EmptyParameterError ¶
type EmptyParameterError struct{ Name string }
func (EmptyParameterError) Error ¶
func (e EmptyParameterError) Error() string
type HCLParser ¶
type HCLParser struct {
// contains filtered or unexported fields
}
HCLParser implements Parser for HCL bundle definitions. Its architecture is exposed to bundle expressions as ${sys.arch}; an empty architecture uses the runtime default. Diagnostics are written to streams.
func NewHCLParser ¶
NewHCLParser creates a new HCLParser. arch is the effective target architecture exposed as ${sys.arch}; pass an empty string to use runtime.GOARCH. streams carries the leveled logger used for parse diagnostics.
func (*HCLParser) ParseAndMaterializeBundleFile ¶
func (p *HCLParser) ParseAndMaterializeBundleFile(ctx context.Context, path string) (*spec.UDSBundle, []byte, error)
ParseAndMaterializeBundleFile reads a source bundle once, using those bytes both for runtime evaluation and the self-contained artifact representation.
func (*HCLParser) ParseBundleBytes ¶
ParseBundleBytes parses HCL bundle content from an in-memory byte slice. ctx is accepted for cancellation/propagation; HCL parsing does not use it, and diagnostics are written via p.streams.
func (*HCLParser) ParseBundleConfig ¶
ParseBundleConfig reads and parses a config.uds.hcl file. It uses gohcl.DecodeBody to decode the options block via HCL struct tags on UDSBundleConfig, and hcl:",remain" to capture the free-form variables attribute which is then manually extracted and converted from cty.Value to Variables. The context parameter is currently unused as none of the HCL parsing methods supports cancellation.
func (*HCLParser) ParseBundleFile ¶
ParseBundleFile reads and parses an HCL bundle file with locals support. ctx is accepted for cancellation/propagation; HCL parsing does not use it, and diagnostics are written via p.streams.
type KeylessVerification ¶
type KeylessVerification struct {
CertificateIdentity string `hcl:"certificate_identity,optional"`
CertificateIdentityRegexp string `hcl:"certificate_identity_regexp,optional"`
CertificateOIDCIssuer string `hcl:"certificate_oidc_issuer,optional"`
CertificateOIDCIssuerRegexp string `hcl:"certificate_oidc_issuer_regexp,optional"`
TrustedRoot string `hcl:"trusted_root,optional"`
}
KeylessVerification holds keyless trust constraints from config.uds.hcl.
type LocalEvaluationError ¶
type LocalEvaluationError struct {
Name string
Diags hcl.Diagnostics
}
LocalEvaluationError occurs when a local variable is unable to be evaluated such as a call to file() with a file that does not exist
func (*LocalEvaluationError) Error ¶
func (e *LocalEvaluationError) Error() string
func (*LocalEvaluationError) Unwrap ¶
func (e *LocalEvaluationError) Unwrap() error
type LocalsAttributeError ¶
type LocalsAttributeError struct {
Diags hcl.Diagnostics
}
LocalsAttributeError occurs when there is a syntactical error and a local variable is unable to be parsed
func (*LocalsAttributeError) Error ¶
func (e *LocalsAttributeError) Error() string
func (*LocalsAttributeError) Unwrap ¶
func (e *LocalsAttributeError) Unwrap() error
type LocalsBlockError ¶
type LocalsBlockError struct {
Diags hcl.Diagnostics
}
LocalsBlockError is a generic error when unable to parse the locals blocks
func (*LocalsBlockError) Error ¶
func (e *LocalsBlockError) Error() string
func (*LocalsBlockError) Unwrap ¶
func (e *LocalsBlockError) Unwrap() error
type PackageTraversal ¶
PackageTraversal wraps a package with its HCL traversal. Bundle dependency expressions are represented as traversals so dependency resolution retains type and source-location context.
type Parser ¶
type Parser interface {
// ParseBundleFile reads and parses a bundle.uds.hcl file with locals support.
ParseBundleFile(ctx context.Context, filePath string) (*spec.UDSBundle, error)
// ParseBundleBytes parses in-memory bundle HCL without permitting file().
ParseBundleBytes(ctx context.Context, src []byte) (*spec.UDSBundle, error)
// ParseBundleConfig reads and parses a config.uds.hcl file.
ParseBundleConfig(ctx context.Context, filePath string) (*UDSBundleConfig, error)
}
Parser defines the interface for parsing bundle definitions and configuration files.
type SignatureVerification ¶
type SignatureVerification struct {
PublicKey string `hcl:"public_key,optional"`
Keyless *KeylessVerification `hcl:"keyless,block"`
}
SignatureVerification holds consumer-owned bundle signature trust material.
type UDSBundleConfig ¶
type UDSBundleConfig struct {
Options *ConfigOptions `hcl:"options,block"`
SignatureVerification *SignatureVerification `hcl:"signature_verification,block"`
Variables Variables // populated after decode from Remain
Remain hcl.Body `hcl:",remain"` // captures variables and any other unstructured top-level attributes
}
UDSBundleConfig represents the parsed content of config.uds.hcl. Variables are decoded from the remaining free-form HCL body after structured blocks.
type UndefinedLocalDependencyError ¶
type UndefinedLocalDependencyError struct {
Name string
// Position the missing variable was referenced at
Position hcl.Range
}
UndefinedLocalDependencyError occurs when an undefined local variable is referenced
func (*UndefinedLocalDependencyError) Error ¶
func (e *UndefinedLocalDependencyError) Error() string
type Variables ¶
Variables contains user-defined configuration values. Nested objects are represented as Variables and list-like values as []any.
func MergeVariables ¶
MergeVariables deep-merges variables from overrides into base, returning a new Variables map. The base is deep-copied so callers can mutate the result without affecting their inputs. Nested Variables are deep-merged; everything else (scalars, lists) is replaced wholesale, matching Helm overlay conventions.
func ParseDefaults ¶
ParseDefaults reads a defaults file from disk and validates it. A valid defaults file contains at most one top-level attribute named "variables" and no blocks. Returns the parsed Variables, or nil if the file has no variables. The context parameter is currently unused as none of the HCL parsing methods supports cancellation.
func ParseDefaultsBytes ¶
ParseDefaultsBytes parses defaults HCL without enabling file-backed expressions.
func (Variables) Flatten ¶
Flatten returns the top-level values as an uppercased string map suitable for Zarf's SetVariables passthrough. Only scalar types (string, float64, bool) are included; non-scalar values (lists, nested Variables, other types) are silently skipped and must be passed to Zarf via values_files instead.
Complex types are excluded because values_files is the proper channel for them. Templates already handle nested Variables natively, and skipping non-scalars steers authors toward the values_files path rather than introducing a footgun where chart authors would need to JSON-decode Zarf var tokens.
Example:
Input: Variables{"domain": "uds.dev", "ports": []any{1.0, 2.0}, "nested": Variables{"key": "val"}}
Output: map[string]string{"DOMAIN": "uds.dev"} (ports and nested skipped)