katalog

package
v0.7.5 Latest Latest
Warning

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

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

README

pkg/katalog

The katalog package is the schema registry for an Orkestra operator. It parses and validates the user's Katalog YAML, enriches each CRD entry with runtime metadata, and exposes the result as a queryable *Katalog value that every other subsystem reads from.

Nothing in Orkestra hardcodes a CRD — everything is driven by what the Katalog says.

What the Katalog holds

What Where in code
Enabled CRD entries (enriched, validated) k.enabledCRDs
Katalog metadata (name, version, author, license) k.metadata
Security configuration (deletion protection, RBAC) k.Security
Conversion rules (/convert webhook) k.conversionRegistry
Admission rules (/validate, /mutate webhooks) k.admissionRegistry
Dependency DAG built lazily by NewDependencyGraph(k)

Boot sequence

merger.Merger (merges N katalog YAML files)
    ↓
NewKatalog(merger, konfig)
    → KomposeRuntimeKatalog  — decode YAML, enrich entries
    → ValidateConfig          — field-level, uniqueness, dependency, GVK, defaults
    → updateResourceMapAndReturn — build GVK → type index
    ↓
*Katalog (ready to use)

NewKatalog calls utils.Exit on any validation failure — the operator does not start with a broken Katalog.

CRD entry lifecycle

Each CRDEntry goes through several enrichment phases before it is considered ready:

  1. Parse — decoded from YAML via the merger.
  2. crdFile population — if crdFile: is declared, populateAPITypesFromCRDFile reads the CRD YAML and fills APITypes (group, version, kind, plural) from it. crdFile is the source of truth and overwrites any inline apiTypes: block. Typed-mode fields (Object, List, Alias, Location) are preserved from the inline declaration if present.
  3. EnrichEnrichCRDEntry fills in computed fields (API path, plural, GVK). For built-in Kubernetes kinds (Deployment, ConfigMap, etc.), group/version/plural are looked up from pkg/children.
  4. Validate — uniqueness, dependency graph (existence + cycle), reconciler mode.
  5. Defaults — workers, resync interval, namespace handling, finalizers, description.
  6. Runtime objects — dynamic mode → *unstructured.Unstructured factory; typed mode → ObjectRegistry lookup.
  7. Reconcilers — hooks from HookRegistry, constructors from ReconcilerRegistry.
  8. Status flagsIgnoreStatusPatch and IgnoreObservedGeneration set from the built-in registry in pkg/children.

After this pipeline, k.enabledCRDs contains fully-prepared entries. All runtime code reads from this map — it is never mutated after boot.

Step 2 (crdFile population) runs inside KomposeRuntimeKatalog, before ValidateConfig. By the time any validation runs, APITypes is fully populated regardless of whether the user declared apiTypes: or crdFile: or both.

Motif support

The katalog package also handles Motif imports — reusable infrastructure templates (databases, caches, message brokers) that a Katalog can import instead of writing all stateful resource declarations by hand.

File Role
motif_imports.go ResolveMotifImports — expands imports: blocks into concrete resource declarations
motif_validate.go ValidateMotif, ValidateMotifImports — structural and semantic validation of Motif YAML

Motif YAML is loaded by pkg/motif/loader.go using utils.StrictUnmarshal (same strict decoder as Katalog/Komposer) and then validated by motif_validate.go before any import expansion runs.

Developer documentation

I want to… Go to
Query the Katalog at runtime docs/01-querying.md
Understand the dependency graph docs/02-dependencies.md
Understand deletion protection docs/03-deletion-protection.md
Understand security defaults docs/04-security.md
Understand built-in type handling docs/05-builtins.md
Understand Motif validation and import expansion docs/06-motif-validation.md
Understand crdFile — auto-populating APITypes from a CRD YAML docs/07-crd-file.md

Documentation

Overview

pkg/katalog/admission_registry.go

pkg/katalog/conversion_registry.go

pkg/katalog/deletion_protection.go

Deletion protection — webhook rules and protected CRD name resolution.

Architecture: two-level filtering.

Level 1 — Webhook rules (DeletionProtectionGVRs):
  Intercepts ALL DELETE on customresourcedefinitions and Orkestra deployments.
  Must be broad — Kubernetes webhook rules filter by GVR, not by object name.

Level 2 — Handler (isProtectedCRD):
  Narrows to only the CRDs managed by THIS Katalog.
  "websites.demo.orkestra.io" from a different operator → allowed.
  "cronjobs.demo.orkestra.io" from this Katalog → denied.

When to register the webhook:

Requires a reachable Kubernetes Service. With ork run the operator runs
locally — there is no Service. failurePolicy: Fail would block ALL CRD
deletions when unreachable. Only register when running inside the cluster.

pkg/katalog/dependencies.go

pkg/katalog/enrichment.go

pkg/katalog/motif_imports.go

Expands imports: blocks at the CRD level (spec.crds[].imports). Each import loads the referenced Motif, binds its inputs from with:, and merges the expanded resources, status, and admission rules into the CRD.

pkg/katalog/motif_validate.go

pkg/katalog/parsek.go

pkg/katalog/security.go

Security accessors on *Katalog.

Precedence (highest → lowest):

  1. Katalog YAML (k.Security)
  2. ENV vars via SecurityConfig (k.konfig.Security())
  3. Hard defaults coded below

KatalogSecurity uses *bool fields which allows detecting "not declared" (nil) vs "explicitly false" (*false).

Deletion protection is ENABLED BY DEFAULT when the security block is present but deletionProtection is not declared.

pkg/katalog/serialize.go

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DetectCyclesForTest

func DetectCyclesForTest(k *Katalog) error

DetectCyclesForTest exposes detectDependencyCycles for integration tests.

