layout

package
v0.2.0-beta.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 3, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

README

Layout Module

Go Reference

The layout module is a sophisticated system for organizing and writing Kubernetes manifests to disk in directory structures that work with GitOps tools like Flux and ArgoCD.

Core Purpose

The layout module transforms Kure's in-memory stack representation (Clusters → Nodes → Bundles → Applications) into organized directory structures with proper kustomization.yaml files that GitOps tools can consume.

Key Components

1. ManifestLayout Structure
  • Central data structure representing a directory with its resources and children
  • Contains: Name, Namespace, Resources (K8s objects), Children (subdirectories)
  • Supports package-aware layouts for multi-OCI/Git scenarios
2. LayoutRules Configuration
  • NodeGrouping: How nodes are organized (GroupByName creates dirs, GroupFlat flattens)
  • BundleGrouping: How bundles within nodes are organized
  • ApplicationGrouping: How applications within bundles are organized
  • FilePer: How resources are written (FilePerResource vs FilePerKind)
  • FluxPlacement: Where/at what granularity Flux Kustomizations go — FluxSeparate, FluxIntegratedPerLayout (a CR per layout node), or FluxIntegratedPerBundle (CRs at bundle boundaries; children included as directories)
  • FileNaming: Resource file naming pattern (see File Naming Modes)
  • ClusterName: Optional cluster name prefix for cluster-aware directory paths
3. Two Main Walker Functions
  • WalkCluster(): Standard hierarchical layout (Node → Bundle → App structure)
  • WalkClusterByPackage(): Groups by PackageRef for multi-source scenarios
4. Writing System
  • WriteManifest(): Config-driven writing — uses Config to resolve file naming, kustomization mode, and directory structure
  • WriteToDisk(): Self-contained method on ManifestLayout — uses the layout's own FileNaming and FluxPlacement fields
  • WriteToTar(): Same as WriteToDisk but writes to a tar archive (used by Crane for OCI artifacts)
  • WritePackagesToDisk(): Package-based writing with sanitized directory names
  • All writers auto-generate kustomization.yaml files with proper resource references

Directory Structure Patterns

Standard Layout (WalkCluster)
clusters/
  cluster-name/
    node1/
      bundle1/
        app1/
          manifest-files.yaml
          kustomization.yaml
        app2/...
      bundle2/...
    node2/...
Package-Based Layout (WalkClusterByPackage)
oci-packages/
  cluster/
    web/
      app-manifests.yaml
git-packages/
  cluster/
    monitoring/
      app-manifests.yaml
Flat Layout (GroupFlat rules)
clusters/
  cluster-name/
    all-manifests-together.yaml
    kustomization.yaml

GitOps Tool Compatibility

Flux Integration
  • Uses spec.path: ./clusters/cluster-name/node format
  • Auto-generates kustomization.yaml files
  • Supports recursive discovery of manifests
  • Handles FluxSeparate vs FluxIntegratedPerLayout placement modes
ArgoCD Integration
  • Uses spec.source.path: clusters/cluster-name/node format
  • Requires explicit kustomization.yaml files (no auto-discovery)
  • Each target directory needs its own Application

Advanced Features

Package Reference Support
  • Tracks different source types (OCIRepository, GitRepository, Bucket)
  • Enables multi-source deployments with proper isolation
  • Sanitizes package keys into valid directory names
Flexible File Organization
  • FilePerResource: Each K8s object gets its own file
  • FilePerKind: Group objects by Kind (all Services together, etc.)
  • AppFileSingle: All app resources in one file
File Naming Modes

Controls how resource YAML files are named:

Mode Format Example
FileNamingDefault {namespace}-{kind}-{name}.yaml default-service-web.yaml
FileNamingKindName {kind}-{name}.yaml service-web.yaml

FileNamingKindName drops the namespace prefix, which is useful when each application already has its own directory (e.g., Pattern A / CentralizedControlPlane). The naming mode is propagated through all writers: WriteManifest, WriteToDisk, and WriteToTar.

