api

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 29, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package api defines the schemas the installer reads and writes:

  • Package (installer.yaml inside a package, hand-authored)
  • Inputs (user answers to wizard prompts)
  • Selection (chosen base + components, derived from Inputs by the wizard)
  • FunctionChain (resolved function invocations, executed by render)

Each schema is shaped as a Kubernetes-style document with apiVersion, kind, metadata, spec. They are stored as Kubernetes/YAML Units in ConfigHub today; later they may move to a ConfigHub/YAML toolchain when first-class entities exist for them.

Index

Constants

View Source
const (
	KindPackage       = "Package"
	KindInputs        = "Inputs"
	KindSelection     = "Selection"
	KindFunctionChain = "FunctionChain"
	KindFacts         = "Facts"
	KindLock          = "Lock"
	KindUpload        = "Upload"
)
View Source
const (
	// ArtifactType is the OCI artifactType set on the image manifest for
	// native installer packages.
	ArtifactType = "application/vnd.confighub.installer.package.v1+json"

	// ConfigMediaType is the media type of the config blob (a JSON-encoded
	// ConfigBlob document).
	ConfigMediaType = "application/vnd.confighub.installer.package.config.v1+json"

	// LayerMediaType is the media type of the single .tgz layer.
	LayerMediaType = "application/vnd.confighub.installer.package.tar+gzip"
)

OCI media types and annotation keys for native installer artifacts.

An installer artifact is a single-layer OCI image manifest where:

  • ArtifactType discriminates the artifact from Helm OCI charts and other unrelated artifacts in the same registry,
  • the config blob (ConfigMediaType) carries enough metadata for the resolver and `installer inspect` to operate without pulling the layer,
  • the single layer (LayerMediaType) is the deterministic .tgz produced by internal/bundle.
View Source
const (
	AnnotationName             = "installer.confighub.com/name"
	AnnotationVersion          = "installer.confighub.com/version"
	AnnotationKubeVersion      = "installer.confighub.com/kube-version"
	AnnotationInstallerVersion = "installer.confighub.com/installer-version"
)

OCI manifest annotation keys for installer-specific metadata. These mirror fields in ConfigBlob so registry-listing UIs can show name/version without fetching the config blob.

View Source
const (
	RenderedArtifactType    = "application/vnd.confighub.installer.rendered.v1+json"
	RenderedConfigMediaType = "application/vnd.confighub.installer.rendered.config.v1+json"
	RenderedLayerMediaType  = "application/vnd.oci.image.layer.v1.tar+gzip"
	RenderedLayerTitle      = "rendered-manifests.tar.gz"
)

Media types for OCI artifacts containing rendered Kubernetes objects.

The layer uses the standard OCI image-layer media type so Argo CD, Flux, ORAS, and other OCI consumers can unpack it without installer-specific support. Installer provenance and check results live in the config blob, outside the Kubernetes files consumed by delivery controllers.

View Source
const (
	AnnotationSourceReference = "installer.confighub.com/source-reference"
	AnnotationSourceDigest    = "installer.confighub.com/source-digest"
	AnnotationBase            = "installer.confighub.com/base"
	AnnotationObjectSetDigest = "installer.confighub.com/object-set-digest"
)
View Source
const APIVersion = "installer.confighub.com/v1alpha1"
View Source
const KindSigningPolicy = "SigningPolicy"
View Source
const LayerTitle = "package"

LayerTitle is the file/directory name set on the layer descriptor's org.opencontainers.image.title annotation. Combined with the file store's unpack annotation, this becomes the subdirectory name when pulling.

Variables

This section is empty.

Functions

func MarshalYAML

func MarshalYAML(v any) ([]byte, error)

MarshalYAML emits a deterministic, header-first YAML doc for any of the installer kinds.

func SniffKind

func SniffKind(data []byte) (apiVersion, kind string, err error)

SniffKind returns the apiVersion + kind of a single YAML doc without parsing the full body. Returns ("", "", err) on parse failure.

func SplitMultiDoc

func SplitMultiDoc(data []byte) ([][]byte, error)

SplitMultiDoc returns each YAML doc in data as a separate []byte. Empty docs are skipped.

Types

type Base

type Base struct {
	// Name is the slug used in Selection.spec.base.
	Name string `yaml:"name" json:"name"`
	// Path is the directory in the package tree containing kustomization.yaml.
	Path string `yaml:"path" json:"path"`
	// Default selects this base when the user does not pick one.
	Default bool `yaml:"default,omitempty" json:"default,omitempty"`
	// Description is shown by `installer doc`.
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
	// ExternalRequires scoped to this base (in addition to package-level requires).
	ExternalRequires []ExternalRequire `yaml:"externalRequires,omitempty" json:"externalRequires,omitempty"`
}

type BundleInfo

type BundleInfo struct {
	// InstallerVersion is the version of the installer CLI that produced
	// this artifact (from internal/version.Version).
	InstallerVersion string `json:"installerVersion,omitempty"`

	// LayerDigest is the sha256 digest of the package .tgz, in the
	// "sha256:<hex>" form. Matches the layer descriptor's Digest.
	LayerDigest string `json:"layerDigest"`

	// LayerSize is the size in bytes of the package .tgz.
	LayerSize int64 `json:"layerSize"`

	// Files is the list of paths in the .tgz, in tar order (sorted). Useful
	// for `installer inspect` and for resolver sanity checks.
	Files []string `json:"files"`
}

BundleInfo is the computed-at-bundle-time header.

type Collector

type Collector struct {
	// Command is the executable. May be relative (resolved against the package
	// root) or absolute. Required.
	Command string `yaml:"command" json:"command"`
	// Args are passed verbatim after Command. Optional.
	Args []string `yaml:"args,omitempty" json:"args,omitempty"`
	// Description is shown by `installer doc`.
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
}

Collector declares a fact-collection executable bundled in the package. The wizard runs it after answering inputs and writes its stdout (a YAML map) to out/spec/facts.yaml. The script may also write .env.secret files into the package working copy at paths its kustomize secretGenerator references; the installer never reads or uploads those files.

The wizard runs the command with the package root as the working directory and the following env vars set (parent env is also inherited so `cub` works):

INSTALLER_PACKAGE_DIR      absolute path to the package working copy
INSTALLER_WORK_DIR         absolute path to the parent working directory
INSTALLER_OUT_DIR          absolute path to <work-dir>/out
INSTALLER_NAMESPACE        value of --namespace
INSTALLER_BASE             chosen base name
INSTALLER_SELECTED         comma-separated selected component names
INSTALLER_INPUT_<NAME>     one variable per declared input (uppercased)

type Component

type Component struct {
	// Name is the slug used in Selection.spec.components.
	Name string `yaml:"name" json:"name"`
	// Path is the directory in the package tree containing the kind: Component
	// kustomization.yaml.
	Path string `yaml:"path" json:"path"`
	// Default selects this component when the user picks the `default`
	// preset in the wizard. Components without `default: true` are only
	// installed under the `all` preset or via explicit selection.
	Default bool `yaml:"default,omitempty" json:"default,omitempty"`
	// Description is shown by `installer doc`.
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
	// Requires names other Components that must be selected. Closure is
	// computed by the wizard's solver before render.
	Requires []string `yaml:"requires,omitempty" json:"requires,omitempty"`
	// Conflicts names Components that cannot be selected together.
	Conflicts []string `yaml:"conflicts,omitempty" json:"conflicts,omitempty"`
	// ValidForBases names Bases this Component is compatible with. Empty
	// means valid for all bases.
	ValidForBases []string `yaml:"validForBases,omitempty" json:"validForBases,omitempty"`
	// ExternalRequires scoped to this Component.
	ExternalRequires []ExternalRequire `yaml:"externalRequires,omitempty" json:"externalRequires,omitempty"`
	// Transformers is an optional component-scoped mixin: function groups
	// that only run when this component is selected. Appended to the
	// package-wide PackageSpec.Transformers in declaration order so the
	// resolved chain still runs in a single in-process executor pass.
	// Authored exactly like the package-wide list — same toolchain /
	// whereResource / invocations shape, same restricted Go template
	// surface ({{ .Namespace }}, {{ .Inputs.* }}, {{ .Selection.* }},
	// {{ .Facts.* }}, {{ .Package.* }}).
	Transformers []FunctionGroup `yaml:"transformers,omitempty" json:"transformers,omitempty"`
	// Validators is the analogous component-scoped validator list. Appended
	// to PackageSpec.Validators when this component is selected; same
	// "Mutating=false only" contract.
	Validators []FunctionGroup `yaml:"validators,omitempty" json:"validators,omitempty"`
}

type ConfigBlob

type ConfigBlob struct {
	// Bundle is the computed-at-bundle-time header (digests, file list,
	// installer-CLI version that produced the artifact).
	Bundle BundleInfo `json:"bundle"`
	// Manifest is the parsed installer.yaml from the bundled .tgz, included
	// here so `installer inspect` and the resolver can read it without
	// pulling the layer.
	Manifest *Package `json:"manifest"`
}

ConfigBlob is the JSON-encoded config blob attached to a native installer OCI artifact. It holds enough metadata for the resolver and `installer inspect` to operate without pulling the layer.

Field naming uses JSON tags only — the blob is always serialized as JSON (mediaType ConfigMediaType).

type ConflictRef

type ConflictRef struct {
	// Package is the OCI ref (oci://host/repo) of the excluded package.
	Package string `yaml:"package" json:"package"`
	// Version is a SemVer range; empty or "*" matches any version.
	Version string `yaml:"version,omitempty" json:"version,omitempty"`
	// Reason is shown in resolver error messages.
	Reason string `yaml:"reason,omitempty" json:"reason,omitempty"`
}

ConflictRef hard-excludes a package from the resolution set. The resolver fails if any dependency (direct or transitive) names a package matching one of these entries.

type Dependency

type Dependency struct {
	// Name is the local handle for this dependency within the parent
	// package. Used in lock files and error messages. Must be unique within
	// a package's Dependencies list.
	Name string `yaml:"name" json:"name"`

	// Package is the OCI ref (oci://host/repo) without a tag — the
	// resolver picks the tag matching Version.
	Package string `yaml:"package" json:"package"`

	// Version is a SemVer range expression (e.g. "^1.2.0", ">= 0.3, < 0.5",
	// "*"). Empty means "any version".
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// Selection pre-answers the dep's wizard. If nil, the dep's defaults
	// apply.
	Selection *DependencySelection `yaml:"selection,omitempty" json:"selection,omitempty"`

	// Inputs pre-answers the dep's wizard prompts (input name → value).
	Inputs map[string]any `yaml:"inputs,omitempty" json:"inputs,omitempty"`

	// Optional, when true, makes this dependency conditional on
	// WhenComponent being selected in the parent's Selection. Optional
	// without WhenComponent means the dep is followed if no parent
	// component disables it (today: always followed; reserved for future
	// nuance).
	Optional bool `yaml:"optional,omitempty" json:"optional,omitempty"`

	// WhenComponent names a parent Component whose selection turns this
	// dependency on. Mirrors Helm subchart conditions and Debian Recommends.
	WhenComponent string `yaml:"whenComponent,omitempty" json:"whenComponent,omitempty"`

	// Satisfies lists ExternalRequire entries from the parent's package
	// that this dependency provides. Lets the resolver mark
	// externalRequires as covered without a separate cluster probe.
	Satisfies []ExternalRequire `yaml:"satisfies,omitempty" json:"satisfies,omitempty"`
}

Dependency declares another installer package this package composes with. Multiple parents may request the same dependency; the resolver picks one version satisfying every constraint, with conflicts/replaces honored.

Phase 3 is parse-only — these fields are validated structurally but not acted upon. The Phase 4 resolver consumes them.

type DependencySelection

type DependencySelection struct {
	// Base is the dep's Base.Name the parent pre-picks.
	Base string `yaml:"base,omitempty" json:"base,omitempty"`
	// Components is the dep's Component names the parent pre-picks. Closure
	// under Requires is computed by the dep's solver at render time.
	Components []string `yaml:"components,omitempty" json:"components,omitempty"`
}

DependencySelection is the parent-visible part of a child package's Selection — base and components only. The full Selection adds metadata the resolver fills in (package name, version), so DependencySelection keeps the authored surface small.

type ExternalManifest

type ExternalManifest struct {
	// Name identifies this manifest within the package.
	Name string `yaml:"name" json:"name"`
	// URL is fetched at render time. Must include a digest pin via Digest.
	URL string `yaml:"url" json:"url"`
	// Digest is the expected sha256:... of the fetched bytes; render fails on mismatch.
	Digest string `yaml:"digest" json:"digest"`
	// SplitByResource splits the fetched multi-doc YAML stream into one Unit
	// per resource (default true). Set false to keep as a single Unit.
	SplitByResource *bool `yaml:"splitByResource,omitempty" json:"splitByResource,omitempty"`
	// Phase assigns these resources to a named phase from spec.phases.
	Phase string `yaml:"phase,omitempty" json:"phase,omitempty"`
}

type ExternalRequire

type ExternalRequire struct {
	// Kind is the precondition category (see ExternalRequireKind constants).
	Kind ExternalRequireKind `yaml:"kind" json:"kind"`
	// Name optionally pins the requirement to a specific instance (e.g.,
	// a particular CRD or operator name). Empty matches any instance of Kind.
	Name string `yaml:"name,omitempty" json:"name,omitempty"`
	// Version is a constraint expression (e.g., ">= v0.4.0").
	Version string `yaml:"version,omitempty" json:"version,omitempty"`
	// Capability is used with GatewayClass to require a specific feature
	// (e.g., "ext-proc"). Any GatewayClass providing the capability satisfies.
	Capability string `yaml:"capability,omitempty" json:"capability,omitempty"`
	// Namespace pins the requirement to a specific namespace (Operator/StorageClass).
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
	// IssuerKind constrains a WebhookCertProvider (e.g., "ClusterIssuer").
	IssuerKind string `yaml:"issuerKind,omitempty" json:"issuerKind,omitempty"`
	// SuggestedSource points the user at a package or chart that satisfies
	// this requirement, surfaced in the wizard.
	SuggestedSource string `yaml:"suggestedSource,omitempty" json:"suggestedSource,omitempty"`
	// SuggestedProviders lists multiple acceptable providers (e.g., for
	// GatewayClass: Istio, EnvoyGateway, kgateway, ...).
	SuggestedProviders []string `yaml:"suggestedProviders,omitempty" json:"suggestedProviders,omitempty"`
}

type ExternalRequireKind

type ExternalRequireKind string

ExternalRequireKind enumerates the typed precondition categories observed across real inference-stack projects (KServe, KubeRay, GAIE, llm-d, vLLM).

const (
	ExtReqCRD                 ExternalRequireKind = "CRD"
	ExtReqClusterFeature      ExternalRequireKind = "ClusterFeature"
	ExtReqWebhookCertProvider ExternalRequireKind = "WebhookCertProvider"
	ExtReqGatewayClass        ExternalRequireKind = "GatewayClass"
	ExtReqOperator            ExternalRequireKind = "Operator"
	ExtReqStorageClass        ExternalRequireKind = "StorageClass"
	ExtReqRuntimeClass        ExternalRequireKind = "RuntimeClass"
)

type Facts

type Facts struct {
	// APIVersion is the installer API group/version.
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	// Kind is "Facts".
	Kind string `yaml:"kind" json:"kind"`
	// Metadata is the doc's ObjectMeta-shaped metadata block.
	Metadata Metadata `yaml:"metadata" json:"metadata"`
	// Spec carries the collected fact values.
	Spec FactsSpec `yaml:"spec" json:"spec"`
}

Facts holds the values produced by the package's Collector script — install- time discovery that depends on cluster, environment, or ConfigHub state and cannot be supplied by the user up front (e.g., a server-derived image tag, a freshly created BridgeWorkerID, the active context's server URL).

Facts are persisted as out/spec/facts.yaml so re-render is reproducible from the same captured state. Re-run `installer wizard` to refresh.

Sensitive material (passwords, tokens, worker secrets) MUST NOT be placed in Facts.Values; the collector writes those as .env.secret files consumed by a kustomize secretGenerator, and the rendered Secret is routed to out/secrets/ (never uploaded as a Unit).

func ParseFacts

func ParseFacts(data []byte) (*Facts, error)

ParseFacts parses facts.yaml bytes into Facts.

type FactsSpec

type FactsSpec struct {
	// Package is the source package name the facts were collected for.
	Package string `yaml:"package" json:"package"`
	// PackageVersion is the source package's SemVer at collection time.
	PackageVersion string `yaml:"packageVersion,omitempty" json:"packageVersion,omitempty"`
	// Values is the YAML map the collector wrote to stdout. Each key is
	// referenced from function-chain templates as `{{ .Facts.<name> }}`.
	Values map[string]any `yaml:"values" json:"values"`
}

type FunctionChain

type FunctionChain struct {
	// APIVersion is the installer API group/version.
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	// Kind is "FunctionChain".
	Kind string `yaml:"kind" json:"kind"`
	// Metadata is the doc's ObjectMeta-shaped metadata block.
	Metadata Metadata `yaml:"metadata" json:"metadata"`
	// Spec carries the resolved function-group list that ran during render.
	Spec FunctionChainSpec `yaml:"spec" json:"spec"`
}

FunctionChain is the resolved (template-expanded) function chain that the render step actually executes. Persisted as a Unit alongside the rendered output so the exact transforms applied are inspectable and replayable.

func ParseFunctionChain

func ParseFunctionChain(data []byte) (*FunctionChain, error)

ParseFunctionChain parses function-chain.yaml bytes.

type FunctionChainSpec

type FunctionChainSpec struct {
	// Package is the source package name the chain was resolved from.
	Package string `yaml:"package" json:"package"`
	// PackageVersion is the source package's SemVer at resolve time.
	PackageVersion string `yaml:"packageVersion,omitempty" json:"packageVersion,omitempty"`
	// Groups is the resolved (template-expanded) function-group list that
	// render executed in order.
	Groups []FunctionGroup `yaml:"groups" json:"groups"`
}

type FunctionGroup

type FunctionGroup struct {
	// Toolchain is the executor toolchain (e.g., "Kubernetes/YAML",
	// "AppConfig/Properties"). Per-group so a single chain can mutate both
	// raw Kubernetes manifests and AppConfig Units in the same render.
	Toolchain string `yaml:"toolchain" json:"toolchain"`
	// WhereResource scopes which resources this group operates on. Empty
	// means all resources.
	WhereResource string `yaml:"whereResource,omitempty" json:"whereResource,omitempty"`
	// Invocations runs in order. Output of each invocation feeds the next
	// (within the group). Output of each group feeds the next group.
	Invocations []FunctionInvocation `yaml:"invocations" json:"invocations"`
	// Description is shown when previewing the chain.
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
}

FunctionGroup is one batch of function invocations sharing a toolchain and a whereResource filter, mirroring the cub function-executor SDK signature (one call to invokeLocalFunctions per group).

type FunctionInvocation

type FunctionInvocation struct {
	// Name is the function name (matches the ConfigHub function registry,
	// e.g., "set-namespace", "set-container-image", "vet-schemas").
	Name string `yaml:"name" json:"name"`
	// Args is the positional argument list passed to the function. Values
	// may contain Go-template expressions resolved at render time
	// ({{ .Namespace }}, {{ .Inputs.* }}, {{ .Facts.* }}, ...).
	Args []string `yaml:"args,omitempty" json:"args,omitempty"`
}

FunctionInvocation is one call within a FunctionGroup.

type Header struct {
	// APIVersion is the installer API group/version (e.g.
	// "installer.confighub.com/v1alpha1").
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	// Kind is one of KindPackage / KindInputs / KindSelection / etc.
	Kind string `yaml:"kind" json:"kind"`
	// Metadata is the doc's ObjectMeta-shaped metadata block.
	Metadata Metadata `yaml:"metadata" json:"metadata"`
}

Header pairs APIVersion + Kind for sniffing the leading bytes of an installer doc without parsing its full body.

type Input

type Input struct {
	// Name is the key in the resolved Inputs map and the variable name used
	// in function chain templates ({{ .Inputs.<name> }}).
	Name string `yaml:"name" json:"name"`
	// Type constrains the value: string, int, bool, enum, list.
	Type string `yaml:"type" json:"type"`
	// Default is used when the user does not supply a value.
	Default any `yaml:"default,omitempty" json:"default,omitempty"`
	// Required fails if missing and no default is set.
	Required bool `yaml:"required,omitempty" json:"required,omitempty"`
	// Prompt is the human-readable question.
	Prompt string `yaml:"prompt,omitempty" json:"prompt,omitempty"`
	// Description is longer help text.
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
	// Options are valid values when Type == "enum".
	Options []string `yaml:"options,omitempty" json:"options,omitempty"`
	// WhenExternalRequire only prompts this input if the package has an
	// ExternalRequire of this Kind.
	WhenExternalRequire ExternalRequireKind `yaml:"whenExternalRequire,omitempty" json:"whenExternalRequire,omitempty"`
}

Input declares one wizard prompt.

type Inputs

type Inputs struct {
	// APIVersion is the installer API group/version.
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	// Kind is "Inputs".
	Kind string `yaml:"kind" json:"kind"`
	// Metadata is the doc's ObjectMeta-shaped metadata block.
	Metadata Metadata `yaml:"metadata" json:"metadata"`
	// Spec carries the wizard answers.
	Spec InputsSpec `yaml:"spec" json:"spec"`
}

Inputs holds the user's wizard answers, persisted as a Unit alongside the rendered output so re-render is reproducible. The wizard authors this from CLI flags (--input k=v); the user may also hand-edit before re-render.

func ParseInputs

func ParseInputs(data []byte) (*Inputs, error)

ParseInputs parses inputs.yaml bytes into Inputs.

type InputsSpec

type InputsSpec struct {
	// Package identifies the source package (name@version) these inputs answer.
	Package string `yaml:"package" json:"package"`
	// PackageVersion is the source package's SemVer at wizard time.
	PackageVersion string `yaml:"packageVersion,omitempty" json:"packageVersion,omitempty"`
	// Namespace is the Kubernetes namespace into which the package will install.
	// Captured at wizard time via --namespace so that every package does not
	// need to declare its own `namespace` input. Function-chain templates
	// reference it as `{{ .Namespace }}`.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
	// Values maps input Name → user-provided value, coerced to the declared Type.
	Values map[string]any `yaml:"values" json:"values"`
	// ImageOverrides maps kustomize image transformer name → image
	// reference (e.g., "hello" → "hello:v2"). Populated by the
	// `--set-image` flag on `installer wizard` / `installer upgrade`.
	// At render time the installer runs `kustomize edit set image
	// <name>=<ref>` for each entry against the chosen base's
	// kustomization.yaml, before invoking `kustomize build`. The
	// package's chosen base must declare an `images:` block in its
	// kustomization.yaml; render fails fast otherwise.
	//
	// Persisted here (rather than in Values) so it round-trips across
	// upgrades without operator re-typing: the next upgrade carries
	// these overrides forward unless the operator passes a different
	// `--set-image` for the same name.
	ImageOverrides map[string]string `yaml:"imageOverrides,omitempty" json:"imageOverrides,omitempty"`
}

type InstallerMetadata

type InstallerMetadata struct {
	// Version is the package's own SemVer version (e.g. "0.3.0"). Used as
	// the right-hand side of `<package>@<version>` everywhere the
	// installer prints, labels, or annotates with package identity.
	Version string `yaml:"version,omitempty" json:"version,omitempty"`
	// KubeVersion is a SemVer range the cluster must satisfy
	// (e.g. ">= 1.28"). Empty means unconstrained.
	KubeVersion string `yaml:"kubeVersion,omitempty" json:"kubeVersion,omitempty"`
	// InstallerVersion is a SemVer range the installer CLI must satisfy
	// (e.g. ">= 0.2.0"). Empty means unconstrained.
	InstallerVersion string `yaml:"installerVersion,omitempty" json:"installerVersion,omitempty"`
}

InstallerMetadata carries Package-level version metadata. Only meaningful on a Package (not on Inputs / Selection / Lock / etc.). Both *Version fields are SemVer range strings (e.g. ">= 1.28"); empty means unconstrained.

type Lock

type Lock struct {
	// APIVersion is the installer API group/version.
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	// Kind is "Lock".
	Kind string `yaml:"kind" json:"kind"`
	// Metadata is the doc's ObjectMeta-shaped metadata block.
	Metadata Metadata `yaml:"metadata" json:"metadata"`
	// Spec carries the resolved dependency DAG.
	Spec LockSpec `yaml:"spec" json:"spec"`
}

Lock pins every dependency of a package to a specific OCI digest. The resolver (Phase 4) writes one Lock as <work-dir>/out/spec/lock.yaml; the renderer (Phase 5) reads it and refuses to proceed if stale.

The lock is also embedded in the parent's installer-record Unit on upload (Phase 6), so each rendered package's ConfigHub Space carries enough metadata to reproduce its own render — without keeping a separate file under version control.

func ParseLock

func ParseLock(data []byte) (*Lock, error)

ParseLock parses lock.yaml bytes into a Lock.

type LockSpec

type LockSpec struct {
	// Package identifies the root package this lock was generated for.
	Package LockedPackage `yaml:"package" json:"package"`

	// Resolved is the dependency DAG in topological order: parents before
	// children. Each entry records the OCI ref + digest the resolver chose.
	Resolved []LockedDependency `yaml:"resolved,omitempty" json:"resolved,omitempty"`
}

type LockedDependency

type LockedDependency struct {
	// Name matches the Dependency.Name from the parent's installer.yaml.
	Name string `yaml:"name" json:"name"`

	// Ref is the full pinned OCI ref the resolver chose, including tag.
	// Example: oci://ghcr.io/confighubai/gateway-api:1.4.2
	Ref string `yaml:"ref" json:"ref"`

	// Digest is the sha256:<hex> of the manifest at Ref. The renderer
	// re-verifies the digest at fetch time so retagging upstream cannot
	// silently change the resolved content.
	Digest string `yaml:"digest" json:"digest"`

	// Version is the resolved SemVer string (without any range operator).
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// RequestedBy lists the names of parents that requested this
	// dependency (transitively). The root is named "root".
	RequestedBy []string `yaml:"requestedBy,omitempty" json:"requestedBy,omitempty"`

	// Selection and Inputs are the pre-answers the resolver passed down
	// (merged across multiple parents requesting the same dep).
	Selection *DependencySelection `yaml:"selection,omitempty" json:"selection,omitempty"`
	Inputs    map[string]any       `yaml:"inputs,omitempty" json:"inputs,omitempty"`
}

LockedDependency pins one resolved dependency.

type LockedPackage

type LockedPackage struct {
	// Name is the root package's metadata.name.
	Name string `yaml:"name" json:"name"`
	// Version is the root package's installerMetadata.version.
	Version string `yaml:"version,omitempty" json:"version,omitempty"`
	// Digest is the OCI manifest digest of the root package, if it was
	// pulled from a registry. Empty for in-tree (un-published) root
	// packages, which is the common case during authoring.
	Digest string `yaml:"digest,omitempty" json:"digest,omitempty"`
}

LockedPackage describes the root package the lock was computed against.

type Metadata

type Metadata struct {
	// Name identifies the doc within its kind. Required.
	Name string `yaml:"name" json:"name"`
	// Labels are short key/value pairs used for selection and grouping.
	Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
	// Annotations are arbitrary key/value pairs carrying out-of-band
	// metadata. Used by the installer for things like the
	// PackageVersion= annotation written onto uploaded Units.
	Annotations map[string]string `yaml:"annotations,omitempty" json:"annotations,omitempty"`
}

Metadata is the common metadata block on every installer doc. The shape matches Kubernetes ObjectMeta (name + labels + annotations) so the docs look familiar to anyone reading Kubernetes YAML.

type Package

type Package struct {
	// APIVersion is the installer API group/version
	// ("installer.confighub.com/v1alpha1"). Required.
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	// Kind is "Package". Required.
	Kind string `yaml:"kind" json:"kind"`
	// Metadata is the Kubernetes-style ObjectMeta block. Only Name is
	// required.
	Metadata Metadata `yaml:"metadata" json:"metadata"`
	// InstallerMetadata carries the package's SemVer (version) plus the
	// optional KubeVersion / InstallerVersion ranges. Hand-authored at
	// the top level of installer.yaml alongside metadata.
	InstallerMetadata InstallerMetadata `yaml:"installerMetadata,omitempty" json:"installerMetadata,omitempty"`
	// Spec carries the package's authored declarations: bases, components,
	// inputs, dependencies, transformers, etc.
	Spec PackageSpec `yaml:"spec" json:"spec"`
}

Package is the installer.yaml document a package author writes by hand. It declares what bases and components are available, what inputs the wizard should ask for, what external preconditions the package needs, and what the function chain template looks like.

func ParsePackage

func ParsePackage(data []byte) (*Package, error)

ParsePackage parses installer.yaml bytes into a Package, validating the header.

type PackageSpec

type PackageSpec struct {
	// Bases are alternative top-level kustomize trees. Exactly one is selected
	// at install time (default: the one with Default: true). Use this when the
	// package supports orthogonal deployment shapes that cannot be expressed
	// as opt-in Components (e.g., KServe Knative vs Raw, llm-d colocated vs
	// P/D-disaggregated).
	Bases []Base `yaml:"bases" json:"bases"`

	// Components are kustomize Components (kind: Component) that may be
	// selected to add features on top of the chosen Base. Selection is
	// closed under Requires.
	Components []Component `yaml:"components,omitempty" json:"components,omitempty"`

	// ExternalRequires lists preconditions the cluster must satisfy. Evaluated
	// at install-time by `installer preflight` and surfaced in the wizard.
	ExternalRequires []ExternalRequire `yaml:"externalRequires,omitempty" json:"externalRequires,omitempty"`

	// Provides lists CRDs and other resources this package installs. Used to
	// detect double-install conflicts when multiple packages are deployed in
	// the same cluster.
	Provides []Provide `yaml:"provides,omitempty" json:"provides,omitempty"`

	// ClusterSingleton lists leader-election leases this package claims at
	// cluster scope. Two packages claiming the same lease cannot coexist.
	ClusterSingleton []SingletonClaim `yaml:"clusterSingleton,omitempty" json:"clusterSingleton,omitempty"`

	// ExternalManifests are remote manifest files (e.g., release tarballs of
	// CRDs) that get fetched at render time and merged into the rendered
	// output as additional Units. Used by projects like Gateway API Inference
	// Extension that distribute CRDs as a release-tarball outside any chart.
	ExternalManifests []ExternalManifest `yaml:"externalManifests,omitempty" json:"externalManifests,omitempty"`

	// Inputs declares the wizard prompts. Inputs are referenced by Go template
	// expressions in Transformers (e.g., "{{ .Inputs.namespace }}").
	Inputs []Input `yaml:"inputs,omitempty" json:"inputs,omitempty"`

	// Collector is an executable bundled in the package that the wizard runs
	// to discover install-time facts (server URL, image tag, worker IDs, etc.)
	// and to produce sensitive material as .env.secret files consumed by
	// kustomize secretGenerator. See Transformers for how facts are
	// referenced.
	Collector *Collector `yaml:"collector,omitempty" json:"collector,omitempty"`

	// Validation points at machine-readable component documentation bundled in
	// the package (typically under ./validation/): a JSON Schema of accepted
	// env vars, the command help YAML, and a runtime spec. Not consumed by
	// render today — surfaced by `installer doc` so an AI agent or human can
	// inspect what the rendered workload supports.
	Validation *Validation `yaml:"validation,omitempty" json:"validation,omitempty"`

	// Phases groups rendered output Units for ordered apply. Each rendered
	// Unit is labeled with the first matching phase. The last phase with an
	// empty WhereResource matches everything else.
	Phases []Phase `yaml:"phases,omitempty" json:"phases,omitempty"`

	// Transformers is a list of function-invocation groups that mutate the
	// rendered output. At render time it is resolved with the wizard answers
	// (Go templates), serialized to out/compose/transformers.yaml as a
	// ConfigHubTransformers KRM function config, and run by `installer
	// transformer` (which kustomize invokes as an exec plugin via the
	// out/compose/installer-transformer.sh wrapper). Each group runs through
	// funcimpl.NewStandardExecutor with its own toolchain and whereResource
	// filter, output of each group feeding the next.
	Transformers []FunctionGroup `yaml:"transformers,omitempty" json:"transformers,omitempty"`

	// Validators is a list of validating-function invocation groups, run
	// at the end of render against the mutated output. Same shape as
	// Transformers, but every named function must be a
	// Validating function (Mutating=false). Validators do not modify
	// the rendered manifests; they fail render if any validator
	// returns Passed=false.
	//
	// The `installer init` command seeds new packages with vet-schemas,
	// vet-merge-keys, and vet-format. Authors can edit this list with
	// `installer edit validator add/remove`. The full list of available
	// validators can be discovered with
	//   `cub function list --where "Validating = TRUE" --toolchain Kubernetes/YAML`.
	Validators []FunctionGroup `yaml:"validators,omitempty" json:"validators,omitempty"`

	// Dependencies declares other installer packages this package composes
	// with. Each entry pins an OCI ref + SemVer constraint; the resolver
	// (Phase 4) walks the DAG and writes out/spec/lock.yaml. Parse-only in
	// Phase 3 — wizard, render, and upload ignore this field.
	Dependencies []Dependency `yaml:"dependencies,omitempty" json:"dependencies,omitempty"`

	// Conflicts hard-excludes other packages from the resolution set.
	// Mirrors Debian's Conflicts:.
	Conflicts []ConflictRef `yaml:"conflicts,omitempty" json:"conflicts,omitempty"`

	// Replaces declares packages this one supersedes (typically across a
	// rename). The resolver treats a request for a Replaces[i].Package
	// matching the version range as satisfied by this package. Mirrors
	// Debian's Replaces:.
	Replaces []ReplaceRef `yaml:"replaces,omitempty" json:"replaces,omitempty"`

	// BundleExamples controls whether the examples/ subtree is included by
	// `installer package`. Default behavior (when nil) is true — examples
	// are bundled. Set to false to exclude them from published artifacts.
	BundleExamples *bool `yaml:"bundleExamples,omitempty" json:"bundleExamples,omitempty"`
}

type Phase

type Phase struct {
	// Name is the phase label written onto each rendered Unit that
	// matches WhereResource.
	Name string `yaml:"name" json:"name"`
	// WhereResource is a ConfigHub function-executor filter expression. The
	// first phase whose filter matches is assigned to a resource. The last
	// phase with empty WhereResource catches everything else.
	WhereResource string `yaml:"whereResource,omitempty" json:"whereResource,omitempty"`
}

type Provide

type Provide struct {
	// Kind is the provided-resource category (see ProvideKind constants).
	Kind ProvideKind `yaml:"kind" json:"kind"`
	// Name identifies the specific resource provided (e.g., a CRD name).
	Name string `yaml:"name" json:"name"`
}

type ProvideKind

type ProvideKind string

ProvideKind enumerates what a package can claim to provide.

const (
	ProvideCRD          ProvideKind = "CRD"
	ProvideOperator     ProvideKind = "Operator"
	ProvideGatewayClass ProvideKind = "GatewayClass"
)

type RenderedBundleInfo

type RenderedBundleInfo struct {
	ManifestCount   int      `json:"manifestCount"`
	ObjectSetDigest string   `json:"objectSetDigest"`
	LayerDigest     string   `json:"layerDigest"`
	LayerSize       int64    `json:"layerSize"`
	Files           []string `json:"files"`
}

type RenderedCheck

type RenderedCheck struct {
	Name   string `json:"name"`
	Result string `json:"result"`
}

type RenderedConfigBlob

type RenderedConfigBlob struct {
	SchemaVersion    string             `json:"schemaVersion"`
	InstallerVersion string             `json:"installerVersion,omitempty"`
	Source           RenderedSource     `json:"source"`
	Render           RenderedContext    `json:"render"`
	Checks           []RenderedCheck    `json:"checks,omitempty"`
	Output           RenderedBundleInfo `json:"output"`
}

RenderedConfigBlob records how a rendered OCI artifact was produced without embedding input values or rendered Secrets in registry metadata.

type RenderedContext

type RenderedContext struct {
	Base                string   `json:"base"`
	Components          []string `json:"components,omitempty"`
	Namespace           string   `json:"namespace,omitempty"`
	SelectionSHA256     string   `json:"selectionSHA256"`
	InputsSHA256        string   `json:"inputsSHA256"`
	FunctionChainSHA256 string   `json:"functionChainSHA256"`
}

type RenderedSource

type RenderedSource struct {
	Reference      string `json:"reference,omitempty"`
	ManifestDigest string `json:"manifestDigest,omitempty"`
	Package        string `json:"package"`
	PackageVersion string `json:"packageVersion,omitempty"`
}

type ReplaceRef

type ReplaceRef struct {
	// Package is the OCI ref (oci://host/repo) of the superseded package.
	Package string `yaml:"package" json:"package"`
	// Version is a SemVer range; empty or "*" matches any version of the
	// superseded package.
	Version string `yaml:"version,omitempty" json:"version,omitempty"`
}

ReplaceRef declares that this package supersedes another. The resolver treats a dependency on the named package matching the version range as satisfied by the package declaring the replacement.

type Selection

type Selection struct {
	// APIVersion is the installer API group/version.
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	// Kind is "Selection".
	Kind string `yaml:"kind" json:"kind"`
	// Metadata is the doc's ObjectMeta-shaped metadata block.
	Metadata Metadata `yaml:"metadata" json:"metadata"`
	// Spec carries the chosen base + closure-resolved components.
	Spec SelectionSpec `yaml:"spec" json:"spec"`
}

Selection records the chosen base + components after the wizard's solver closes the user's picks under Requires and validates ValidForBases / Conflicts. Persisted as a Unit alongside the rendered output; user-editable for re-render ("add cache-server", "switch to knative base").

func ParseSelection

func ParseSelection(data []byte) (*Selection, error)

ParseSelection parses selection.yaml bytes into a Selection.

type SelectionSpec

type SelectionSpec struct {
	// Package identifies the source package this selection is against.
	Package string `yaml:"package" json:"package"`
	// PackageVersion is the source package's SemVer at selection time.
	PackageVersion string `yaml:"packageVersion,omitempty" json:"packageVersion,omitempty"`
	// Base is the chosen Base.Name from the package.
	Base string `yaml:"base" json:"base"`
	// Components is the closure-resolved list of Component names.
	Components []string `yaml:"components,omitempty" json:"components,omitempty"`
}

type SigningPolicy

type SigningPolicy struct {
	// APIVersion is the installer API group/version.
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	// Kind is "SigningPolicy".
	Kind string `yaml:"kind" json:"kind"`
	// Metadata is the doc's ObjectMeta-shaped metadata block.
	Metadata Metadata `yaml:"metadata,omitempty" json:"metadata,omitempty"`
	// Spec carries the enforce flag and the trusted-signer lists.
	Spec SigningPolicySpec `yaml:"spec" json:"spec"`
}

SigningPolicy declares which signatures the installer trusts when verifying OCI artifacts on pull / deps update. The file lives at ~/.config/installer/policy.yaml. Absent file ⇒ no verification.

When Enforce is true and a ref's signature does not satisfy at least one entry in TrustedKeys or TrustedKeyless, the operation fails.

func ParseSigningPolicy

func ParseSigningPolicy(data []byte) (*SigningPolicy, error)

ParseSigningPolicy parses ~/.config/installer/policy.yaml.

type SigningPolicySpec

type SigningPolicySpec struct {
	// Enforce, when true, makes pull/deps update fail on unverified
	// artifacts. When false, the policy is treated as advisory:
	// `installer verify` still works, but pull and deps update do not
	// gate on it.
	Enforce bool `yaml:"enforce" json:"enforce"`

	// TrustedKeys lists cosign public-key entries.
	TrustedKeys []TrustedKey `yaml:"trustedKeys,omitempty" json:"trustedKeys,omitempty"`

	// TrustedKeyless lists Sigstore-keyless identity entries (Fulcio
	// certificate identity + OIDC issuer).
	TrustedKeyless []TrustedKeyless `yaml:"trustedKeyless,omitempty" json:"trustedKeyless,omitempty"`
}

type SingletonClaim

type SingletonClaim struct {
	// Lease is the leader-election lease name this package claims.
	Lease string `yaml:"lease" json:"lease"`
	// Namespace scopes the lease to a specific namespace; empty means
	// cluster-scoped.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
}

type TrustedKey

type TrustedKey struct {
	// PublicKey is the path on disk OR a cosign key reference
	// (k8s://, awskms://, etc.) passed verbatim to `cosign verify --key`.
	PublicKey string `yaml:"publicKey" json:"publicKey"`
	// Repos optionally scopes this key to specific OCI repos. Each entry
	// is matched as a prefix (no globs in v1). Empty = matches all repos.
	Repos []string `yaml:"repos,omitempty" json:"repos,omitempty"`
	// Description is shown in error messages when no key matches.
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
}

TrustedKey points at a cosign-compatible public key.

type TrustedKeyless

type TrustedKeyless struct {
	// Identity is the cosign --certificate-identity value (the email or
	// URI in the Fulcio cert). Required.
	Identity string `yaml:"identity" json:"identity"`
	// Issuer is the OIDC issuer URL (--certificate-oidc-issuer).
	// Required.
	Issuer string `yaml:"issuer" json:"issuer"`
	// Repos scopes this identity to specific OCI repos (prefix match).
	Repos []string `yaml:"repos,omitempty" json:"repos,omitempty"`
	// Description is shown in error messages when no identity matches.
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
}

TrustedKeyless is a Sigstore identity claim.

type Upload

type Upload struct {
	// APIVersion is the installer API group/version.
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	// Kind is "Upload".
	Kind string `yaml:"kind" json:"kind"`
	// Metadata is the doc's ObjectMeta-shaped metadata block.
	Metadata Metadata `yaml:"metadata" json:"metadata"`
	// Spec carries the destination Space(s) and the cub context used.
	Spec UploadSpec `yaml:"spec" json:"spec"`
}

Upload records where a work-dir's spec was last uploaded so the wizard (and plan/update/upgrade) can re-enter from ConfigHub instead of from the local files. Persisted as <work-dir>/out/spec/upload.yaml after a successful `installer upload`. Also embedded in the per-Space installer-record Unit body so a freshly cloned work-dir can be recovered from ConfigHub alone.

func ParseUpload

func ParseUpload(data []byte) (*Upload, error)

ParseUpload parses upload.yaml bytes into an Upload.

type UploadSpec

type UploadSpec struct {
	// Package is the parent package name from installer.yaml.
	Package string `yaml:"package" json:"package"`
	// PackageVersion is the parent package version.
	PackageVersion string `yaml:"packageVersion,omitempty" json:"packageVersion,omitempty"`
	// SpacePattern is the --space-pattern (or single --space) used at
	// upload time. Recorded so re-uploads with the same pattern are
	// idempotent.
	SpacePattern string `yaml:"spacePattern,omitempty" json:"spacePattern,omitempty"`
	// Spaces is one entry per package uploaded — the parent first, then
	// each locked dep — naming the resolved Space slug.
	Spaces []UploadedSpace `yaml:"spaces" json:"spaces"`
	// UploadedAt is the RFC3339 timestamp of the upload.
	UploadedAt string `yaml:"uploadedAt,omitempty" json:"uploadedAt,omitempty"`
	// Server is the ConfigHub server URL the upload targeted, taken from
	// the cub context at upload time. Sanity-checked on every subsequent
	// command against the current cub context.
	Server string `yaml:"server,omitempty" json:"server,omitempty"`
	// OrganizationID is the ConfigHub organization ID from the cub
	// context at upload time. Sanity-checked on every subsequent command.
	OrganizationID string `yaml:"organizationID,omitempty" json:"organizationID,omitempty"`
}

type UploadedSpace

type UploadedSpace struct {
	// Package is the package's metadata.name.
	Package string `yaml:"package" json:"package"`
	// Version is the package's installerMetadata.version at upload time.
	Version string `yaml:"version,omitempty" json:"version,omitempty"`
	// Slug is the resolved ConfigHub Space slug (from SpacePattern).
	Slug string `yaml:"slug" json:"slug"`
	// IsParent flags the entry for the parent (root) package as opposed to
	// a locked dependency.
	IsParent bool `yaml:"isParent,omitempty" json:"isParent,omitempty"`
}

UploadedSpace records one (package, resolved Space slug) pair from an upload. Each parent or locked dependency uploads into its own Space.

type Validation

type Validation struct {
	// CommandHelp is a YAML file produced by `cub-worker-run docgen command`
	// (Cobra command tree).
	CommandHelp string `yaml:"commandHelp,omitempty" json:"commandHelp,omitempty"`
	// EnvSchema is a JSON Schema describing accepted env vars, produced by
	// `cub-worker-run docgen env`.
	EnvSchema string `yaml:"envSchema,omitempty" json:"envSchema,omitempty"`
	// RuntimeSpec is the runtime spec YAML produced by
	// `cub-worker-run docgen runtime` (ports, paths, probes).
	RuntimeSpec string `yaml:"runtimeSpec,omitempty" json:"runtimeSpec,omitempty"`
	// HowToRegenerate is human-readable shell text shown by `installer doc`.
	HowToRegenerate string `yaml:"howToRegenerate,omitempty" json:"howToRegenerate,omitempty"`
}

Validation points at component documentation bundled in the package.

Typically generated by running `docker run <image> docgen {command,env,runtime}` and committed under ./validation/ so consumers (including AI agents) can read what env vars the workload accepts and what runtime expectations it has without re-pulling the image.

Jump to

Keyboard shortcuts

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