func EnrichCRDEntry

func EnrichCRDEntry(entry *orktypes.CRDEntry) (orktypes.EnrichmentOutcome, error)

EnrichCRDEntry checks whether a CRD entry uses kind-only declaration and, if so, enriches it with the corresponding built-in API metadata.

Called during Katalog validation before the CRD entry is used at runtime.

A CRD entry qualifies for enrichment when:

  • apiTypes.kind is set
  • apiTypes.group is empty
  • apiTypes.version is empty
  • apiTypes.plural is empty

All three must be empty for enrichment to trigger — a partially-specified entry (e.g. kind + group but no version) is an error, not an enrichment candidate. This prevents silent misconfigurations.

Returns:

  • EnrichmentNotNeeded: entry was already fully specified, no change
  • EnrichmentApplied: entry was enriched successfully
  • EnrichmentFailed: kind not found in built-in registry, error returned

func NewSchemeRegistry

func NewSchemeRegistry(k *Katalog) (*runtime.Scheme, error)

NewSchemeRegistry returns a new scheme

func ResolveCRDFiles added in v0.4.8

func ResolveCRDFiles(path string) ([]byte, error)

ResolveCRDFiles reads the katalog YAML at path, resolves every crdFile reference to inline apiTypes, removes the crdFile key, and returns the rewritten YAML. The result is safe to embed in a bundle ConfigMap — the Orkestra runtime receives concrete apiTypes and never needs to read the file.

func ValidateCustomResource added in v0.4.6

func ValidateCustomResource(cr *orktypes.CustomResourceTemplateSource, path string) error

ValidateCustomResource validates a single CustomResource declaration. It enforces the structural and semantic rules required by Orkestra while intentionally avoiding CRD schema validation (the API server owns that).

Validation responsibilities:

  • Ensure required top-level fields (apiVersion, kind) are present and well-formed.
  • Ensure metadata.name is present after templating.
  • Enforce namespaced vs cluster-scoped semantics using Metadata.Namespaced with a defensive default of namespaced=true.
  • Validate labels and annotations using existing validators.
  • Validate template syntax for spec/status/other fields (no structural schema).
  • Validate hasStatus semantics and warn when user-provided status will be ignored.
  • Return path-aware errors so callers can point users to the exact declaration.

Note: This function assumes the following helpers exist in the package or elsewhere in the codebase and will be used here:

  • isValidKind(kind string) bool
  • validateLabels(labels map[string]string) error
  • validateAnnotations(annotations map[string]string) error
  • validateTemplateFields(obj map[string]any, path string) error

The `path` parameter should identify the declaration location (e.g. "mycrd.onCreate.custom[0]") and is used to produce clear error messages.

Types

type AdmissionRegistry

type AdmissionRegistry interface {
	// GetValidationRules returns the validation config for a GVR key.
	// Returns nil when no rules are registered for that resource.
	GetValidationRules(gvrKey string) *orktypes.ValidationConfig

	// GetMutationRules returns the mutation config for a GVR key.
	// Returns nil when no rules are registered for that resource.
	GetMutationRules(gvrKey string) *orktypes.MutationConfig

	// RegisterValidationRules stores validation rules for a GVR key.
	RegisterValidationRules(gvrKey string, cfg *orktypes.ValidationConfig)

	// RegisterMutationRules stores mutation rules for a GVR key.
	RegisterMutationRules(gvrKey string, cfg *orktypes.MutationConfig)

	// ValidationGVRs returns all GVR keys that have validation rules.
	// Used at startup to build the ValidatingWebhookConfiguration rules.
	ValidationGVRs() []GVREntry

	// MutationGVRs returns all GVR keys that have mutation rules.
	// Used at startup to build the MutatingWebhookConfiguration rules.
	MutationGVRs() []GVREntry
}

AdmissionRegistry is the interface used by the health server's admission handlers.

type ConversionRegistry

type ConversionRegistry interface {
	GetConversionRules(kind string) *orktypes.ConversionRules
	RegisterConversionRules(rules *orktypes.ConversionRules)
}

ConversionRegistry is the interface used by the health server's /convert handler. Decoupled from the Katalog struct so the health server has no import cycle.

type DependencyDisplay added in v0.5.4

type DependencyDisplay struct {
	StartupOrder []string                     // CRD names in deterministic startup order
	Conditions   map[string]map[string]string // CRD name → dep name → condition string
}

DependencyDisplay holds pre-computed dependency graph data for ork validate --full.

func (*DependencyDisplay) SortedDeps added in v0.5.4

func (dd *DependencyDisplay) SortedDeps(crdName string) []string

SortedDependencyNames returns the dependency names for a CRD in sorted order, along with their conditions. Used for deterministic display.

type DependencyGraph

type DependencyGraph struct {
	// contains filtered or unexported fields
}

DependencyGraph represents the CRD dependency DAG for a Katalog. Each CRD is a node, and edges represent "A must start before B" relationships.

The graph is used to:

  • compute deterministic startup order (topological sort)
  • compute deterministic shutdown order (reverse topological sort)
  • validate dependency correctness (no cycles, no missing CRDs)
  • expose dependency metadata to the runtime

The graph is immutable after construction.

func NewDependencyGraph

func NewDependencyGraph(katalog *Katalog) *DependencyGraph

NewDependencyGraph constructs the dependency DAG for all enabled CRDs. It validates that all declared dependencies exist and builds the adjacency lists.

func (*DependencyGraph) GetDependencies

func (g *DependencyGraph) GetDependencies(name string) []string

GetDependencies returns all CRDs that the given CRD depends on.

func (*DependencyGraph) GetDependents

func (g *DependencyGraph) GetDependents(name string) []string

GetDependents returns all CRDs that depend on the given CRD.

func (*DependencyGraph) GetEdges

func (g *DependencyGraph) GetEdges() map[string][]string

GetEdges returns the adjacency list: dependency → dependents.

func (*DependencyGraph) GetInDegree

func (g *DependencyGraph) GetInDegree(name string) int

GetInDegree returns how many CRDs this CRD depends on.

func (*DependencyGraph) GetNode

func (g *DependencyGraph) GetNode(name string) *Node

GetNode returns the node for a CRD name.

func (*DependencyGraph) GetNodes

func (g *DependencyGraph) GetNodes() map[string]*Node

GetNodes returns all nodes in the graph.

func (*DependencyGraph) GetOutDegree

func (g *DependencyGraph) GetOutDegree(name string) int

GetOutDegree returns how many CRDs depend on this CRD.

func (*DependencyGraph) ShutdownOrder

func (g *DependencyGraph) ShutdownOrder() []string

ShutdownOrder returns the reverse of the startup order. This ensures CRDs are stopped only after all dependents have been drained.

func (*DependencyGraph) StartupOrder

func (g *DependencyGraph) StartupOrder() []string

StartupOrder returns a deterministic topological ordering of CRDs. CRDs with no dependencies appear first; dependents appear after their prerequisites.

This order is used by the runtime to start CRDs in the correct sequence.

The result is cached and computed only once.

func (*DependencyGraph) Validate

func (g *DependencyGraph) Validate() error

Validate performs basic sanity checks on the graph.

type GVREntry

type GVREntry struct {
	// Key — the full GVR key string: "group/version/resource" or "version/resource"
	Key string

	// Group — API group. Empty for core group resources.
	Group string

	// Version — API version.
	Version string

	// Resource — plural resource name.
	Resource string

	// Operations — which operations this GVR should be webhoooked for.
	// Comes from AdmissionWebhookConfig.Operations or the default ["CREATE", "UPDATE"]
	Operations []string
}

GVREntry holds the parsed GVR components for webhook configuration. Built from the key during registry population.

type InMemoryAdmissionRegistry

type InMemoryAdmissionRegistry struct {
	// contains filtered or unexported fields
}

InMemoryAdmissionRegistry is the concrete implementation used at runtime. Safe for concurrent use — the /validate and /mutate handlers read from it concurrently; the Katalog load writes to it once at startup.

func NewInMemoryAdmissionRegistry

func NewInMemoryAdmissionRegistry() *InMemoryAdmissionRegistry

NewInMemoryAdmissionRegistry returns an initialised registry.

func (*InMemoryAdmissionRegistry) AddMutationGVR added in v0.3.1

func (r *InMemoryAdmissionRegistry) AddMutationGVR(entry GVREntry, cfg *orktypes.MutationConfig)

AddMutationGVR registers both mutation rules and the GVR entry so that MutationGVRs() returns the entry. Used in tests and tooling.

func (*InMemoryAdmissionRegistry) AddValidationGVR added in v0.3.1

func (r *InMemoryAdmissionRegistry) AddValidationGVR(entry GVREntry, cfg *orktypes.ValidationConfig)

AddValidationGVR registers both validation rules and the GVR entry so that ValidationGVRs() returns the entry. Used in tests and tooling.

func (*InMemoryAdmissionRegistry) GetMutationRules

func (r *InMemoryAdmissionRegistry) GetMutationRules(gvrKey string) *orktypes.MutationConfig

func (*InMemoryAdmissionRegistry) GetValidationRules

func (r *InMemoryAdmissionRegistry) GetValidationRules(gvrKey string) *orktypes.ValidationConfig

func (*InMemoryAdmissionRegistry) MutationGVRs

func (r *InMemoryAdmissionRegistry) MutationGVRs() []GVREntry

func (*InMemoryAdmissionRegistry) RegisterMutationRules

func (r *InMemoryAdmissionRegistry) RegisterMutationRules(gvrKey string, cfg *orktypes.MutationConfig)

func (*InMemoryAdmissionRegistry) RegisterValidationRules

func (r *InMemoryAdmissionRegistry) RegisterValidationRules(gvrKey string, cfg *orktypes.ValidationConfig)

func (*InMemoryAdmissionRegistry) ValidationGVRs

func (r *InMemoryAdmissionRegistry) ValidationGVRs() []GVREntry

type InMemoryConversionRegistry

type InMemoryConversionRegistry struct {
	// contains filtered or unexported fields
}

InMemoryConversionRegistry holds per-Kind conversion rules. Safe for concurrent use — the /convert endpoint reads from multiple goroutines and Katalog load writes once at startup.

func NewInMemoryConversionRegistry

func NewInMemoryConversionRegistry() *InMemoryConversionRegistry

NewInMemoryConversionRegistry returns an initialised registry.

func NewInMemoryRegistryForTest

func NewInMemoryRegistryForTest() *InMemoryConversionRegistry

Test exports

func (*InMemoryConversionRegistry) GetConversionRules

func (r *InMemoryConversionRegistry) GetConversionRules(kind string) *orktypes.ConversionRules

GetConversionRules returns the rules for a given Kind. Returns nil when no rules are registered for that Kind.

func (*InMemoryConversionRegistry) RegisterConversionRules

func (r *InMemoryConversionRegistry) RegisterConversionRules(rules *orktypes.ConversionRules)

RegisterConversionRules stores rules for the Kind declared in rules.Kind. Called once per CRD entry during Katalog load.

type Katalog

type Katalog struct {
	APIVersion   string                                `yaml:"apiVersion"`
	Kind         string                                `yaml:"kind"`
	Spec         orktypes.KatalogSpec                  `yaml:"spec"`
	Security     orktypes.KatalogSecurity              `yaml:"security"`
	Gateway      *orktypes.GatewayConfig               `yaml:"gateway,omitempty"`
	Notification *orktypes.KatalogNotification         `yaml:"notification,omitempty"`
	Providers    []orktypes.KatalogProviderRequirement `yaml:"providers,omitempty"`

	KomposerMetadata orktypes.KatalogMeta `yaml:"metadata"`
	// contains filtered or unexported fields
}

----------------------------------------------------------------------------- Structs -----------------------------------------------------------------------------

func BuildExpanded added in v0.4.8

func BuildExpanded(kfg *konfig.Konfig, m *merger.Merger) (*Katalog, error)

BuildExpanded is the canonical pipeline for CLI commands that need a fully ready Katalog: merge → expand motifs → validate.

Use this instead of calling KomposeRuntimeKatalog + ValidateConfig separately. For the rare case where validation must be skipped (e.g. ork template --no-validate), call KomposeRuntimeKatalog directly.

func NewEmptyKatalog

func NewEmptyKatalog() *Katalog

Empty katalog for testing

func NewKatalog

func NewKatalog(kfg *konfig.Konfig, m *merger.Merger) *Katalog

NewKatalog returns a list of CRD data

func NewKatalogForTest

func NewKatalogForTest(crds map[string]orktypes.CRDEntry) *Katalog

NewKatalogForTest creates a Katalog with pre-set enabledCRDs for testing. Bypasses YAML parsing and ValidateConfig so tests can construct controlled graphs.

func ParseBytes added in v0.4.8

func ParseBytes(data []byte, dir string) (*Katalog, error)

ParseBytes loads and enriches a Katalog from raw YAML bytes. dir is used as the base directory for resolving relative paths (e.g. crdFile). Pass "." when no specific directory context is available.

func ParseFile added in v0.4.8

func ParseFile(path string) (*Katalog, error)

ParseFile loads and enriches a Katalog from a single YAML file path. Uses a default konfig — suitable for CLI tools (plan, simulate) that do not need the full operator runtime.

func (*Katalog) AdmissionRegistry

func (k *Katalog) AdmissionRegistry() AdmissionRegistry

func (*Katalog) All

func (k *Katalog) All() map[string]orktypes.CRDEntry

All returns every CRD in the katalog, including disabled ones.

func (*Katalog) AllCRDs

func (k *Katalog) AllCRDs() map[string]orktypes.CRDEntry

AllCRDs returns all CRDs including disabled ones (from Spec).

func (*Katalog) CRDEntry added in v0.4.8

func (k *Katalog) CRDEntry(name string) (orktypes.CRDEntry, bool)

CRDEntry returns the enabled CRD entry for the given name.

func (*Katalog) CRDNames

func (k *Katalog) CRDNames() []string

CRDNames returns the names of all enabled CRDs.

func (*Katalog) CertAutoRotate added in v0.4.9

func (k *Katalog) CertAutoRotate() bool

CertAutoRotate reports whether pre-emptive TLS certificate rotation is enabled.

Precedence:

YAML security.certManager.autoRotate declared → use YAML value
YAML absent                                   → fall back to TLS_AUTO_ROTATE env (default: true)

func (*Katalog) CertRotationThreshold added in v0.4.9

func (k *Katalog) CertRotationThreshold() time.Duration

CertRotationThreshold returns the pre-rotation window as a parsed duration. Returns 30 days when the configured value cannot be parsed.

Precedence:

YAML security.certManager.rotationThreshold non-empty → use YAML value
YAML absent or empty                                  → fall back to TLS_ROTATION_THRESHOLD env (default: "30d")

func (*Katalog) CertValidFor added in v0.4.9

func (k *Katalog) CertValidFor() time.Duration

CertValidFor returns the certificate validity duration as a parsed duration. Returns 1 year when the configured value cannot be parsed.

Precedence:

YAML security.certManager.rotateAfter non-empty → use YAML value
YAML absent or empty                                  → fall back to TLS_ROTATE_AFTER env (default: "1y")

func (*Katalog) CertValidForStr added in v0.4.9

func (k *Katalog) CertValidForStr() string

CertValidForStr returns the raw validity string for use in CertificateSpec.ValidFor. Falls back to "1y" when not configured.

func (*Katalog) ClusterName added in v0.6.5

func (k *Katalog) ClusterName() string

ClusterName returns the effective cluster name for this Katalog.

Precedence:

metadata.clusterName non-empty → use Katalog value
CLUSTER_NAME env var set       → use konfig value
Neither set                    → empty string

func (*Katalog) Controllers

func (k *Katalog) Controllers() []string

Controllers returns a list of CRDs that have reconcilers.

func (*Katalog) ConversionRegistry

func (k *Katalog) ConversionRegistry() ConversionRegistry

func (*Katalog) ConversionWindow

func (k *Katalog) ConversionWindow() int

ConversionWindow returns the effective rolling window size for conversion/admission stats.

Precedence:

YAML security.conversion.conversionWindow > 0 → use YAML value
YAML absent or zero                           → fall back to CONVERSION_WINDOW env

func (*Katalog) DebugKatalogInformation added in v0.1.8

func (k *Katalog) DebugKatalogInformation()

Debug katalog information from merger

func (*Katalog) DeletionProtectedCRDNames added in v0.1.9

func (k *Katalog) DeletionProtectedCRDNames() map[string]struct{}

DeletionProtectedCRDNames returns the set of CRD full names (plural.group) managed by this Katalog that should be protected at the **CRD type level**. e.g. {"cronjobs.demo.orkestra.io": {}}

Used by the /deletion-protection handler for name‑based filtering when a DELETE request arrives on the CRD endpoint. A CRD not in this set is allowed through even though the webhook intercepted it.

Per‑CRD control: a CRD name is included only if:

  • Global deletion protection is enabled
  • The CRD is not a built‑in (only custom CRDs can be protected at type level)
  • CRDEntry.ShouldProtectCRD() returns true

This allows administrators to opt out of CRD type protection for specific CRDs via the Katalog's per‑CRD `deletionProtection.protectCRD: false` override.

When running outside the cluster (e.g. `ork run`), the webhook cannot be reached, so no protection is guaranteed.

func (*Katalog) DeletionProtectionCleanupOnShutdown

func (k *Katalog) DeletionProtectionCleanupOnShutdown() bool

DeletionProtectionCleanupOnShutdown reports whether Deletion Protection should be deleted on shutdown.

Precedence:

YAML security.deletionProtection.cleanupOnShutdown present → use YAML value
YAML block absent                                      → fall back to DELETION_PROTECTION_CLEANUP_ON_SHUTDOWN env

func (*Katalog) DeletionProtectionFailurePolicy

func (k *Katalog) DeletionProtectionFailurePolicy() string

DeletionProtectionFailurePolicy returns the effective failure policy string. YAML value takes precedence over ENV.

func (*Katalog) DeletionProtectionGVRs

func (k *Katalog) DeletionProtectionGVRs() []GVREntry

DeletionProtectionGVRs returns the list of GVRs that the deletion‑protection admission webhook should intercept.

This includes:

  • CRDs managed by this Katalog (broad match; handler filters by name)
  • Orkestra’s internal control‑plane resources (deployment, service, serviceaccount, configmap, RBAC objects, ingress, etc.)

The internal resources are derived from the built‑ins registry via OrkestraInternalGVRs(), ensuring the list is declarative and maintained in a single place.

For custom CRDs, the inclusion of their GVRs is controlled by CRDEntry.ShouldProtectCRs() (default true). This allows per‑CRD opt‑out of instance‑level protection.

When running outside the cluster (e.g. `ork run`), the webhook cannot be reached, so no rules are returned.

func (*Katalog) DeletionProtectionServiceName

func (k *Katalog) DeletionProtectionServiceName() string

DeletionProtectionServiceName returns the effective service name for deletion protection. YAML value takes precedence over ENV.

func (*Katalog) DependencyDisplayData added in v0.5.4

func (k *Katalog) DependencyDisplayData() *DependencyDisplay

DependencyDisplayData builds dependency display data for ork validate --full. Returns nil when no enabled CRD declares any dependsOn — callers should skip the section entirely in that case.

func (*Katalog) Dependents

func (k *Katalog) Dependents(name string) []string

Dependents returns all CRDs that depend on the given CRD.

func (*Katalog) Depends

func (k *Katalog) Depends(crdName, target string) bool

Depends returns true if crdName depends on target.

func (*Katalog) Describe

func (k *Katalog) Describe(name string) (string, error)

Describe returns a human‑readable summary of a CRD.

func (*Katalog) Enabled

func (k *Katalog) Enabled() map[string]orktypes.CRDEntry

Enabled returns only the enabled CRDs in the katalog.

func (*Katalog) EnabledCRDs

func (k *Katalog) EnabledCRDs() map[string]orktypes.CRDEntry

EnabledCRDs returns a map of enabled CRDs.

func (*Katalog) Exists

func (k *Katalog) Exists(name string) bool

Exists returns true if a CRD with the given name exists in the katalog.

func (*Katalog) Explain

func (k *Katalog) Explain(name string) (string, error)

Explain returns a technical explanation of how Orkestra handles this CRD.

func (*Katalog) GatewayEndpoint added in v0.4.9

func (k *Katalog) GatewayEndpoint() string

GatewayEndpoint returns the effective gateway endpoint URL.

Precedence:

YAML gateway.endpoint non-empty          → use gateway block value
If not set          	                 → fall back to ORK_GATEWAY_ENDPOINT env

func (*Katalog) GatewayServiceName added in v0.4.9

func (k *Katalog) GatewayServiceName() string

Gateway Service Name returns the effective service name for orkestra gateway. YAML value takes precedence over ENV.

func (*Katalog) GenerateGatewayRBACRules added in v0.4.9

func (k *Katalog) GenerateGatewayRBACRules() []rbacv1.PolicyRule

GenerateGatewayRBACRules returns the RBAC rules required by the gateway process (webhook server, certificate management, namespace labeling).

func (*Katalog) GeneratePerCRDRBACRules added in v0.5.4

func (k *Katalog) GeneratePerCRDRBACRules() map[string][]rbacv1.PolicyRule

GeneratePerCRDRBACRules returns the RBAC rules attributed to each enabled CRD. The map key is the CRD name. Excludes system-level rules (leases, events, secrets, namespaces, webhook configurations) — use GenerateRuntimeRBACRules / GenerateGatewayRBACRules for those.

func (*Katalog) GenerateRBACRules

func (k *Katalog) GenerateRBACRules() []rbacv1.PolicyRule

func (*Katalog) GenerateRuntimeRBACRules added in v0.4.9

func (k *Katalog) GenerateRuntimeRBACRules() []rbacv1.PolicyRule

GenerateRuntimeRBACRules returns the RBAC rules required by the runtime reconciler process. This is GenerateRBACRules() minus the NeedsCertificates() block (webhook/secrets), minus the IsDeletionProtectionEnabled() namespace block, and minus CRD CA-bundle patch rules.

func (*Katalog) Get

func (k *Katalog) Get(name string) (*orktypes.CRDEntry, error)

Get returns an enabled CRD by name.

func (*Katalog) Graph

func (k *Katalog) Graph() map[string][]string

Graph returns a map of CRD name → dependency names.

func (*Katalog) HasConversionPaths

func (k *Katalog) HasConversionPaths() bool

HasConversionPaths returns true only if conversion is enabled and at least one CRD declares conversion paths.

func (*Katalog) HasMutationRules

func (k *Katalog) HasMutationRules() bool

HasMutationRules returns true if admission is enabled and at least one CRD declares mutation rules.

func (*Katalog) HasNotification added in v0.1.9

func (k *Katalog) HasNotification() bool

HasNotification returns whether a katalog has notification configured or not

func (*Katalog) HasTeams

func (k *Katalog) HasTeams() bool

HasTeams returns whether a katalog has teams configured or not

func (*Katalog) HasValidationOrMutationRules added in v0.1.8

func (k *Katalog) HasValidationOrMutationRules() bool

HasValidationOrMutationRules returns true if any CRD has validation or mutation rules.

func (*Katalog) HasValidationRules

func (k *Katalog) HasValidationRules() bool

HasValidationRules returns true if admission is enabled and at least one CRD declares validation rules.

func (*Katalog) IsAdmissionEnabled

func (k *Katalog) IsAdmissionEnabled() bool

IsAdmissionEnabled reports whether admission webhooks are globally enabled.

Precedence:

YAML security.webhooks.admission block present → use YAML value
YAML block absent                              → fall back to ENABLE_ADMISSION_WEBHOOK env

func (*Katalog) IsConversionEnabled

func (k *Katalog) IsConversionEnabled() bool

IsConversionEnabled reports whether the conversion webhook is globally enabled.

Precedence:

YAML security.conversion block present → use YAML value
YAML block absent                      → fall back to ENABLE_CONVERSION env

func (*Katalog) IsDeletionProtectionEnabled

func (k *Katalog) IsDeletionProtectionEnabled() bool

IsDeletionProtectionEnabled reports whether deletion protection is active.

Precedence:

YAML security.deletionProtection block present → use YAML value (default-on when block declared)
YAML block absent                              → fall back to ENABLE_DELETION_PROTECTION env

func (*Katalog) IsEmailNotificationEnabled

func (k *Katalog) IsEmailNotificationEnabled() bool

IsEmailNotificationEnabled reports whether email notifications are possible.

Precedence:

YAML team.email present → require SMTP env capability
YAML absent             → no email notifications

func (*Katalog) IsGatewayEnabled added in v0.5.1

func (k *Katalog) IsGatewayEnabled() bool

IsGatewayEnabled reports whether this Katalog requires the gateway to be installed (paired mode). When true:

  • Helm must install the gateway chart
  • endpoint is optional (runtime may populate it)
  • spec: must be present (CRDs required)

func (*Katalog) IsNamespaceProtectionEnabled added in v0.1.9

func (k *Katalog) IsNamespaceProtectionEnabled() bool

IsNamespaceProtectionEnabled reports whether namespace protection is active.

Precedence:

YAML security.namespaceProtection block present → use YAML value (default-on when block declared)
YAML block absent                               → fall back to ENABLE_NAMESPACE_PROTECTION env

func (*Katalog) IsNotificationStandalone added in v0.4.9

func (k *Katalog) IsNotificationStandalone() bool

IsNotificationStandalone reports whether notification dispatch runs directly on the runtime without a gateway.

Precedence:

YAML notification.standalone declared → use YAML value
Not in a Kubernetes cluster (local dev / CLI) → implicit true
In-cluster, no explicit declaration → false (gateway required)

func (*Katalog) IsSlackNotificationEnabled

func (k *Katalog) IsSlackNotificationEnabled() bool

IsSlackNotificationEnabled reports whether Slack notifications are possible.

func (*Katalog) IsStandaloneGateway added in v0.4.9

func (k *Katalog) IsStandaloneGateway() bool

IsStandaloneGateway reports whether this Katalog is deployed as a standalone gateway with no companion runtime operator.

When true:

  • gatewayEndpoint validation is skipped
  • spec: may be empty (no CRDs required)

func (*Katalog) IsStrictModeEnabled added in v0.4.8

func (k *Katalog) IsStrictModeEnabled() bool

IsStrictModeEnabled reports whether strict mode is active for deletion protection. Strict mode treats removal of the deletion-protection label as a deletion attempt. Only valid when deletion protection is also enabled.

func (*Katalog) IsWebhookControllerEnabled added in v0.1.9

func (k *Katalog) IsWebhookControllerEnabled() bool

IsWebhookControllerEnabled reports whether the webhook controller is enabled.

func (*Katalog) KomposeRuntimeKatalog added in v0.3.1

func (k *Katalog) KomposeRuntimeKatalog(
	kfg *konfig.Konfig,
	m *merger.Merger,
	paths ...string,
) (map[string]orktypes.CRDEntry, error)

KomposeRuntimeKatalog composes the runtime Katalog for Orkestra from merged configuration sources.

This function is the central entry point for transforming the declarative Katalog (YAML files + overrides) into a fully resolved, validated, and defaulted runtime representation (map of CRDEntry). It is called once at Orkestra startup.

The runtime Katalog is used for:

  • Reconciliation (controller loops, worker counts, resync periods)
  • Admission webhooks (validation, mutation, deletion protection)
  • Child resource materialisation (operatorBox onCreate/onReconcile)
  • Status field resolution (Layer 2 status)
  • Enrichment (owner, replicasets, pods, HPA)

Processing steps (in order):

  1. Extract merged spec, security, gateway, providers, and metadata from the merger.

  2. Retrieve the list of enabled CRDs (the union of all declarations).

  3. For each CRD entry:

    - If a CRD file path is provided, populate APITypes from the actual CRD (group, version, plural, scope) – this overrides any inline apiTypes.

    - Run enrichment (EnrichCRDEntry) to resolve kind-only built-in declarations (e.g., "Namespace" → group: "", version: "v1", plural: "namespaces").

  4. Expand motif imports declared in operatorBox blocks (motif re-use across CRDs).

  5. Initialize conversion and admission registries (for webhook generation).

  6. Register validation, mutation, and conversion rules from each CRD entry.

  7. Apply defaults (workers, max queue depth, resync, etc.) from the global config.

Returns the final map of CRDEntry keyed by CRD name, ready for the reconciler and webhook servers.

Errors are returned for:

  • Missing or invalid CRD files
  • Unknown built-in kinds during enrichment
  • Partially specified apiTypes (e.g., kind+group but no version)
  • Motif import resolution failures
  • Default assignment errors

Example:

runtimeCRDs, err := katalog.KomposeRuntimeKatalog(kfg, merger, "path/to/katalog")

func (*Katalog) List

func (k *Katalog) List() map[string]orktypes.CRDEntry

func (*Katalog) Meta

func (k *Katalog) Meta() orktypes.KatalogMeta

Useful Metadata

func (*Katalog) Metadata

func (k *Katalog) Metadata() orktypes.KatalogMeta

func (*Katalog) NamespaceProtectionCleanupOnShutdown added in v0.1.9

func (k *Katalog) NamespaceProtectionCleanupOnShutdown() bool

NamespaceProtectionCleanupOnShutdown reports whether Deletion Protection should be deleted on shutdown.

Precedence:

YAML security.namespaceProtection.cleanupOnShutdown present → use YAML value
YAML block absent                                      → fall back to NAMESPACE_PROTECTION_CLEANUP_ON_SHUTDOWN env

func (*Katalog) NamespaceProtectionFailurePolicy added in v0.1.9

func (k *Katalog) NamespaceProtectionFailurePolicy() string

NamespaceProtectionFailurePolicy returns the effective failure policy string. YAML value takes precedence over ENV.

func (*Katalog) NamespaceProtectionGVRs added in v0.1.9

func (k *Katalog) NamespaceProtectionGVRs() []GVREntry

NamespaceProtectionGVRs returns the list of GVRs for CRDs that declare allowedNamespaces or restrictedNamespaces. Only these CRDs are intercepted by the namespace-protection webhook.

When running outside the cluster (e.g. `ork run`), the webhook cannot be reached, so no rules are returned.

func (*Katalog) NamespaceProtectionRuleMap added in v0.1.9

func (k *Katalog) NamespaceProtectionRuleMap() map[string]NamespaceRuleEntry

NamespaceProtectionRuleMap returns the allowed/restricted namespace lists for every CRD that declares namespace rules. Key format is "plural.group" — matching the lookup key used by the /namespace-protection handler.

Returns nil when namespace protection is disabled.

func (*Katalog) NamespaceProtectionServiceName added in v0.1.9

func (k *Katalog) NamespaceProtectionServiceName() string

NamespaceProtectionServiceName returns the effective service name for namespace protection. YAML value takes precedence over ENV.

func (*Katalog) NeedsCertificates

func (k *Katalog) NeedsCertificates() bool

NeedsCertificates reports whether Orkestra must generate TLS certificates.

Certificates are required when deletion protection, admission webhooks, or conversion webhooks are enabled with valid usecases configured in at least 1 CRD— all three use the same TLS cert.

func (*Katalog) NeedsGateway added in v0.4.9

func (k *Katalog) NeedsGateway() bool

NeedsGateway reports whether this Katalog requires a companion gateway process.

A gateway is required when any of the following are configured:

  • Security features that run on the gateway's HTTPS server (deletion protection, admission webhooks, conversion, namespace protection)
  • Notifications — unless standalone: true is declared (or implied by local dev)

Used by ValidateConfig to fail fast when gatewayEndpoint is not set.

func (*Katalog) NotificationInterval

func (k *Katalog) NotificationInterval(teamName string) orktypes.Duration

NotificationInterval returns the effective interval for a team.

Precedence:

YAML team.interval > YAML defaults.interval > ENV defaultInterval > hard default

func (*Katalog) Order

func (k *Katalog) Order() []string

Order returns CRDs in dependency‑safe order (topological sort).

func (*Katalog) ProjectInfo added in v0.3.9

func (k *Katalog) ProjectInfo() interface{}

ProjectInfo returns the project information for use by control center. Populated by ork-doctor at generation time; empty in operator-authored Katalogs.

func (*Katalog) Projects added in v0.4.2

func (k *Katalog) Projects() map[string]interface{}

Projects returns the map of all project infos from the katalog metadata. Populated by the developer path (createdBy: orkdoctor) via ork doctor deploy.

func (*Katalog) ResolveGVR added in v0.4.1

ResolveGVR resolves a ManagedResource into a concrete GroupVersionResource.

Resolution priority (explicit always wins):

  1. Full explicit GVR: - group + version + plural are all provided → use them directly.

  2. Explicit group + version (plural omitted) → infer plural as strings.ToLower(kind) + "s".

  3. APIVersion + plural: - apiVersion: "group/version" - plural provided → parse apiVersion and use provided plural.

  4. APIVersion only: - apiVersion: "group/version" - plural omitted → parse apiVersion and infer plural as strings.ToLower(kind) + "s".

  5. Built‑in Kubernetes resource: - kind matches Orkestra's built‑in registry → use children.GVRForBuiltIn(kind).

  6. Otherwise: → resolution fails and (GVR{}, false) is returned.

This ensures:

  • Explicit declarations always override inference.
  • Custom resources can be fully specified without guessing.
  • Built‑ins remain simple (kind‑only).
  • RBAC generation remains deterministic and zero‑footprint safe.

func (*Katalog) RuntimeServiceName added in v0.4.9

func (k *Katalog) RuntimeServiceName() string

Runtime Service Name returns the effective service name for orkestra runtime. YAML value takes precedence over ENV.

func (*Katalog) SMTPConfig

func (k *Katalog) SMTPConfig() (host string, port int, user, pass, from string)

SMTPConfig returns the effective SMTP configuration (from ENV only).

func (*Katalog) Scheme added in v0.4.8

func (k *Katalog) Scheme() (*runtime.Scheme, error)

Scheme builds and returns a runtime.Scheme with all Katalog types registered.

func (*Katalog) SerializeExpanded added in v0.4.8

func (k *Katalog) SerializeExpanded() ([]byte, error)

SerializeExpanded serializes the post-KomposeRuntimeKatalog state to YAML.

The output is a valid Katalog YAML with fully expanded CRDs (all motif imports already inlined, imports: field absent). This is what the bundle's ConfigMap should embed — the runtime can load it without any OCI pulls.

Must be called after KomposeRuntimeKatalog; returns an error if no CRDs are present (indicates expansion hasn't been run yet).

func (*Katalog) SlackWebhook

func (k *Katalog) SlackWebhook() string

SlackWebhook returns the effective Slack webhook URL (from ENV only).

func (*Katalog) ToUI

func (k *Katalog) ToUI() *orktypes.KatalogForUI

ToUI returns a UI-friendly representation of the merged Katalog. This method extracts only the fields needed for display in the Control Center:

  • API version and kind (always "Katalog" at runtime)
  • Metadata (name, description, version, author, license)
  • All merged CRD definitions

Internal fields (Scheme, GroupVersionKind, etc.) are excluded because they have `yaml:"-" json:"-"` tags and won't be serialized to JSON.

This method is used by the /katalog/raw endpoint to provide a clean, readable view of the Katalog that created the current operator.

func (*Katalog) Uses

func (k *Katalog) Uses(resource string) bool

Uses reports whether any enabled CRD uses the given resource in a hook template block. Accepts both singular ("deployment") and plural ("deployments") keys, as well as shorthands ("hpa"). Drives off builtInRegistry — no separate table to maintain.

func (*Katalog) ValidateConfig

func (k *Katalog) ValidateConfig(kfg *konfig.Konfig) (*Katalog, error)

Validate Config

func (*Katalog) WebhookCleanupOnShutdown

func (k *Katalog) WebhookCleanupOnShutdown() bool

WebhookCleanupOnShutdown reports whether admission webhooks should be deleted on shutdown.

Precedence:

YAML security.webhooks.cleanupOnShutdown present → use YAML value
YAML block absent                                → fall back to WEBHOOK_CLEANUP_ON_SHUTDOWN env

func (*Katalog) WebhookControllerSyncInterval added in v0.1.9

func (k *Katalog) WebhookControllerSyncInterval() time.Duration

WebhookControllerSyncInterval returns the webhook controller sync interval.

func (*Katalog) WebhookResources added in v0.3.7

func (k *Katalog) WebhookResources() []string

WebhookResources returns the list of admission webhook resources that Orkestra needs to manage when webhooks/certificates are required.

Rules:

  • validatingwebhookconfigurations is required for deletion protection, namespace protection, or any validation rules.
  • mutatingwebhookconfigurations is required only when mutation rules exist.
  • conversion webhooks are handled separately and do not require these resources.

func (*Katalog) WebhooksFailurePolicy

func (k *Katalog) WebhooksFailurePolicy() string

WebhooksFailurePolicy returns the effective failure policy for admission webhooks. YAML value takes precedence over ENV.

func (*Katalog) WebhooksServiceName

func (k *Katalog) WebhooksServiceName() string

WebhooksServiceName returns the effective service name for admission/conversion webhooks. YAML value takes precedence over ENV.

func (*Katalog) WithCRDFiles added in v0.7.4

func (k *Katalog) WithCRDFiles() []string

WithCRDFiles returns the names of CRDs that declared a crdFile. Populated during KomposeRuntimeKatalog before the field is cleared, so callers can inspect which CRDs used the local-file shortcut even after apiTypes have been resolved and CRDFile wiped.

type MotifValidationError added in v0.3.9

type MotifValidationError struct {
	Path    string
	Message string
}

MotifValidationError represents a single validation failure for a Motif.

func ValidateMotif added in v0.3.9

func ValidateMotif(path string) []MotifValidationError

ValidateMotif validates a Motif YAML file at the given path. Returns a slice of errors — empty means valid.

func ValidateMotifImports added in v0.3.9

func ValidateMotifImports(crdName string, imports []orktypes.MotifImport) []MotifValidationError

ValidateMotifImports validates that all imports in an operatorBox have required inputs provided in their with: block.

func (MotifValidationError) Error added in v0.3.9

func (e MotifValidationError) Error() string

type NamespaceRuleEntry added in v0.1.9

type NamespaceRuleEntry struct {
	Allowed    []string
	Restricted []string
}

NamespaceRuleEntry holds the raw allowed/restricted namespace lists for one CRD. Returned by NamespaceProtectionRuleMap so callers can build their own lookup structures.

type Node

type Node struct {
	Name      string
	CRD       orktypes.CRDEntry
	InDegree  int // number of CRDs this CRD depends on
	OutDegree int // number of CRDs that depend on this CRD
}

Node represents a single CRD in the dependency graph.

Jump to

Keyboard shortcuts

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