Kustomization Generation
  • KustomizationExplicit: Lists all manifest files explicitly
  • KustomizationRecursive: References subdirectories only
  • Smart handling of cross-references and child relationships
Extra Files and ConfigMap Generators

ManifestLayout.ExtraFiles lets callers attach arbitrary files (e.g. a values.yaml) into a layout's directory alongside the resource YAMLs. ManifestLayout.ConfigMapGenerators adds entries to a configMapGenerator: section in the generated kustomization.yaml. kustomize appends a content-hash suffix to the generated ConfigMap name and rewrites references (e.g. HelmRelease.spec.valuesFrom) on build, so any change to the source file forces re-reconciliation — the canonical FluxCD pattern for tracking Helm values changes.

LayoutAugmenter is an optional interface on stack.ApplicationConfig:

type LayoutAugmenter interface {
    AugmentLayout(layout *ManifestLayout) error
}

When app.Config implements it, the walker invokes AugmentLayout on the per-app ManifestLayout after resource generation, giving the config a chance to attach ExtraFiles, ConfigMapGenerators, and sub-ManifestLayout children. Only invoked on per-app layouts produced by the non-flat (GroupByName) walker paths; GroupFlat and umbrella layouts merge resources into shared parent layouts and are not currently augmented.

Sub-Layout Children and Flux Integration

Augmenters may attach sub-layouts as Children of a per-app ManifestLayout. In FluxIntegratedPerLayout mode each such child that is eligible (see below) receives a Flux Kustomization CR automatically placed in the parent layout's Resources.

Eligibility for CR generation. A child layout receives a Flux Kustomization CR when ALL of the following hold:

  • The ancestor node bundle's layout operates in FluxIntegratedPerLayout mode.
  • !child.UmbrellaChild
  • child.ApplicationFileMode != AppFileSingle
  • The ancestor bundle has a non-nil, non-empty SourceRef with both Kind and Name set. A nil, empty struct, or incomplete SourceRef (missing either field) causes IntegrateWithLayout to return a hard error — a Kustomization without spec.sourceRef is rejected by Flux.

This rule mirrors exactly what the writers use to emit flux-system-kustomization-{child.Name}.yaml from the parent's kustomization.yaml, so every file reference the writers produce has a backing CR. The integrator applies this rule recursively: it covers both direct children of the node layout and augmenter-added sub-layouts at any depth.

Naming Constraint

Child layout Name is used as the Flux Kustomization CR name in FluxIntegratedPerLayout mode (matching the filename emitted by the writers: flux-system-kustomization-{child.Name}.yaml). Flux Kustomization CRs live in the flux-system namespace, so names must be globally unique across all apps in the cluster — two CRs with the same metadata.name collide.

Augmenters are responsible for ensuring uniqueness. The recommended convention is to prefix each child name with the app name: {appName}-{hookGroupDir} (e.g. nginx-00-pre-install).

DependsOn

Set ManifestLayout.DependsOn to a list of sibling layout names. In FluxIntegratedPerLayout mode the layout integrator translates these into spec.dependsOn entries on the child's Kustomization CR, enabling ordered reconciliation between hook groups (e.g. pre-install → hooks → post-install).

ClusterName-Aware Layouts

Setting LayoutRules.ClusterName prepends the cluster name as a root directory, producing paths like {clusterName}/{nodeName}/... instead of {nodeName}/.... This is useful when a single repository manages multiple clusters.

Flatten Single Tier (opt-in)

