extras

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2026 License: Apache-2.0 Imports: 30 Imported by: 0

Documentation

Overview

Package extras loads raw Kubernetes manifests and CRDs from .deployah/, merges Deployah identity metadata, injects manifests into a Helm release via a post-renderer, and applies CRDs to the cluster before the release.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GroupVersionsFromCRDs

func GroupVersionsFromCRDs(crds []Object) map[string]struct{}

GroupVersionsFromCRDs returns the set of "group/version" strings declared by the given CRD objects (every entry under spec.versions). Used to skip required-API checks for APIs this deploy is about to install.

Types

type Bundle

type Bundle struct {
	// Manifests are objects from .deployah/manifests/ for the selected environment.
	Manifests []Object
	// CRDs are CustomResourceDefinition objects from .deployah/crds/.
	CRDs []Object
}

Bundle holds the deploy-ready extras for one environment.

func Load

func Load(cfg LoadConfig) (*Bundle, error)

Load reads .deployah/manifests and .deployah/crds under SpecDir, validates them, merges Deployah identity metadata, and returns a deploy-ready Bundle. Missing directories yield an empty Bundle with a nil error.

func LoadFromSpec

func LoadFromSpec(specPath string, spc *spec.Spec, platform *spec.PlatformConfig, environment, releaseNamespace string, cfg *rest.Config) (*Bundle, error)

LoadFromSpec loads extras for a deploy/plan of the given spec. specPath is the path to deployah.yaml. When cfg is non-nil, live discovery is used for scope resolution; otherwise Offline is set so unknown types are not rejected (scope still comes from the built-in table and in-repo CRDs).

func (*Bundle) PostRendererFor

func (b *Bundle) PostRendererFor() postrenderer.PostRenderer

PostRendererFor returns a Helm post-renderer for the bundle's manifests, or a true nil interface when there are none (avoids a typed-nil *PostRenderer).

type CRDStats

type CRDStats struct {
	// Created is how many CRDs were newly installed.
	Created int
	// Replaced is how many existing CRDs were server-side-applied.
	Replaced int
	// Ready is how many CRDs were waited on (created, replaced, or already present).
	Ready int
}

CRDStats summarizes what ApplyCRDs did for one deploy.

func ApplyCRDs

func ApplyCRDs(ctx context.Context, cfg *rest.Config, crds []Object, policy Policy, timeout time.Duration) (CRDStats, error)

ApplyCRDs installs CRDs according to policy, then waits for each to report Established. CRDs are never pruned. timeout bounds the wait.

create-replace uses server-side apply with a patch derived from the object YAML (status and server-managed metadata stripped). See https://kubernetes.io/docs/reference/using-api/server-side-apply/

type DiscoveryResolver

type DiscoveryResolver struct {
	Mapper meta.RESTMapper
	Table  TableResolver
}

DiscoveryResolver wraps a RESTMapper and falls back to TableResolver.

func (*DiscoveryResolver) Known

Known implements ScopeResolver.

func (*DiscoveryResolver) Namespaced

func (r *DiscoveryResolver) Namespaced(gvk schema.GroupVersionKind) (bool, error)

Namespaced implements ScopeResolver.

type Identity

type Identity struct {
	APIVersion string
	Kind       string
	Namespace  string
	Name       string
}

Identity uniquely identifies a Kubernetes object for collision checks.

func (Identity) Key

func (id Identity) Key() string

Key returns a stable map key for identity comparisons.

func (Identity) String

func (id Identity) String() string

String returns a human-readable identity for error messages.

type LoadConfig

type LoadConfig struct {
	// SpecDir is the directory containing deployah.yaml (and .deployah/).
	SpecDir string
	// Project is the project name for identity annotations/labels.
	Project string
	// Environment is the runtime environment (e.g. review/pr-123).
	Environment string
	// DeclaredEnvs are the registry keys used to validate manifests/<env>/ dirs.
	DeclaredEnvs []string
	// ReleaseNamespace fills empty metadata.namespace on namespaced objects.
	ReleaseNamespace string
	// Scope resolves namespaced vs cluster-scoped. Required.
	Scope ScopeResolver
	// Offline is true when cluster discovery is unavailable (plan --offline
	// or missing rest config). Unknown types are then allowed; scope defaults
	// to namespaced unless an in-repo CRD declares otherwise.
	Offline bool
}

LoadConfig configures Load.

type Object

type Object struct {
	Path string
	Raw  []byte
	Obj  *unstructured.Unstructured
}

Object is one Kubernetes document loaded from an extras file.

func (*Object) GVK

func (o *Object) GVK() schema.GroupVersionKind

GVK returns the object's GroupVersionKind.

func (*Object) Identity

func (o *Object) Identity() Identity

Identity returns the object's identity, using an empty namespace for cluster-scoped resources that have none set.

func (*Object) MarshalYAML

func (o *Object) MarshalYAML() ([]byte, error)

MarshalYAML serializes the object back to YAML bytes.

type Policy

type Policy string

Policy controls how Deployah installs CRDs from .deployah/crds/.

const (
	// PolicyCreate installs a CRD only when it does not already exist.
	PolicyCreate Policy = "create"
	// PolicyCreateReplace creates a missing CRD or server-side-applies over
	// an existing one (force ownership).
	PolicyCreateReplace Policy = "create-replace"
)

type PostRenderer

type PostRenderer struct {
	Manifests []Object
}

PostRenderer appends literal extra manifests to Helm's rendered stream. Extra YAML never passes through the template engine, so `{{ }}` is preserved.

func (*PostRenderer) Run

func (p *PostRenderer) Run(renderedManifests *bytes.Buffer) (*bytes.Buffer, error)

Run implements helm.sh/helm/v4/pkg/postrenderer.PostRenderer.

type ScopeResolver

type ScopeResolver interface {
	// Known reports whether gvk is a built-in kind, declared by an in-repo
	// CRD, or present in live discovery.
	Known(gvk schema.GroupVersionKind) (bool, error)
	// Namespaced reports whether gvk is namespaced. When Known is false and
	// discovery is unavailable, callers may still use this; unknown kinds
	// default to namespaced.
	Namespaced(gvk schema.GroupVersionKind) (bool, error)
}

ScopeResolver reports whether a GVK is known and whether it is namespaced.

func NewDiscoveryResolver

func NewDiscoveryResolver(cfg *rest.Config, crdScope map[string]bool) (ScopeResolver, error)

NewDiscoveryResolver builds a ScopeResolver from a rest.Config. When cfg is nil, it returns a table-only resolver.

type TableResolver

type TableResolver struct {
	// CRDScope maps "group/kind" (lowercase) to namespaced, from .deployah/crds.
	CRDScope map[string]bool
}

TableResolver resolves scope from a built-in group/kind table and optional CRD-provided scopes. Unknown kinds are not Known; Namespaced defaults them to namespaced when called anyway.

func (*TableResolver) Known

func (r *TableResolver) Known(gvk schema.GroupVersionKind) (bool, error)

Known implements ScopeResolver.

func (*TableResolver) Namespaced

func (r *TableResolver) Namespaced(gvk schema.GroupVersionKind) (bool, error)

Namespaced implements ScopeResolver.

Jump to

Keyboard shortcuts

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