LayoutRules.FlattenSingleTier collapses one vestigial intermediate directory layer when the wrapping Node adds no semantic value. Typical case: a flat single-bundle app whose caller wraps the Bundle in an extra Node (e.g. crane's apps Node), producing cluster-name/apps/manifests.yaml where the apps/ layer is redundant. Enabling the flag yields cluster-name/manifests.yaml directly.

Conservative collapse preconditions — ALL must hold:

  • LayoutRules.FlattenSingleTier is true.
  • The parent layout is top-level (Namespace has no path separator).
  • Parent has exactly one Children entry.
  • Parent has no own Resources.
  • The single child is not an UmbrellaChild.
  • The single child has no Children of its own (terminal layer).

Multi-tier apps with sub-Kustomizations are unaffected: the precondition that the child be terminal preserves them. Empty containers (only-Children) are also unaffected: the precondition requiring the parent to have no own resources doesn't apply to them.

When the layout participates in Flux integration, the flatten helper records redirect tables (nodeAliases for findLayoutNode lookups, pathRewrites for Spec.Path rewriting). IntegrateWithLayout consults the aliases during integrated placement and calls ApplyFlattenPathRewrites(root) before returning, regardless of placement mode (FluxIntegratedPerLayout or FluxSeparate). Direct callers using WalkCluster + IntegrateWithLayout (without going through CreateLayoutWithResources) get the rewrite for free.

Scoped to WalkCluster. WalkClusterByPackage is unaffected — its synthetic unnamed wrappers express package boundaries that the flatten helper would otherwise erroneously collapse.

Default: false — no behaviour change for existing callers.

Layout Presets

Three named presets provide pre-configured LayoutRules for common deployment patterns. Use LayoutRulesForPreset() to get rules, or ConfigForPreset() to get a matching Config.

Preset Pattern FluxPlacement NodeGrouping FileNaming
CentralizedControlPlane A FluxSeparate GroupFlat FileNamingKindName
SiblingControlPlane B FluxSeparate GroupByName FileNamingDefault
ParentDeployedControl C FluxIntegratedPerLayout GroupByName FileNamingDefault
rules, err := layout.LayoutRulesForPreset(layout.PresetCentralizedControlPlane)
cfg, err := layout.ConfigForPreset(layout.PresetCentralizedControlPlane)

Real-World Use Cases

  1. Simple Cluster: Single source, hierarchical structure
  2. Multi-OCI Deployment: Different services from different OCI registries
  3. Monorepo: Everything flattened into minimal directory structure
  4. Bootstrap Scenarios: Special handling for Flux/ArgoCD system components

Example Usage

// Create layout rules
rules := layout.DefaultLayoutRules()
rules.BundleGrouping = layout.GroupFlat
rules.ApplicationGrouping = layout.GroupFlat

// Walk cluster to create layout
ml, err := layout.WalkCluster(cluster, rules)
if err != nil {
    return err
}

// Write to disk
cfg := layout.DefaultLayoutConfig()
err = layout.WriteManifest("out/manifests", cfg, ml)

Key Files

  • types.go: Core types and configuration options
  • walker.go: Tree traversal algorithms (WalkCluster, WalkClusterByPackage)
  • manifest.go: ManifestLayout structure and package-based writing
  • write.go: Standard manifest writing with kustomization generation
  • config.go: Configuration and file naming conventions

The layout module essentially bridges the gap between Kure's programmatic resource construction and the file-based expectations of GitOps workflows, with extensive configurability for different organizational preferences and tool requirements.

Documentation

Overview

Package layout provides utilities for generating cluster directory layouts and for writing Kubernetes and Flux manifests to disk.

Flux Kustomizations and ArgoCD Applications reference directories in a Git repository using different fields. Flux uses `spec.path`, which must start with `./` and is always interpreted relative to the repository root. ArgoCD uses `spec.source.path` without the `./` prefix but with the same relative semantics.

When nodes or bundles live in nested subfolders, the path must point directly to the folder containing the manifests unless the directory tree only contains files for a single node or bundle. Flux will recursively auto-generate a `kustomization.yaml` when one is missing and include every manifest under the specified path. ArgoCD does not auto-generate a `kustomization.yaml` and therefore ignores nested directories unless they are referenced from a `kustomization.yaml` at the target path.

For example, consider the layout:

repo/
  clusters/
    prod/
      nodes/
        cp/
          kustomization.yaml
      bundles/
        monitoring/
          kustomization.yaml

The Flux Kustomization for the control-plane node uses:

spec.path: ./clusters/prod/nodes/cp

The equivalent ArgoCD Application uses:

spec.source.path: clusters/prod/nodes/cp

With this layout, each node or bundle is targeted individually. Pointing a Flux Kustomization at `./clusters/prod` would combine the `cp` and `monitoring` manifests into a single deployment because it would auto-generate a `kustomization.yaml` for the entire tree. ArgoCD will only process the manifests under `clusters/prod` itself unless a `kustomization.yaml` aggregates the subdirectories, so each subfolder must be referenced separately.

Package api defines configuration structures used to generate Kubernetes manifests and Flux resources.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApplyFlattenPathRewrites

func ApplyFlattenPathRewrites(root *ManifestLayout)

ApplyFlattenPathRewrites walks the layout tree, gathers all path rewrites recorded by flattenSingleTier collapses, and rewrites Spec.Path on every Flux Kustomization CR found in the tree's Resources. Idempotent: if no rewrites were recorded, returns immediately; on repeated invocations already-rewritten paths no longer match the rewrite keys, so subsequent passes are no-ops.

flattenInfo is intentionally left in place after a rewrite pass so that IntegrateWithLayout can be called multiple times on the same flattened layout — the integrator's findLayoutNode fallback depends on the nodeAliases remaining populated for the lifetime of the layout.

Called by the Flux integrator's IntegrateWithLayout before returning. Lives in the layout package because the flattenInfo field is unexported here.

func DefaultKustomizationFileName

func DefaultKustomizationFileName(name string) string

DefaultKustomizationFileName returns the standard Flux Kustomization file name.

func DefaultManifestFileName

func DefaultManifestFileName(namespace, kind, name string, mode FileExportMode) string

DefaultManifestFileName implements the standard file naming convention used by Kure. It writes either one file per resource or groups by kind depending on the FileExportMode.

func KindNameManifestFileName

func KindNameManifestFileName(_, kind, name string, mode FileExportMode) string

KindNameManifestFileName returns file names using {kind}-{name}.yaml format, without the namespace prefix. This is the default for Pattern A (CentralizedControlPlane) where per-app artifact directories make the namespace prefix redundant.

func WalkClusterByPackage

func WalkClusterByPackage(c *stack.Cluster, rules LayoutRules) (map[string]*ManifestLayout, error)

WalkClusterByPackage traverses a stack.Cluster and builds separate ManifestLayout trees for each unique PackageRef (OCI artifact). Returns a map where keys are PackageRef GVKs and values are the corresponding ManifestLayout trees. Nodes without PackageRef inherit from their parent, with nil representing the default package.

func WriteManifest

func WriteManifest(basePath string, cfg Config, ml *ManifestLayout) error

WriteManifest writes a ManifestLayout to disk using the provided configuration.

func WritePackagesToDisk

func WritePackagesToDisk(packages map[string]*ManifestLayout, basePath string) error

WritePackagesToDisk writes multiple package layouts to separate directory structures

Types

type ApplicationFileMode

type ApplicationFileMode string

ApplicationFileMode specifies how resources within an application are written.

The default is AppFilePerResource which mirrors the behaviour of FilePerResource and writes each generated resource to its own file. AppFileSingle groups all resources belonging to an application into a single manifest file.

const (
	// AppFilePerResource writes each application resource to its own file.
	AppFilePerResource ApplicationFileMode = "resource"
	// AppFileSingle writes all resources for an application into one file.
	AppFileSingle ApplicationFileMode = "single"
	// AppFileUnset indicates that no application file mode was specified.
	AppFileUnset ApplicationFileMode = ""
)

type Config

type Config struct {
	// ManifestsDir is the directory under which Kubernetes manifests are written.
	ManifestsDir string
	// FluxDir is the directory under which Flux manifests are written.
	FluxDir string
	// FilePer determines how resources are grouped into files when writing manifests.
	FilePer FileExportMode
	// ApplicationFileMode controls whether application resources are written
	// to a single file or split per resource. Defaults to AppFilePerResource.
	ApplicationFileMode ApplicationFileMode
	// KustomizationMode controls how kustomization.yaml files are generated.
	// Defaults to KustomizationExplicit.
	KustomizationMode KustomizationMode
	// FluxKustomizationMode overrides KustomizationMode based on FluxPlacement.
	// When a ManifestLayout's FluxPlacement matches a key in this map, the
	// corresponding KustomizationMode is used instead of the global
	// KustomizationMode. This allows different kustomization.yaml reference
	// styles per flux placement strategy.
	FluxKustomizationMode map[FluxPlacement]KustomizationMode
	// FileNaming controls the file naming pattern. When set, it determines
	// the ManifestFileNameFunc to use. If ManifestFileName is also set, it
	// takes precedence over FileNaming.
	FileNaming FileNamingMode
	// ManifestFileName formats the file name for a resource manifest.
	// Takes precedence over FileNaming when set.
	ManifestFileName ManifestFileNameFunc
	// KustomizationFileName formats the file name for a Flux Kustomization.
	KustomizationFileName KustomizationFileNameFunc
}

Config LayoutConfig defines rules for generating a cluster layout.

func ConfigForPreset

func ConfigForPreset(p LayoutPreset) (Config, error)

ConfigForPreset returns a Config configured for the given preset. Unknown presets return an error.

func DefaultConfigForProfile

func DefaultConfigForProfile(p Profile) Config

DefaultConfigForProfile returns a Config initialised with defaults for the given profile. Unknown profiles fall back to FluxProfile.

func DefaultLayoutConfig

func DefaultLayoutConfig() Config

DefaultLayoutConfig returns a configuration that matches the directory layout expected by FluxCD when writing manifests and Kustomizations.

func (Config) ResolveKustomizationMode

func (c Config) ResolveKustomizationMode(fp FluxPlacement) KustomizationMode

ResolveKustomizationMode returns the effective KustomizationMode for the given FluxPlacement. If FluxKustomizationMode contains an override for the placement, that value is used. Otherwise, the global KustomizationMode (or KustomizationExplicit when unset) is returned.

func (Config) ResolveManifestFileName

func (c Config) ResolveManifestFileName() ManifestFileNameFunc

ResolveManifestFileName returns the effective ManifestFileNameFunc for this Config. If ManifestFileName is set it is returned directly. Otherwise, FileNaming is used to select the function. If neither is set, DefaultManifestFileName is returned.

type ConfigMapGeneratorSpec

type ConfigMapGeneratorSpec struct {
	Name  string
	Files []string
}

ConfigMapGeneratorSpec describes a single kustomize configMapGenerator entry. Files are paths (relative to the layout directory) of files included in the generated ConfigMap.

type ExtraFile

type ExtraFile struct {
	Name    string
	Content []byte
}

ExtraFile is an arbitrary file written into a ManifestLayout's directory alongside the resource YAMLs.

type FileExportMode

type FileExportMode string

FileExportMode determines how resources are written to disk.

const (
	// FilePerResource writes each resource to its own file.
	FilePerResource FileExportMode = "resource"
	// FilePerKind groups resources by kind into a single file.
	FilePerKind FileExportMode = "kind"
	// FilePerUnset indicates that no export mode is specified.
	FilePerUnset FileExportMode = ""
)

type FileNamingMode

type FileNamingMode string

FileNamingMode controls the file naming pattern for manifest files.

const (
	// FileNamingDefault uses the standard {namespace}-{kind}-{name}.yaml format.
	FileNamingDefault FileNamingMode = "default"
	// FileNamingKindName uses the {kind}-{name}.yaml format, omitting the namespace prefix.
	FileNamingKindName FileNamingMode = "kind-name"
	// FileNamingUnset indicates no file naming preference.
	FileNamingUnset FileNamingMode = ""
)

type FluxPlacement

type FluxPlacement string

FluxPlacement determines how Flux Kustomizations are placed in the layout.

const (
	// FluxSeparate places all Flux Kustomizations in a separate directory.
	FluxSeparate FluxPlacement = "separate"
	// FluxIntegratedPerLayout places a Flux Kustomization CR inline for every
	// layout node, including augmenter-added child layouts. Children are
	// referenced from the parent kustomization.yaml as kustomization-<child>.yaml
	// CR files. Finest granularity; use when each child should be reconciled by
	// its own Flux Kustomization (e.g. hook-group dependsOn).
	FluxIntegratedPerLayout FluxPlacement = "integrated"
	// FluxIntegratedPerBundle places Flux Kustomization CRs inline at bundle/node
	// boundaries only; a bundle's interior (including augmenter-added child
	// layouts) is a single kustomize build, with children referenced as
	// directories. Coarser than PerLayout: Flux reconciles per bundle, kustomize
	// handles the interior. Use when the unit of Flux reconciliation is the
	// bundle, not each layout node.
	FluxIntegratedPerBundle FluxPlacement = "integrated-per-bundle"
	// FluxUnset indicates no flux placement preference.
	FluxUnset FluxPlacement = ""
)

type GroupingMode

type GroupingMode string

GroupingMode controls how nodes, bundles and applications are laid out on disk.

The default for all grouping modes is GroupByName which creates a directory per entity. GroupFlat places all entities in the same directory.

const (
	// GroupByName creates a directory for each item in the hierarchy.
	GroupByName GroupingMode = "name"
	// GroupFlat flattens the hierarchy placing all items in the same directory.
	GroupFlat GroupingMode = "flat"
	// GroupUnset indicates that no grouping preference was specified.
	GroupUnset GroupingMode = ""
)

type KustomizationFileNameFunc

type KustomizationFileNameFunc func(name string) string

KustomizationFileNameFunc returns the file name for a Flux Kustomization manifest.

type KustomizationMode

type KustomizationMode string

KustomizationMode determines how kustomization.yaml files reference manifests.

const (
	// KustomizationExplicit lists each manifest file in kustomization.yaml.
	KustomizationExplicit KustomizationMode = "explicit"
	// KustomizationRecursive references only subdirectories in kustomization.yaml.
	KustomizationRecursive KustomizationMode = "recursive"
	// KustomizationUnset indicates no kustomization mode preference.
	KustomizationUnset KustomizationMode = ""
)

type LayoutAugmenter

type LayoutAugmenter interface {
	AugmentLayout(layout *ManifestLayout) error
}

LayoutAugmenter is an optional interface that ApplicationConfig implementations can implement to attach extra files or configMapGenerator entries to their per-app ManifestLayout after resource generation. The walker invokes AugmentLayout when app.Config satisfies this interface.

The interface lives in the layout package (rather than pkg/stack alongside Validator) because ApplicationConfig — defined in pkg/stack — cannot reference *ManifestLayout without creating an import cycle: the layout package already imports pkg/stack.

type LayoutPreset

type LayoutPreset string

LayoutPreset identifies a named layout pattern that configures all layout dimensions into a known-valid combination. Presets are based on the layout patterns defined in the Wharf FluxCD layout research.

const (
	// PresetCentralizedControlPlane implements Pattern A: all Flux KS CRs in
	// dedicated aggregator directories, completely separate from payload. Best
	// suited for fleet management with many applications. Uses flat directory
	// grouping and {kind}-{name}.yaml file naming.
	PresetCentralizedControlPlane LayoutPreset = "CentralizedControlPlane"

	// PresetSiblingControlPlane implements Pattern B: Flux KS CRs in a
	// flux-system/ sibling directory within each artifact. Designed for
	// single-artifact or per-app artifact scenarios.
	PresetSiblingControlPlane LayoutPreset = "SiblingControlPlane"

	// PresetParentDeployedControl implements Pattern C: KS CRs live in the
	// payload of their parent Kustomization. Best suited for simple,
	// single-app deployments.
	PresetParentDeployedControl LayoutPreset = "ParentDeployedControl"
)

type LayoutRules

type LayoutRules struct {
	// NodeGrouping controls how nodes are written to disk. Defaults to
	// GroupByName.
	NodeGrouping GroupingMode
	// BundleGrouping controls how bundles are written to disk. Defaults to
	// GroupByName.
	BundleGrouping GroupingMode
	// ApplicationGrouping controls how applications are written to disk.
	// Defaults to GroupByName.
	ApplicationGrouping GroupingMode
	// ApplicationFileMode controls whether application resources are
	// combined into a single file or split per resource. Defaults to
	// AppFilePerResource.
	ApplicationFileMode ApplicationFileMode
	// FilePer sets the default file export mode for resources. Defaults to
	// FilePerResource.
	FilePer FileExportMode
	// ClusterName specifies a cluster name to prepend to all paths.
	// When set, creates clusters/{ClusterName}/... structure.
	ClusterName string
	// FluxPlacement determines how Flux Kustomizations are placed.
	// Defaults to FluxSeparate.
	FluxPlacement FluxPlacement
	// FileNaming controls the file naming pattern for manifest files.
	// Defaults to FileNamingDefault ({namespace}-{kind}-{name}.yaml).
	FileNaming FileNamingMode

	// FlattenSingleTier collapses a vestigial intermediate directory layer
	// produced by the walker when it adds no semantic value: a parent layout
	// with exactly one named child whose own children are empty and which is
	// not an UmbrellaChild, where the parent itself is a top-level layout
	// (Namespace has no path separator) with no own Resources.
	//
	// Typical case: flat single-bundle apps where the caller wraps the bundle
	// in an extra Node (e.g. crane's "apps" Node). Multi-tier apps with sub-
	// Kustomizations are unaffected — the collapse rules require the
	// intermediate to be terminal.
	//
	// Only effective for WalkCluster (not WalkClusterByPackage, which uses
	// synthetic unnamed wrappers to express package boundaries).
	//
	// When the layout participates in Flux integration, the flatten helper
	// records pathRewrites/nodeAliases on the absorbing layout.
	// IntegrateWithLayout consults aliases via findLayoutNode and calls
	// ApplyFlattenPathRewrites before returning, so generated Flux
	// Kustomization CRs resolve to the post-collapse directory.
	FlattenSingleTier bool
}

LayoutRules control how layouts are generated.

Zero values are interpreted as the defaults described in the field documentation.

func DefaultLayoutRules

func DefaultLayoutRules() LayoutRules

DefaultLayoutRules returns a LayoutRules instance populated with the documented default values.

func LayoutRulesForPreset

func LayoutRulesForPreset(p LayoutPreset) (LayoutRules, error)

LayoutRulesForPreset returns LayoutRules configured for the given preset. Unknown presets return an error.

func (LayoutRules) Validate

func (lr LayoutRules) Validate() error

Validate ensures the LayoutRules contain known option values.

type ManifestFileNameFunc

type ManifestFileNameFunc func(namespace, kind, name string, mode FileExportMode) string

ManifestFileNameFunc returns a file name for the given namespace, kind and resource name.

type ManifestLayout

type ManifestLayout struct {
	Name                string
	Namespace           string
	PackageRef          *schema.GroupVersionKind
	FilePer             FileExportMode
	ApplicationFileMode ApplicationFileMode
	Mode                KustomizationMode
	FluxPlacement       FluxPlacement  // Track flux placement mode for kustomization generation
	FileNaming          FileNamingMode // Controls resource file naming pattern
	Resources           []client.Object
	Children            []*ManifestLayout
	// ExtraFiles are arbitrary files written alongside resource YAMLs in this
	// layout's directory. Typical use: a values.yaml referenced by a
	// configMapGenerator entry. Augmenters (LayoutAugmenter) attach these.
	ExtraFiles []ExtraFile
	// ConfigMapGenerators emit a kustomize configMapGenerator: section in
	// kustomization.yaml. kustomize appends a content-hash suffix to each
	// generated ConfigMap name; resources referencing it (e.g.
	// HelmRelease.spec.valuesFrom) are rewritten to the suffixed name on
	// build, so any change to the source file forces re-reconciliation.
	ConfigMapGenerators []ConfigMapGeneratorSpec
	// UmbrellaChild marks this layout as rendered from a Bundle.Children
	// entry. When true, kustomization.yaml writers emit a
	// flux-system-kustomization-{Name}.yaml reference in the parent directory
	// (regardless of FluxPlacement), and the layout integrator places the
	// child's Flux Kustomization CR at the parent layout node rather than in
	// the child's own directory.
	UmbrellaChild bool
	// DependsOn lists sibling layout names whose Kustomization CRs must reconcile
	// before this layout's CR. In FluxIntegratedPerLayout mode the layout integrator
	// translates these into spec.dependsOn on the emitted Kustomization CR.
	// Augmenters (LayoutAugmenter) set this field; the integrator reads it.
	DependsOn []string
	// contains filtered or unexported fields
}

func FindByNodeAlias

func FindByNodeAlias(ml *ManifestLayout, nodePath string) *ManifestLayout

FindByNodeAlias walks the layout tree looking for a flattenInfo nodeAlias matching nodePath. Returns the absorbing layout, or nil if no alias matches. Used by the Flux integrator's findLayoutNode as a fallback when regular path-based search fails.

func WalkCluster

func WalkCluster(c *stack.Cluster, rules LayoutRules) (*ManifestLayout, error)

WalkCluster traverses a stack.Cluster and builds a ManifestLayout tree that mirrors the node and bundle hierarchy. Behaviour is controlled via LayoutRules. When BundleGrouping and ApplicationGrouping are set to GroupFlat, all application resources are written directly to their parent node's directory.

func (*ManifestLayout) FlattenInfoNodeAlias

func (ml *ManifestLayout) FlattenInfoNodeAlias(nodePath string) *ManifestLayout

FlattenInfoNodeAlias returns the absorbing layout for the given node path recorded on this layout's flattenInfo, or nil if no alias matches. Exposed for the Flux integrator's findLayoutNode fallback.

func (*ManifestLayout) FlattenInfoPathRewrites

func (ml *ManifestLayout) FlattenInfoPathRewrites() map[string]string

FlattenInfoPathRewrites returns the path-rewrite map recorded on this layout's flattenInfo, or nil. Exposed for ApplyFlattenPathRewrites.

func (*ManifestLayout) FullRepoPath

func (ml *ManifestLayout) FullRepoPath() string

func (*ManifestLayout) FullRepoPathWithPackage

func (ml *ManifestLayout) FullRepoPathWithPackage() string

FullRepoPathWithPackage returns the repository path including package-specific prefix

func (*ManifestLayout) WriteToDisk

func (ml *ManifestLayout) WriteToDisk(basePath string) error

func (*ManifestLayout) WriteToTar

func (ml *ManifestLayout) WriteToTar(w io.Writer) error

WriteToTar writes the ManifestLayout to a tar archive, mirroring the directory structure that WriteToDisk would produce. File paths use forward slashes and output is deterministic (sorted file names).

type Profile

type Profile string

Profile identifies a supported layout profile.

const (
	// FluxProfile represents defaults matching FluxCD conventions.
	FluxProfile Profile = "flux"
	// ArgoProfile represents defaults matching Argo CD conventions.
	ArgoProfile Profile = "argocd"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL