types

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: 21 Imported by: 0

README

pkg/types

types is the foundational contract package for the Orkestra control plane. It defines every shared struct, interface, and registry that the runtime, reconcilers, generators, and CLI tooling share. No other Orkestra package should duplicate a type that belongs here.

The package is large by design — centralising types avoids import cycles. Callers import pkg/types (aliased as orktypes by convention) and access everything they need from one import.

File organisation

File(s) What they define
types.go Core CRD entry shape — CRDEntry, OperatorBox, HookTemplates
katalog.go, katalog_spec_providers.go Katalog and Komposer document shapes
sources.go Per-resource template source structs (DeploymentTemplateSource, ServiceTemplateSource, …)
foreach.go ForEachSpec — the forEach field shared by all template sources
hook_temp.go, hooks_resources.go, hooks_probes.go, hooks_sleep.go Hook template structs and nested blocks
hook_methods.go Methods on hook types (UsesTemplates, template detection helpers)
methods.go Methods on CRDEntry (IsEnabled, DefaultReconcile, ShouldEnrich, …)
registry.go Runtime type registries (ObjectRegistry, ListRegistry, HookRegistry, ReconcilerRegistry)
status.go Status field declarations and StatusField shape
conditions.go Condition helpers used by reconcilers
enrichment.go EnrichmentSpec — the enrich: list on a CRD entry
provider.go, provider_katalog.go Provider interface and ProviderDeclaration
security.go Security policy types (SecuritySpec, deletion protection, namespace restriction)
notification.go Notification policy types
autoscale.go Worker autoscale policy
rollback.go Rollback policy and trigger conditions
secret_rotation.go Secret rotation policy
when.go WhenSpec — conditional expressions for provider declarations
admission.go, conversion.go Webhook configuration types
external.go, docker.go, git.go External call, Docker, and Git integration types
cross.go, cross_methods.go, cross_oncop.go Cross-CRD dependency types
custom_resource.go Dynamic unstructured CR helpers
func.go Function declaration types (hooks, constructors)
normalize.go Field normalisation helpers
ns_allowed.go, ns_restricted.go Namespace restriction helpers
motif.go Motif document type
e2e.go E2E document type

Convention

All callers import this package with the orktypes alias:

import orktypes "github.com/orkspace/orkestra/pkg/types"

Contributor docs

Document What it covers
docs/hook-visitor-pattern.md How to write cross-hook validators using VisitResources + typed interfaces. Read this before adding a new field validator to pkg/katalog/.

Documentation

Overview

pkg/types/admission.go

pkg/types/autoscale.go

Autoscale configuration for an operatorbox.

The autoscaler adjusts workers, queueDepth, and resync at runtime based on metric conditions, time windows, and cron expressions. The CRD's declared values are always the baseline — overrides are temporary and automatically reverted when conditions are no longer met.

YAML shape (inside operatorBox:):

operatorBox:
  autoscale:
    interval: 15s
    cooldown: 2m
    conditions:
      anyOf:
        - time:
            after: "08:00"
            before: "17:00"
        - cron: "0 20 * * 1-5"
          duration: 4h
      when:
        - field: metrics.queueDepth
          greaterThan: "200"
    do:
      workers: 12
      queueDepth: 1000
      resync: 20s

pkg/types/conditions.go

pkg/types/conversion.go

pkg/types/cross.go

Cross-CRD observation declarations.

The cross: block under a CRD's reconciler allows one CR to observe another CRD's CR instances without making API server calls — data is read from the target CRD's informer cache directly.

YAML:

spec:
  crds:
    application:
      cross:
        - crd: database             # target CRD name (lowercase, matches spec.crds key)
          selector:
            name: "{{ .metadata.name }}"       # find by name
            namespace: "{{ .metadata.namespace }}"
          as: database              # available as .cross.database.*

    database:
      operatorBox: ...               # database CRD — already has an informer

After ReadCross runs, the Application reconciler has access to:

{{ .cross.database.found }}                → "true" if CR was found
{{ .cross.database.status.phase }}         → Database CR's status.phase
{{ .cross.database.status.endpoint }}      → Database CR's status.endpoint
{{ .cross.database.spec.storageGb }}       → Database CR's spec field

This is zero API calls for same-binary CRDs — data comes from the informer cache that is already maintained for the target CRD. For cross-binary or cross-cluster observation, set source.endpoint.

Use cases:

  • Wait for a Database CR to be Ready before creating the Application Deployment
  • Copy a Database endpoint into the Application status
  • Gate resource creation on another CRD's phase
  • Service mesh without a service mesh: Application watches Database watches Network

pkg/types/external.go

External HTTP call declarations.

The external: block under onReconcile allows declarative HTTP calls before resource creation. Results are injected into the resolver context and available in subsequent template expressions and when: conditions.

YAML:

onReconcile:
  external:
    - name: health-check
      url: "{{ .spec.serviceUrl }}/health"
      method: GET
      expectedStatus: 200
      continueOnError: false
      timeout: 5s

    - name: feature-flags
      url: "https://flags.internal/api/{{ .metadata.name }}"
      method: GET
      token: "$FEATURE_FLAG_TOKEN"
      continueOnError: true

  deployments:
    - name: "{{ .metadata.name }}"
      image: "{{ .spec.image }}"
      when:
        - field: external.health-check.status
          equals: "200"
        - field: external.feature-flags.body
          contains: "\"enabled\":true"

Calls run sequentially in declaration order before any resource groups. Results are immutable once injected — a call cannot see a later call's result.

Security: tokens are resolved via the standard resolver — use environment variable references ($TOKEN) or Kubernetes Secret references via the KubeReader mechanism. Never put raw secrets in Katalog YAML.

pkg/types/foreach.go

ForEachSpec — declares dynamic resource expansion over a list field.

When a template source declares forEach, the reconciler expands it into N resource declarations — one per element in the list field.

The item is injected into the resolver context and available as:

{{ .item }}      — always available
{{ .<as> }}      — the name declared in forEach.as
{{ .index }}     — 0-based position in the list

YAML:

onReconcile:
  deployments:
    - name: "{{ .metadata.name }}-{{ .item }}"
      image: "{{ .spec.image }}"
      forEach:
        field: spec.regions       # list field on the CR
        as: item                  # optional, default: "item"

For CR with spec.regions: [us-east-1, eu-west-1, ap-southeast-1]: Produces three Deployments:

my-app-us-east-1
my-app-eu-west-1
my-app-ap-southeast-1

Each declaration is fully independent — when:, anyOf:, labels, and all other fields are evaluated per-item with .item in context.

forEach works on all resource types: deployments, services, secrets, configmaps, jobs, cronjobs, serviceaccounts.

Nesting: forEach is not nestable. One level of expansion per declaration. For matrix expansion (regions × environments), declare two separate resource types or use a hook.

pkg/types/katalog.go

pkg/types/motif.go

pkg/types/notification_refined.go

This file replaces the KatalogNotification type in pkg/types. It adds:

  • enabled: true/false at the notification block level
  • per-team Slack webhookUrl (overrides the global default)
  • a global default Slack webhook
  • message template field per team for customisation
  • rollback integration (notify on rollback via existing team references)

YAML shape:

notification:
  enabled: true
  defaults:
    interval: 15m
    slackWebhookUrl: "https://hooks.slack.com/services/..."  # global default
  teams:
    platform:
      email: ["platform@company.io"]
      slack: ["#platform-alerts"]
      slackWebhookUrl: "https://hooks.slack.com/services/..."  # override
      interval: 5m
      message: "{{ .metadata.name }} in {{ .metadata.namespace }}: {{ .status.conditions.Ready.message }}"
    oncall:
      slack: ["#oncall"]
      interval: 1m

# On conditions:
when:
  - field: status.phase
    equals: Degraded
    notify: [platform, oncall]

# On rollback:
rollback:
  trigger:
    consecutiveFailures: 3
  notify: [oncall]     # fires when rollback activates

SMTP config is read from pkg/konfig env vars — not declared in YAML. Slack webhook URL is per-team or global default — not from env (user choice).

pkg/types/ns_allowed.go

pkg/types/ns_restricted.go

pkg/types/provider.go

Provider interface — the extension point for external infrastructure.

A provider handles a named YAML block in onCreate/onReconcile/onDelete. Orkestra dispatches the block to the registered provider after all Kubernetes resource groups have been reconciled.

Registration (in cmd/operator/main.go or wherever komponents are wired):

registry := orktypes.NewProviderRegistry()
registry.Register(awsprovider.New(sess))
registry.Register(mongoprovider.New(uri))

Katalog usage:

onCreate:
  aws:
    - rds:
        instanceClass: db.t3.micro
        engine: postgres
  database:
    - driver: mongo
      uri: "$MONGO_ATLAS_URI"
      createUser: "{{ .spec.dbUser }}"

Orkestra calls provider.Reconcile for each block whose name matches a registered provider. Unregistered blocks are skipped with a warning. Provider errors fail the reconcile cycle and trigger backoff.

pkg/types/provider_katalog.go

Provider types for Katalog YAML parsing and runtime dispatch.

Layer 1 — Katalog-level manifest (KatalogProviderRequirement)

Declared at the top level under providers[]. Lists which providers this Katalog uses and supplies the credentials for each. Credentials support $ENV_VAR expansion. Only providers registered here are active — per-CRD blocks for unregistered providers are skipped with a warning.

providers: is a top-level sibling of spec: and security:, not nested under spec:, because providers represent operational infrastructure dependencies — distinct state from the CRD definitions in spec:.

providers:
  - name: aws
    required: true
    auth:
      accessKeyId: "$AWS_ACCESS_KEY_ID"
      secretAccessKey: "$AWS_SECRET_ACCESS_KEY"
      region: "$AWS_REGION"
  - name: mongodb
    required: true
    auth:
      mongoUri: "$MONGODB_URL"

Layer 2 — Per-CRD provider blocks (ProviderBlock, RawProviderDeclaration)

Declared under spec.crds[].operatorBox.providers. Each named block is dispatched to the registered provider library. Template expressions are resolved before the provider is called. A per-CRD auth block can override the katalog-level credentials for that CRD.

operatorBox:
  providers:
    aws:
      - s3:
          bucket: "{{ .metadata.name }}-assets"
          region: "{{ .spec.region }}"
    mongodb:
      - database:
          name: "{{ .metadata.name }}"
      - user:
          name: "{{ .spec.dbUser }}"
          database: "{{ .metadata.name }}"
          credentials:
            secretName: "{{ .metadata.name }}-mongo-creds"

pkg/types/registry.go

pkg/types/rollback.go

Rollback — declarative failure recovery for operatorboxes.

When a reconcile fails a configurable number of times (or within a time window), Orkestra enters a rollback phase. In this phase it applies the previous desired state — captured before the failing spec change was applied — and blocks normal reconciliation until the operator fixes the spec.

Rollback is not "undo" in the transactional sense. It is "re-apply the last known good declaration." The existing Update functions handle idempotent re-application — no new primitives are needed.

YAML shape (inside operatorBox:):

operatorBox:
  rollback:
    trigger:
      consecutiveFailures: 3    # OR
      withinDuration: 5m        # triggers if N failures occur within this window
    onRollback:
      deployments:
        - name: "{{ .previous.metadata.name }}"
          image: "{{ .previous.spec.image }}"
          replicas: "{{ .previous.spec.replicas }}"
          reconcile: true
      configMaps:
        - name: "{{ .previous.metadata.name }}-config"
          reconcile: true

The .previous.* context is hydrated from the annotation:

orkestra.orkspace.io/previous-spec

which is written atomically before each spec change is applied.

The rollback phase exits only when the spec changes (new generation). Until then, normal onCreate/onReconcile is blocked.

pkg/types/security.go

Security configuration at the Katalog level.

The unified security block covers four concerns:

  1. Deletion protection — webhook that blocks deletion of managed CRDs and the operator itself.
  2. Admission webhooks — ValidatingWebhookConfiguration and MutatingWebhookConfiguration.
  3. Conversion — CRD version conversion via /convert (separate from webhooks).

YAML shape:

security:
  deletionProtection:
    enabled: true            # default: true when block is present
    serviceName: orkestra    # default: ORK_SERVICE_NAME env / "orkestra"
    failurePolicy: Fail      # default: Fail

  webhooks:
    admission:
      enabled: true          # default: ENABLE_ADMISSION_WEBHOOK env / false
    failurePolicy: Ignore    # default: WEBHOOKS_FAILURE_POLICY env / "Ignore"
    serviceName: orkestra    # default: ORK_SERVICE_NAME env / "orkestra"

  conversion:
    enabled: true            # default: ENABLE_CONVERSION env / false
    conversionWindow: 100    # default: CONVERSION_WINDOW env / 100

Precedence: katalog YAML value > ENV value > hard default. ENV values populate SecurityConfig during Init() and act as defaults. Katalog values are merged on top in KomposeRuntimeKatalog.

pkg/types/sources.go

pkg/types/status.go

pkg/orktypes/types.go

pkg/types/types_configmap.go

pkg/types/types_crd_entry.go

pkg/types/types_dependson.go

pkg/types/types_deployment.go

pkg/types/types_hook_templates.go

pkg/types/types_hpa.go

pkg/types/types_ingress.go

pkg/types/types_job.go

pkg/types/types_operatorbox.go

pkg/types/types_pdb.go

pkg/types/types_pod.go

pkg/types/types_probes.go

pkg/types/types_pvc.go

pkg/types/types_rbac.go

pkg/types/types_replicaset.go

pkg/types/types_secret.go

pkg/types/types_service.go

pkg/types/types_serviceaccount.go

pkg/types/types_shared.go

pkg/types/types_statefulset.go

pkg/types/when.go

EvaluateWhen — extended condition evaluation with OR logic.

The when: field ([]Condition) uses AND semantics. anyOf: is a new parallel field on template sources with OR semantics.

# AND only
when:
  - field: status.phase
    equals: "Ready"

# OR
anyOf:
  - field: status.phase
    equals: "Failed"
  - field: status.phase
    equals: "Succeeded"

# Combined: (spec.enabled=true) AND (phase=Failed OR phase=Succeeded)
when:
  - field: spec.enabled
    equals: "true"
anyOf:
  - field: status.phase
    equals: "Failed"
  - field: status.phase
    equals: "Succeeded"

Index

Constants

View Source
const (
	// AnnotationGeneratedAt is the RFC3339 timestamp when the secret was last generated.
	AnnotationGeneratedAt = "orkestra.orkspace.io/generated-at"

	// AnnotationRotateAfter stores the declared rotation duration.
	AnnotationRotateAfter = "orkestra.orkspace.io/rotate-after"
)
View Source
const (
	CRDModeTyped   CRDMode = "typed"
	CRDModeDynamic CRDMode = "dynamic"

	DependencyConditionStarted DependencyCondtion = "started"
	DependencyConditionHealthy DependencyCondtion = "healthy"

	// Future
	DependencyCondtionPending   DependencyCondtion = "pending"
	DependencyCondtionReady     DependencyCondtion = "ready"
	DependencyConditionDegraded DependencyCondtion = "degraded"
	DependencyConditionDeleted  DependencyCondtion = "deleted"
)
View Source
const PreviousSpecAnnotation = "orkestra.orkspace.io/previous-spec"

PreviousSpecAnnotation is the annotation key where the previous spec is stored before a spec change is applied. Value is a base64-encoded, gzip-compressed JSON of the CR spec.

View Source
const RollbackGenerationAnnotation = "orkestra.orkspace.io/rollback-at-generation"

RollbackGenerationAnnotation records the generation at which rollback was last triggered. Used to detect spec changes that should exit rollback.

Variables

View Source
var HookRegistry = map[schema.GroupVersionKind]func() domain.AnyReconcileHooks{}
View Source
var ListRegistry = map[schema.GroupVersionKind]func() runtime.Object{}
View Source
var ObjectRegistry = map[schema.GroupVersionKind]func() runtime.Object{}
View Source
var ReconcilerRegistry = map[schema.GroupVersionKind]NewReconcilerFunc{}
View Source
var SchemeAdderFns []func(*runtime.Scheme) error

SchemeAdderFns holds AddToScheme functions collected from generated init() calls. Each generated zz_generated_runtime_registry.go appends to this slice in its init(); NewSchemeRegistry drains it via RegisterTypedScheme. This is the bridge between the user's generated package and the Orkestra internal pkg/runtime stub — no explicit call needed beyond the blank import.

Functions

func BuildONCOPURL added in v0.4.5

func BuildONCOPURL(decl CrossCRDDeclaration) string

BuildONCOPURL constructs an Orkestra‑native cross‑operator URL using the Orkestra Native Cross‑Operator Protocol (ONCOP).

ONCOP allows cross‑binary CRD observation without requiring callers to hard‑code full URLs. When a CrossSource specifies a Host (and no Endpoint), the final URL is inferred from:

  • the CRD name extracted from the field path (cross.<crd>.…)
  • the Source.Type ("info", "metrics", "health", "events")
  • the Source.Namespace override (optional)
  • the CR's own namespace/name when Type requires it

URL shapes:

Type: "cr"    → <host>/katalog/<crd>/cr/<ns>/<name>
Type: "info"    → <host>/katalog/<crd>
Type: "metrics" → <host>/katalog/<crd>
Type: "health"  → <host>/katalog/<crd>/health
Type: "events"  → <host>/katalog/<crd>/cr/<ns>/<name>/events

If Source.Endpoint is provided, ONCOP is bypassed entirely and the raw endpoint is used as‑is. This enables integration with non‑Orkestra operators or arbitrary JSON‑producing services.

BuildONCOPURL centralises this logic so all cross‑CRD resolution paths (metrics, health, info, autoscale conditions, status.fields) share the same URL construction semantics.

func EvaluateOneCond

func EvaluateOneCond(data map[string]interface{}, cond Condition, eval TemplateEvaluator) bool

EvaluateOneCond evaluates a single Condition against a data map. Exported so the template package and reconciler package can both call it. Defined here in pkg/types to avoid import cycles.

When cond.Field is a template expression AND eval is non-nil, the expression is evaluated and the string result is used for operator comparison. Time-based conditions (time:, dayOfWeek:, cron:) are evaluated against the current wall clock — they do not reference the data map.

func EvaluateWhen

func EvaluateWhen(data map[string]interface{}, allOf []Condition, anyOf []Condition, eval TemplateEvaluator) bool

EvaluateWhen evaluates when: (allOf, AND) and anyOf: (OR) conditions. data is resolver.Data() — full CR map including children, external, cross. eval is optional — pass nil to disable template evaluation (backward compatible).

Both blocks must pass when both are declared. Empty blocks always pass.

func ExtractCrossCRD added in v0.4.5

func ExtractCrossCRD(field string) string

ExtractCrossCRD returns the <crd> portion of a cross.* field path. Examples:

cross.loader.metrics.queueDepth      → "loader"
cross.processor.health.state         → "processor"
cross.db.info.status.phase           → "db"

func ExtractCrossCategory added in v0.4.5

func ExtractCrossCategory(field string) string

ExtractCrossCategory returns the category segment after cross.<crd>. Examples:

cross.loader.metrics.queueDepth → "metrics"
cross.db.health.state           → "health"
cross.api.info.status.phase     → "info"

func ExtractCrossFieldName added in v0.4.5

func ExtractCrossFieldName(field string) string

ExtractCrossFieldName returns the field name after the category. Examples:

cross.loader.metrics.queueDepth → "queueDepth"
cross.db.health.lastError       → "lastError"
cross.api.info.status.phase     → "status.phase"

func ExtractCrossNamespace added in v0.4.5

func ExtractCrossNamespace(field string) string

ExtractCrossNamespace returns the namespace portion for ONCOP info/events when encoded in a field path of the form:

cross.<crd>.info.<namespace>.<name>.status.phase

If no namespace is encoded, returns "".

Examples:

cross.db.info.default.my-db.status.phase → "default"
cross.api.info.prod.service-a.spec.port  → "prod"
cross.loader.metrics.queueDepth          → ""

NOTE: Namespace is only encoded for info/events categories. Metrics/health do not carry namespace in the field path.

func ExtractCrossSuffix added in v0.4.5

func ExtractCrossSuffix(field string) string

ExtractCrossSuffix returns the suffix after cross.<crd>. in a field path. Examples:

cross.loader.metrics.queueDepth  → "metrics.queueDepth"
cross.db.health.lastError        → "health.lastError"
cross.api.info.status.phase      → "info.status.phase"

func IsCrossChildrenField added in v0.4.5

func IsCrossChildrenField(field string) bool

IsCrossChildrenField returns true when the field path refers to another operatorbox's managed Kubernetes children via cross.*.children.*.

func IsCrossEventsField added in v0.4.5

func IsCrossEventsField(field string) bool

IsCrossEventsField returns true when the field path refers to another operatorbox's CR events via the cross.*.events.* namespace.

func IsCrossHealthField added in v0.4.5

func IsCrossHealthField(field string) bool

IsCrossHealthField returns true when the field path refers to another operatorbox's runtime health via the cross.*.health.* namespace.

func IsCrossInfoField added in v0.4.5

func IsCrossInfoField(field string) bool

IsCrossInfoField returns true when the field path refers to another operatorbox's CR detail (the CRD info endpoint) via cross.*.info.*.

func IsCrossMetricField added in v0.4.5

func IsCrossMetricField(field string) bool

IsCrossMetricField returns true when the field path refers to another operatorbox's runtime metrics via the cross.*.metrics.* namespace.

func IsValidProtocol added in v0.3.9

func IsValidProtocol(p string) bool

IsValidProtocol reports whether the provided protocol is valid. Accepted values (case‑insensitive):

  • TCP
  • UDP
  • SCTP

func IsValidServiceType added in v0.3.9

func IsValidServiceType(t string) bool

IsValidServiceType reports whether the provided service type is valid. Accepted values (case‑insensitive):

  • ClusterIP
  • NodePort
  • LoadBalancer
func NavigateDotPath(m map[string]interface{}, path string) string

NavigateDotPath walks a dot-notation path through a nested map. Returns "" when any segment is missing — the notExists case. Exported for use by the template package and status field resolver.

func NavigateRawPath(m map[string]interface{}, path string) interface{}

NavigateRawPath walks a dot-notation path through a nested map. Returns interface{} when any segment is missing — the notExists case. Exported for use by the template package and status field resolver.

func NeedsRotation

func NeedsRotation(generatedAt, rotateAfter string) bool

NeedsRotation returns true when the secret has exceeded its rotation threshold. generatedAt is the value of the AnnotationGeneratedAt annotation. rotateAfter is the declared rotation duration string.

func ParseTimeDuration added in v0.4.2

func ParseTimeDuration(s string) (time.Duration, error)

ParseTimeDuration parses a human‑friendly rotation duration string.

It extends Go's time.ParseDuration by adding long‑term units:

d   = days (24h)
w   = weeks (7d)
mo  = months (30d)
y   = years (365d)

Examples:

"30s"     → 30 seconds
"5m"      → 5 minutes (Go duration)
"12h"     → 12 hours
"10d"     → 10 days
"2w"      → 14 days
"3mo"     → 90 days
"1y"      → 365 days

Notes:

  • Only "mo" is accepted for months to avoid collision with Go's "m" (minutes).
  • Fractional values are supported (e.g., "1.5mo").
  • Falls back to time.ParseDuration for standard units.

func TickCronWindow added in v0.1.9

func TickCronWindow(windows map[string]time.Time, cronExpr string, duration, interval time.Duration, now time.Time) bool

TickCronWindow advances the cron window state machine for one expression. It updates windows (caller-owned state map) and returns whether the window is currently open.

duration is how long the window stays open after a cron fire. interval is the evaluation tick period — used to detect fires between ticks. When duration is zero, interval is used as the window length.

This is the general-purpose cron window tracker. Any part of Orkestra that needs cron-gated behaviour (autoscaler, future job runner, etc.) can bring its own map[string]time.Time and call this on each evaluation tick.

func UsesTemplates added in v0.4.8

func UsesTemplates[T any](tpl *HookTemplates, sel func(*HookTemplates) []T) bool

UsesTemplates safely checks a HookTemplates pointer and returns true if the selected slice contains at least one template. Used by pkg/katalog builtin registry to detect resource usage.

Types

type APITypes

type APITypes struct {
	// Object — Go type name for a single CR instance. Required for typed mode.
	// Used by ork generate to emit ObjectRegistry entries.
	// e.g. "Project" → func() runtime.Object { return &projv1.Project{} }
	Object string `yaml:"object,omitempty" json:"object,omitempty" validate:"omitempty"`

	// List — Go type name for the CR list. Required for typed mode.
	// Used by ork generate to emit ListRegistry entries.
	// e.g. "ProjectList" → func() runtime.Object { return &projv1.ProjectList{} }
	List string `yaml:"objectList,omitempty" json:"objectList,omitempty" validate:"omitempty"`

	// Alias — Go import alias for the API types package. Optional.
	// Auto-derived from the last two segments of Location if not set.
	// e.g. "projv1" → import projv1 "github.com/.../project/v1alpha1"
	Alias string `yaml:"alias,omitempty" json:"alias,omitempty" validate:"omitempty"`

	// Group — Kubernetes API group. Required in all modes.
	// e.g. "platform.orkestra.io"
	Group string `yaml:"group" json:"group" validate:"required,hostname_rfc1123"`

	// Version — API version. Required in all modes.
	// e.g. "v1alpha1"
	Version string `yaml:"version" json:"version" validate:"required"`

	// Kind — resource Kind. Required in all modes.
	// e.g. "Platform"
	Kind string `yaml:"kind" json:"kind" validate:"required"`

	// Plural — lowercase plural resource name. Required in all modes.
	// Used for REST client URL construction.
	// e.g. "projects"
	Plural string `yaml:"plural" json:"plural" validate:"required"`

	// APIPath — REST API path prefix. Default: /apis.
	// Override to /api only for core Kubernetes types (Pod, ConfigMap, etc.)
	// Almost always leave this empty — Orkestra defaults it to /apis.
	APIPath string `yaml:"apiPath,omitempty" json:"apiPath,omitempty" validate:"omitempty"`

	// Location — fully qualified Go import path for the API types package.
	// Required for typed mode. Used by ork generate for import statements
	// and scheme registration in RegisterScheme().
	// Not needed for dynamic mode — omit entirely.
	// e.g. "github.com/orkspace/orkestra/api/types/project/v1alpha1"
	Location string `yaml:"location,omitempty" json:"location,omitempty" validate:"omitempty"`
}

type Admission added in v0.3.9

type Admission struct {
	Validation *ValidationConfig
	Mutation   *MutationConfig
}

Admission holds validation and mutation configuration for a CRD.

func (*Admission) HasMutationRules added in v0.4.0

func (a *Admission) HasMutationRules() bool

Separate helpers for hasMutationRules and hasValidationRules

func (*Admission) HasValidationOrMutationRules added in v0.4.0

func (a *Admission) HasValidationOrMutationRules() bool

Returns true when either validation or mutation rules are declared.

func (*Admission) HasValidationRules added in v0.4.0

func (a *Admission) HasValidationRules() bool

type AdmissionWebhookConfig

type AdmissionWebhookConfig struct {
	// Validation — include this CRD in the ValidatingWebhookConfiguration.
	// Default: true when validation rules are declared.
	Validation *bool `yaml:"validation,omitempty" json:"validation,omitempty"`

	// Mutation — include this CRD in the MutatingWebhookConfiguration.
	// Default: true when mutation rules are declared.
	Mutation *bool `yaml:"mutation,omitempty" json:"mutation,omitempty"`

	// Operations — which operations trigger the webhook.
	// Default: ["CREATE", "UPDATE"]
	// Valid values: CREATE, UPDATE, DELETE, CONNECT
	Operations []string `yaml:"operations,omitempty" json:"operations,omitempty"`
}

AdmissionWebhookConfig is the per-CRD admission webhook control block. Declared under spec.crds[].webhooks in the Katalog.

Example:

  • name: website webhooks: validation: true # intercept at admission — ValidatingWebhookConfiguration mutation: true # intercept at admission — MutatingWebhookConfiguration

Both default to true when ENABLE_ADMISSION_WEBHOOK=true and the corresponding validation/mutation block has rules declared. Set to false to opt a specific CRD out of admission interception while keeping its reconcile-time enforcement.

func (*AdmissionWebhookConfig) EffectiveOperations

func (w *AdmissionWebhookConfig) EffectiveOperations() []string

EffectiveOperations returns the operations this webhook intercepts. Defaults to CREATE and UPDATE when not specified.

func (*AdmissionWebhookConfig) WebhookMutationEnabled

func (w *AdmissionWebhookConfig) WebhookMutationEnabled() bool

WebhookMutationEnabled reports whether admission-time mutation is enabled.

func (*AdmissionWebhookConfig) WebhookValidationEnabled

func (w *AdmissionWebhookConfig) WebhookValidationEnabled() bool

WebhookValidationEnabled reports whether admission-time validation is enabled for this CRD. True when Validation is nil or true.

type AdmissionWebhookToggle

type AdmissionWebhookToggle struct {
	// Enabled controls whether ValidatingWebhookConfiguration and
	// MutatingWebhookConfiguration are registered at startup.
	// Default: ENABLE_ADMISSION_WEBHOOK env / false.
	Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`
}

AdmissionWebhookToggle controls whether admission webhooks are globally enabled.

type AllowedNamespaces

type AllowedNamespaces []string

AllowedNamespaces holds the set of allowed namespace patterns.

func (AllowedNamespaces) IsAllowed

func (a AllowedNamespaces) IsAllowed(namespace string) bool

IsAllowed reports whether a given namespace matches any allowed pattern. If the list is empty, all namespaces are allowed. Supports exact matches and simple glob patterns (* prefix or suffix).

func (AllowedNamespaces) Merge

Merge combines two AllowedNamespaces sets, deduplicating entries. Since allowances are additive, a namespace allowed at any level is allowed at all levels — more specific levels cannot remove allowances.

type AutoscaleAction

type AutoscaleAction struct {
	// Workers — number of concurrent reconcile goroutines.
	Workers *int `yaml:"workers,omitempty" json:"workers,omitempty"`

	// QueueDepth — maximum queue depth before backpressure.
	QueueDepth *int `yaml:"queueDepth,omitempty" json:"queueDepth,omitempty"`

	// Resync — resync interval override. How frequently all CRs are
	// re-enqueued regardless of changes.
	Resync *Duration `yaml:"resync,omitempty" json:"resync,omitempty"`
}

AutoscaleAction declares the override values to apply when conditions are met. All fields are optional pointers — only set fields are overridden. Unset fields retain their current value (baseline or previous override).

type AutoscaleBaseline

type AutoscaleBaseline struct {
	Workers  int
	MaxDepth int
	Resync   time.Duration
}

AutoscaleBaseline captures the CRD's declared configuration before any autoscale override is applied. Always restored when conditions are false.

type AutoscaleConditions

type AutoscaleConditions struct {
	// AnyOf — OR semantics. At least one condition in this list must be true.
	// Supports all Condition kinds: time, dayOfWeek, cron, and metric fields.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// When — AND semantics. All conditions in this list must be true.
	// Supports: metric conditions (metrics.*, cross.<crd>.metrics.*).
	When []Condition `yaml:"when,omitempty" json:"when,omitempty"`
}

AutoscaleConditions holds the condition blocks for autoscale evaluation.

type AutoscaleSpec

type AutoscaleSpec struct {
	// Interval is how often the autoscaler evaluates conditions.
	// Shorter intervals respond faster to load changes at the cost of
	// more frequent evaluation overhead (negligible in practice).
	// Default: 15s
	Interval Duration `yaml:"interval,omitempty" json:"interval,omitempty"`

	// Cooldown is the minimum time conditions must be continuously false
	// before the baseline is restored. Prevents oscillation when metrics
	// fluctuate around a threshold.
	// Default: 2m
	Cooldown Duration `yaml:"cooldown,omitempty" json:"cooldown,omitempty"`

	// Conditions declares the trigger conditions. Both blocks must pass
	// when both are declared (AND between blocks, OR within anyOf).
	Conditions AutoscaleConditions `yaml:"conditions" json:"conditions"`

	// Do declares the override values applied when conditions are met.
	// Fields omitted in Do are not changed — only declared fields are overridden.
	Do AutoscaleAction `yaml:"do" json:"do"`

	// A profile is:
	// 	a named preset that expands into a complete autoscale configuration
	// using computed heuristics tuned for a specific behavior pattern
	Profile string `yaml:"profile,omitempty" json:"profile,omitempty"`
}

AutoscaleSpec declares the autoscale behavior for one operatorbox. Declared inside OperatorBoxConfig.

func (*AutoscaleSpec) EffectiveCooldown

func (a *AutoscaleSpec) EffectiveCooldown() time.Duration

EffectiveCooldown returns the cooldown duration, applying the default of 2m when not declared.

func (*AutoscaleSpec) EffectiveInterval

func (a *AutoscaleSpec) EffectiveInterval() time.Duration

EffectiveInterval returns the autoscale evaluation interval, applying the default of 15s when not declared.

func (*AutoscaleSpec) HasAnyOfConditions added in v0.1.9

func (a *AutoscaleSpec) HasAnyOfConditions() bool

HasAnyOfConditions returns whether anyOf conditions are declared.

func (*AutoscaleSpec) HasCooldownDuration added in v0.1.9

func (a *AutoscaleSpec) HasCooldownDuration() bool

HasCooldownDuration returns whether cooldown is set.

func (*AutoscaleSpec) HasDoQueueDepth added in v0.1.9

func (a *AutoscaleSpec) HasDoQueueDepth() bool

HasDoQueueDepth returns whether do.queueDepth is set.

func (*AutoscaleSpec) HasDoResync added in v0.1.9

func (a *AutoscaleSpec) HasDoResync() bool

HasDoResync returns whether do.resync is set.

func (*AutoscaleSpec) HasDoWorkers added in v0.1.9

func (a *AutoscaleSpec) HasDoWorkers() bool

HasDoWorkers returns whether do.workers is set.

func (*AutoscaleSpec) HasIntervalDuration added in v0.1.9

func (a *AutoscaleSpec) HasIntervalDuration() bool

HasIntervalDuration returns whether interval is set.

func (*AutoscaleSpec) HasWhenConditions added in v0.1.9

func (a *AutoscaleSpec) HasWhenConditions() bool

HasWhenConditions returns whether when conditions are declared.

type AutoscaleState

type AutoscaleState struct {
	// OverrideActive is true when an override is currently applied.
	OverrideActive bool

	// ConditionsFalseAt is the time when conditions last became continuously false.
	// Used to enforce the cooldown period before restoring the baseline.
	// Zero when conditions are currently true or have never been false.
	ConditionsFalseAt time.Time

	// CronWindowsOpenAt tracks when each cron-condition window opened.
	// Key is the cron expression string.
	// Without this, a cron fire that happens between two evaluation ticks would
	// be missed — the window must stay open across ticks until duration elapses.
	CronWindowsOpenAt map[string]time.Time
}

AutoscaleState tracks the runtime state of the autoscaler for one operatorbox. Not serialized — ephemeral, reset on restart.

type CRDConversion

type CRDConversion struct {
	// Participant marks this CRD as a conversion participant without declaring
	// conversion paths. Use this on the stable/storage-version CRD when the
	// conversion paths are declared on the other version. Both CRDs need to
	// be marked (one with paths, one with participant: true) for conversion
	// stats to appear for each in the Control Center.
	Participant bool `yaml:"participant,omitempty" json:"participant,omitempty"`

	// StorageVersion — the version all objects are stored as internally.
	// All conversion paths route through this version.
	StorageVersion string `yaml:"storageVersion,omitempty" json:"storageVersion,omitempty"`

	// Paths — one entry per (from, to) pair.
	// You need at least two paths for a two-version CRD:
	//   - old → storage  (up-conversion)
	//   - storage → old  (down-conversion)
	Paths []ConversionPath `yaml:"paths,omitempty" json:"paths,omitempty"`

	// UpdateCRD — when true, Orkestra patches the CRD's
	// spec.conversion.webhook.clientConfig.caBundle with the CA bundle
	// from the generated (or configured) TLS certificate at startup.
	// Set this to true when you let Orkestra manage TLS; set it to false
	// when you manage caBundle injection yourself (e.g. cert-manager).
	// Default: false.
	UpdateCRD bool `yaml:"updateCRD,omitempty" json:"updateCRD,omitempty"`
}

CRDConversion declares declarative version conversion rules for a CRD. When enabled, Orkestra serves the /convert endpoint and translates ConversionReview requests using these rules and the template resolver.

Example Katalog declaration:

conversion:
  storageVersion: v1
  paths:
    - from: v1alpha1
      to: v1
      spec:
        image: "{{ .spec.image }}"
        replicas: "{{ .spec.replicas }}"
        seo:
          enabled: false   # default — v1alpha1 has no SEO field
    - from: v1
      to: v1alpha1
      spec:
        image: "{{ .spec.image }}"
        replicas: "{{ .spec.replicas }}"
        theme: "default"   # default — v1 has no theme field

type CRDEntry

type CRDEntry struct {

	// Name — unique CRD identifier within the Katalog. Must be lowercase.
	// Injected from the map key during loading — never set from YAML.
	Name string `yaml:"-" json:"name" validate:"required,hostname_rfc1123"`

	// KatalogName — unique identifier for the katalog in the runtime.
	KatalogName string `yaml:"-" json:"katalogName,omitempty"`

	// KatalogNamespace — the namespace this CRD's Katalog belongs to.
	// Defaults to "default" when not declared. Used by the Control Center to
	// group CRDs by team/tenant within a single runtime.
	KatalogNamespace string `yaml:"-" json:"katalogNamespace,omitempty"`

	// KatalogDescription — the description from the source Katalog's metadata.
	// Falls back to the Komposer's description when the sub-Katalog has none.
	KatalogDescription string `yaml:"-" json:"katalogDescription,omitempty"`

	// KatalogVersion — the version from the source Katalog's metadata.
	// Falls back to the Komposer's version when the sub-Katalog has none.
	KatalogVersion string `yaml:"-" json:"katalogVersion,omitempty"`

	// CrossAccess controls whether other Katalogs can read this CRD's CR state
	// via the cross: block. Defaults to true (readable). Set to false to opt
	// this CRD out of cross reads — the reconciler returns empty for any
	// cross: reference that targets an opted-out CRD.
	CrossAccess *bool `yaml:"crossAccess,omitempty" json:"crossAccess,omitempty"`

	// Enabled — include this CRD in the runtime. false = skipped entirely.
	// WARNING: only set to false after stripping Orkestra finalizers from all
	// live CRs — disabled CRDs with live finalizers will cause stuck objects.
	Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`

	// Description — human-readable description. Shown in /katalog API responses.
	Description string `yaml:"description,omitempty" json:"description,omitempty" validate:"omitempty"`

	// Mode — see CRDMode for full documentation.
	// Auto-detected when omitted based on whether apiTypes.location is set.
	Mode CRDMode `yaml:"mode,omitempty" json:"mode,omitempty" validate:"omitempty,oneof=typed dynamic"`

	// ── API Types ─────────────────────────────────────────────────────────────
	// See APITypes for full field documentation.
	APITypes APITypes `yaml:"apiTypes" json:"apiTypes" validate:"required"`

	// CRDFile is the path to the CRD YAML file to apply before operator start.
	// Supports relative (resolved from katalog file location), absolute, or
	// remote (https://…) paths.
	//
	// Only applied when running outside the cluster (dev mode via ork run).
	// In production, CRDs must be pre-applied by the platform operator.
	//
	// During ork validate, the file is read and its group/kind are checked
	// against apiTypes to catch mismatches before deployment.
	CRDFile string `yaml:"crdFile,omitempty" json:"crdFile,omitempty"`

	// CRFiles is an ordered list of CR YAML files to apply before the runtime
	// starts. Applied in declaration order after the CRD is registered.
	// Same path resolution as CRDFile. Dev mode only.
	CRFiles []string `yaml:"crFiles,omitempty" json:"crFiles,omitempty"`

	// Setup declares prerequisite resources to apply before Orkestra starts.
	// Shorthand: a plain list of strings applies each file (backward compatible).
	Setup *SetupConfig `yaml:"setup,omitempty" json:"setup,omitempty"`

	// ── Runtime objects ───────────────────────────────────────────────────────
	// Set by addRuntimeObjects() during Katalog validation. Never set from YAML.
	//
	// Typed mode:        DynamicModeObject and ListDynamicModeObject are factory functions
	//                    from ObjectRegistry and ListRegistry respectively.
	//                    TypedModeObject and ListTypedModeObject are set in BuildKatalogFromGo().
	//
	// Dynamic mode: DynamicModeObject and ListDynamicModeObject are factory functions
	//                    that return *unstructured.Unstructured and *unstructured.UnstructuredList.
	//                    These are always set by addRuntimeObjects() — never nil after validation.
	TypedModeObject       runtime.Object        `yaml:"-" json:"-"`
	ListTypedModeObject   runtime.Object        `yaml:"-" json:"-"`
	DynamicModeObject     func() runtime.Object `yaml:"-" json:"-"`
	ListDynamicModeObject func() runtime.Object `yaml:"-" json:"-"`

	// Scheme — AddToScheme function generated by controller-gen for this API type.
	// Required for typed mode so the REST client can decode API server responses.
	// Not needed for dynamic mode — the dynamic client bypasses scheme decoding.
	// Set in BuildKatalogFromGo() for Go mode. Handled by RegisterScheme() for YAML mode.
	Scheme func(s *runtime.Scheme) error `yaml:"-" json:"-"`

	// ── Computed GVK/GVR ─────────────────────────────────────────────────────
	// Set by setGroupVersionKind() during Katalog validation.
	// Derived from APITypes fields. Never set manually.
	GroupVersion         *schema.GroupVersion        `yaml:"-" json:"-"`
	GroupVersionKind     schema.GroupVersionKind     `yaml:"-" json:"-"`
	GroupVersionResource schema.GroupVersionResource `yaml:"-" json:"-"`

	// Namespaced — true if this CRD is namespace-scoped, false if cluster-scoped.
	// Default is true
	Namespaced *bool `yaml:"namespaced,omitempty" json:"namespaced,omitempty"`

	// Namespace — target namespace for namespace-scoped CRDs.
	// Informer watches this namespace only. Empty = all namespaces.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty" validate:"omitempty"`

	// Workers — number of concurrent reconcile workers for this CRD.
	// Higher values increase throughput but also increase API server load.
	// 0 → uses Orkestra-level default (DEFAULT_WORKERS env var).
	Workers int `yaml:"workers,omitempty" json:"workers,omitempty" validate:"omitempty,gte=1,lte=50"`

	// WorkersActive — records number of active concurrent reconcile workers for this CRD.
	WorkersActive int `yaml:"workersActive,omitempty" json:"workersActive,omitempty" validate:"omitempty,gte=1,lte=50"`

	// Resync — full re-list interval for the informer cache.
	// Triggers a reconcile for every cached object at this interval.
	// 0 → uses Orkestra-level default (DEFAULT_RESYNC env var).
	Resync time.Duration `yaml:"resync,omitempty" json:"resync,omitempty" validate:"omitempty"`

	// DependsOn — names of other CRDs that must reach a condition before this one starts.
	// Orkestra resolves the dependency graph and starts CRDs in topological order.
	// Cycle detection runs at validation time — cycles fail fast with a clear error.
	// Supports three YAML formats (list, key-value, full map) — see DependsOnMap.
	DependsOn DependsOnMap `yaml:"dependsOn,omitempty" json:"dependsOn,omitempty"`

	// ── Enrichment ─────────────────────────────────────────────────────────────
	// Controls which secondary data is fetched and embedded into child resource
	// maps before they are available in template context.
	//
	// Only one of EnrichAll or Enrich may be set — setting both is a validation error.
	//
	//	enrichAll: true    — enrich all supported resource types
	//	enrich: [pods]     — enrich only the listed targets (shorthand)
	//	enrich:            — conditional enrichment (struct form)
	//	  - events:
	//	      when:
	//	        - field: "{{ replicasReady .children.deployment }}"
	//	          equals: "false"
	EnrichAll bool           `yaml:"enrichAll,omitempty" json:"enrichAll,omitempty"`
	Enrich    []EnrichTarget `yaml:"enrich,omitempty"    json:"enrich,omitempty"`

	// ── OperatorBox ────────────────────────────────────────────────────
	OperatorBox OperatorBoxConfig `yaml:"operatorBox,omitempty" json:"operatorBox,omitempty"`

	// ── Queue ────────────────────────────────────────────────────
	Queue Queue `yaml:"queue,omitempty" json:"queue,omitempty"`

	// Labels           []ResourceLabel  `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`
	// LabelSelector filters which resources this CRD entry reconciles.
	// Only resources whose labels match ALL declared key-value pairs are watched.
	// Required for built-in types (ConfigMap, Pod, etc.) — without a selector,
	// Orkestra would reconcile every instance in the cluster.
	// For custom CRDs this is optional — can narrow scope within a CRD.
	LabelSelector SelectorMap `yaml:"labelSelector,omitempty"`

	// FieldSelector filters which resources this CRD entry reconciles.
	// Only resources whose *fields* match ALL declared key-value expressions
	// are listed or watched. Field selectors operate on the server side and
	// support exact-match comparisons on well-known metadata paths
	// (e.g. "metadata.name", "metadata.namespace").
	//
	// Unlike label selectors, field selectors cannot match arbitrary user-defined
	// keys — only fields exposed by the Kubernetes API server. They are evaluated
	// before any client-side filtering, reducing load on the informer pipeline.
	//
	// Common use cases:
	//   - Restricting reconciliation to a specific namespace:
	//       {key: "metadata.namespace", value: "default"}
	//   - Targeting a single object by name:
	//       {key: "metadata.name", value: "my-config"}
	//
	// Field selectors are optional for all types. When omitted, Orkestra will
	// watch all objects permitted by LabelSelector and namespace restrictions.
	FieldSelector SelectorMap `yaml:"fieldSelector,omitempty"`

	// IsBuiltIn is set to true when this CRD entry was enriched from the
	// built-in Kubernetes resource registry. Used for ork validate output
	// and informational logging only — does not affect runtime behavior.
	IsBuiltIn bool `yaml:"-" json:"-"` // never serialized — runtime state only

	// IgnoreStatusPatch reports whether or not to patch the status of this CRD
	IgnoreStatusPatch bool `yaml:"ignoreStatusPatch,omitempty" json:"ignoreStatusPatch,omitempty"`

	// IgnoreObservedGeneration reports whether or not to ignore the observedGeneration field for this CRD.
	IgnoreObservedGeneration bool `yaml:"ignoreObservedGeneration,omitempty" json:"ignoreObservedGeneration,omitempty"`

	// IsStatusless reports whether this CRD has no meaningful readiness semantics.
	// These resources become "Ready" immediately upon creation.
	IsStatusless bool `yaml:"-" json:"IsStatusless,omitempty"`

	// BuiltInGroup is the display name of the API group for built-in resources.
	// "core" for resources in the core group (empty string group).
	// Only set when IsBuiltIn is true.
	BuiltInGroup string `yaml:"-" json:"-"` // never serialized

	// EnrichmentOutcome records the result of the API type enrichment phase.
	// During validation, built‑in Kubernetes kinds (e.g., Pod, Deployment, Secret)
	// are automatically enriched with their full API metadata — group, version,
	// plural, API path, and namespaced scope. This allows users to specify only:
	//
	//	apiTypes:
	//	  kind: Pod
	//
	// and rely on Orkestra to resolve all remaining fields based on the
	// Kubernetes discovery API. Custom resources are enriched using their declared
	// group/version/kind. This field is never serialized and is used internally to
	// report enrichment status and drive downstream runtime behavior.
	EnrichmentOutcome EnrichmentOutcome `yaml:"-" json:"-"` // never serialized

	// Endpoints defines which operator HTTP endpoints are enabled for this CRD.
	Endpoints EndpointsConfig `yaml:"endpoints,omitempty" json:"endpoints,omitempty"`

	// Restricted Namespaces
	RestrictedNamespaces RestrictedNamespaces `yaml:"restrictedNamespaces,omitempty" json:"restrictedNamespaces,omitempty"`

	// Allowed Namespaces
	AllowedNamespaces AllowedNamespaces `yaml:"allowedNamespaces,omitempty" json:"allowedNamespaces,omitempty"`

	// Conversion is useful for handling multi-version crd
	Conversion *CRDConversion `yaml:"conversion,omitempty" json:"conversion,omitempty"`

	// Validation is a list of rules
	Validation *ValidationConfig `yaml:"validation,omitempty" json:"validation,omitempty"`

	// Mutation is a list of rules
	Mutation *MutationConfig `yaml:"mutation,omitempty" json:"mutation,omitempty"`

	// Webhooks controls per-CRD admission webhook behaviour.
	// Only meaningful when ENABLE_ADMISSION_WEBHOOK=true.
	// By default, any CRD with Validation or Mutation rules is included
	// in the corresponding webhook configuration automatically.
	// Set validation: false or mutation: false to opt a specific CRD out of
	// admission-time interception while keeping its reconcile-time enforcement.
	Webhooks AdmissionWebhookConfig `yaml:"webhooks,omitempty" json:"webhooks,omitempty"`

	// Normalize Spec fields before rendering
	Normalize *NormalizeConfig `yaml:"normalize,omitempty"`

	// NotificationEnabled returns whether this CRD belongs to katalog with notification access
	NotificationEnabled *bool `yaml:"-" json:"-"`

	// RemoveFinalizers -> testing
	RemoveFinalizers bool `yaml:"removeFinalizers,omitempty" json:"removeFinalizers,omitempty"`

	// DeletionProtection overrides the global deletion protection policy
	// for this specific CRD. If nil, both ProtectCRD and ProtectCRs default to true.
	DeletionProtection *DeletionProtectionOverride `yaml:"deletionProtection,omitempty" json:"deletionProtection,omitempty"`

	// Warnings collects non‑fatal validation messages for this CRD.
	Warnings Warnings `json:"-"` // not serialized

	// Imports declares Motif imports for this operatorBox.
	// Each import references a Motif by OCI reference, file path, or short name,
	// and binds its inputs via with:. Resources from imported Motifs are merged
	// into OnReconcile at Katalog load time.
	// Required inputs not provided in with: are a validation error.
	Imports []MotifImport `yaml:"imports,omitempty" json:"imports,omitempty"`
}

func (*CRDEntry) ActiveEnrichTargets added in v0.6.0

func (c *CRDEntry) ActiveEnrichTargets(data map[string]interface{}, eval TemplateEvaluator) []EnrichTarget

ActiveEnrichTargets returns the subset of Enrich entries whose when:/anyOf: conditions pass for the given data map and evaluator. Unconditional entries (no when: or anyOf:) always pass. Called from ReadChildren to pre-filter crd.Enrich before dispatching to individual enricher functions.

func (*CRDEntry) AllAllowedNamespaces added in v0.1.9

func (c *CRDEntry) AllAllowedNamespaces() AllowedNamespaces

AllAllowedNamespaces returns a list of allowed namespaces for this crd

func (*CRDEntry) AllRestrictedNamespaces added in v0.1.9

func (c *CRDEntry) AllRestrictedNamespaces() RestrictedNamespaces

AllRestrictedNamespaces returns a list of restricted namespaces for this crd

func (*CRDEntry) AllowedNamespacesOnly added in v0.1.9

func (c *CRDEntry) AllowedNamespacesOnly() bool

AllowedNamespacesOnly reports if only allowedNamespaces is defined for this crd.

func (*CRDEntry) AutoScaleProfile

func (c *CRDEntry) AutoScaleProfile() string

AutoScaleProfile returns the string value of the autoscale profile

func (*CRDEntry) AutoscaleEnabled

func (c *CRDEntry) AutoscaleEnabled() bool

AutoscaleEnabled reports whether this CRD declares the autoscale block

func (*CRDEntry) CollectCapabilityEntries added in v0.5.4

func (c *CRDEntry) CollectCapabilityEntries() []CapabilityEntry

CollectCapabilityEntries returns all capabilities declared across every hook phase. Both add and drop lists are included. Template expressions are included as-is and must be skipped by the caller.

func (*CRDEntry) CollectHPAProfileEntries added in v0.5.4

func (c *CRDEntry) CollectHPAProfileEntries() []HPAProfileEntry

CollectHPAProfileEntries returns all behavior.profile references declared for this CRD across OnCreate, OnReconcile, and OnDelete. Only entries with a non-empty Profile string are returned.

func (*CRDEntry) CollectPDBProfileEntries added in v0.5.4

func (c *CRDEntry) CollectPDBProfileEntries() []PDBProfileEntry

CollectPDBProfileEntries returns all behavior.profile references declared for this CRD across OnCreate, OnReconcile, and OnDelete. Only entries with a non-empty Profile string are returned.

func (*CRDEntry) CollectPortProtocolEntries added in v0.6.2

func (c *CRDEntry) CollectPortProtocolEntries() []PortProtocolEntry

CollectPortProtocolEntries returns all non-empty protocol declarations across OnCreate, OnReconcile, and OnDelete for this CRD.

func (*CRDEntry) CollectProbeProfileEntries added in v0.4.2

func (c *CRDEntry) CollectProbeProfileEntries() []ProbeProfileEntry

CollectProbeProfileEntries returns all probe profile references declared for this CRD across OnCreate, OnReconcile, and OnDelete. Only entries with a non-empty Profile string are returned — omitted profiles (which fall back to "standard") are not surfaced for validation.

func (*CRDEntry) CollectResourceProfileEntries added in v0.4.2

func (c *CRDEntry) CollectResourceProfileEntries() []ResourceProfileEntry

CollectResourceProfileEntries returns all resources.profile references declared for this CRD across OnCreate, OnReconcile, and OnDelete. Only entries with a non-empty Profile string are returned.

func (*CRDEntry) CollectRollingUpdateProfileEntries added in v0.5.4

func (c *CRDEntry) CollectRollingUpdateProfileEntries() []RollingUpdateProfileEntry

CollectRollingUpdateProfileEntries returns all rollingUpdate.profile references declared for this CRD across OnCreate, OnReconcile, and OnDelete. Only entries with a non-empty Profile string are returned.

func (*CRDEntry) CollectSecurityProfileEntries added in v0.5.4

func (c *CRDEntry) CollectSecurityProfileEntries() []SecurityProfileEntry

CollectSecurityProfileEntries returns all security profile references declared for this CRD across OnCreate, OnReconcile, and OnDelete. Only entries with a non-empty Profile string are returned.

func (*CRDEntry) CollectSleepEntries added in v0.4.2

func (c *CRDEntry) CollectSleepEntries() []SleepEntry

CollectSleepEntries returns all SleepEntry items declared for this CRD across OnCreate, OnReconcile and OnDelete. This is the canonical discovery method callers should use for validation, diagnostics, or runtime wiring.

func (*CRDEntry) ConditionalActiveEnrichTargets added in v0.6.2

func (c *CRDEntry) ConditionalActiveEnrichTargets(data map[string]interface{}, eval TemplateEvaluator) []EnrichTarget

ConditionalActiveEnrichTargets returns entries that HAVE conditions and whose conditions pass for the given data. Called in phase 2 of ReadChildren after children data is available — gates like {{ replicasReady .children.deployment }} can only be evaluated once the deployment has been read.

func (CRDEntry) Config

func (e CRDEntry) Config() OperatorBoxConfig

Config returns the OperatorBox configuration for this CRD. Safe to call when OperatorBox is the zero value.

func (*CRDEntry) ConstructorEnabled added in v0.2.0

func (c *CRDEntry) ConstructorEnabled() bool

ConstructorEnabled reports whether the reconcile behaviour uses a constructor. Defaults to false when omitted.

func (*CRDEntry) ConstructorManagedResources added in v0.4.1

func (c *CRDEntry) ConstructorManagedResources() []ManagedResource

ConstructorManagedResources returns the list of managed resources declared under the constructor block. Returns nil if constructor is not declared or no resources exist.

func (*CRDEntry) CustomHooksEnabled added in v0.2.0

func (c *CRDEntry) CustomHooksEnabled() bool

CustomHooksEnabled reports whether the reconcile behaviour uses custom hooks. Defaults to false when omitted.

func (*CRDEntry) DefaultReconcile

func (c *CRDEntry) DefaultReconcile() bool

DefaultReconcile reports whether this CRD uses the default reconciler behavior. Defaults to true unless explicitly enabled.

func (*CRDEntry) GVK

func (c *CRDEntry) GVK() schema.GroupVersionKind

GVK returns the fully resolved GroupVersionKind for this CRD. Used for logging, routing, and dynamic client operations.

func (*CRDEntry) GVKString

func (c *CRDEntry) GVKString() string

GVKString returns the fully resolved GroupVersionKind for this CRD as a string.

func (*CRDEntry) GVR

GVR returns the fully resolved GroupVersionResource for this CRD. Used for dynamic client list/watch operations.

func (*CRDEntry) GVRString

func (c *CRDEntry) GVRString() string

GVRString returns the fully resolved GroupVersionResource for this CRD as a string.

func (*CRDEntry) GetDependencies

func (c *CRDEntry) GetDependencies() []string

GetDependencies returns the dependency names for this CRD in sorted order.

func (*CRDEntry) GetRuntimeObjects

func (c *CRDEntry) GetRuntimeObjects() (runtime.Object, runtime.Object)

GetRuntimeObjects returns the object and list constructors appropriate for the current mode (dynamic or typed). Used by the reconciler to instantiate new runtime objects for watches, lists, and reconciliation.

func (*CRDEntry) HasAllowedNamespaces added in v0.1.9

func (c *CRDEntry) HasAllowedNamespaces() bool

HasAllowedNamespaces reports if allowedNamespaces is defined for this crd.

func (*CRDEntry) HasAnyClusterRoleBindings added in v0.4.2

func (c *CRDEntry) HasAnyClusterRoleBindings() bool

HasAnyClusterRoleBindings reports whether this CRD defines any ClusterRoleBindings in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyClusterRoles added in v0.4.2

func (c *CRDEntry) HasAnyClusterRoles() bool

HasAnyClusterRoles reports whether this CRD defines any ClusterRoles in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyConfigMaps added in v0.4.2

func (c *CRDEntry) HasAnyConfigMaps() bool

HasAnyConfigMaps reports whether this CRD defines any ConfigMaps in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyCustomResources added in v0.4.6

func (c *CRDEntry) HasAnyCustomResources() bool

HasAnyCustomResources reports whether this CRD entry declares any Custom resources in either the OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyDaemonSets added in v0.4.2

func (c *CRDEntry) HasAnyDaemonSets() bool

HasAnyDaemonSets reports whether this CRD defines any DaemonSets in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyDeployments added in v0.3.8

func (c *CRDEntry) HasAnyDeployments() bool

HasAnyDeployments reports whether this CRD defines any Deployments in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyHPA added in v0.2.3

func (c *CRDEntry) HasAnyHPA() bool

HasAnyHPA reports whether this CRD defines any HPA defined in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyHookTemplates added in v0.4.6

func (c *CRDEntry) HasAnyHookTemplates() bool

HasAnyHooks reports whether this CRD declares any onCreate, onReconcile, or onDelete hooks.

func (*CRDEntry) HasAnyIngresses added in v0.4.2

func (c *CRDEntry) HasAnyIngresses() bool

HasAnyIngresses reports whether this CRD defines any Ingresses in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyLimitRanges added in v0.4.2

func (c *CRDEntry) HasAnyLimitRanges() bool

HasAnyLimitRanges reports whether this CRD defines any LimitRanges in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyNamespaces added in v0.4.2

func (c *CRDEntry) HasAnyNamespaces() bool

HasAnyNamespaces reports whether this CRD defines any Namespaces in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyNetworkPolicies added in v0.4.2

func (c *CRDEntry) HasAnyNetworkPolicies() bool

HasAnyNetworkPolicies reports whether this CRD defines any NetworkPolicies in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyPersistentVolumeClaims added in v0.4.2

func (c *CRDEntry) HasAnyPersistentVolumeClaims() bool

HasAnyPersistentVolumeClaims reports whether this CRD defines any PVCs in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyPersistentVolumes added in v0.4.2

func (c *CRDEntry) HasAnyPersistentVolumes() bool

HasAnyPersistentVolumes reports whether this CRD defines any PersistentVolumes in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyPodDisruptionBudgets added in v0.4.2

func (c *CRDEntry) HasAnyPodDisruptionBudgets() bool

HasAnyPodDisruptionBudgets reports whether this CRD defines any PDBs in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyPodSecurityPolicies added in v0.4.2

func (c *CRDEntry) HasAnyPodSecurityPolicies() bool

HasAnyPodSecurityPolicies reports whether this CRD defines any PSPs in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyPodTemplates added in v0.4.2

func (c *CRDEntry) HasAnyPodTemplates() bool

HasAnyPodTemplates reports whether this CRD defines any PodTemplates in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyPods added in v0.4.2

func (c *CRDEntry) HasAnyPods() bool

HasAnyPods reports whether this CRD defines any Pods in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyPriorityClasses added in v0.4.2

func (c *CRDEntry) HasAnyPriorityClasses() bool

HasAnyPriorityClasses reports whether this CRD defines any PriorityClasses in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyPriorityLevelConfigurations added in v0.4.2

func (c *CRDEntry) HasAnyPriorityLevelConfigurations() bool

HasAnyPriorityLevelConfigurations reports whether this CRD defines any PL configs in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyReplicaSets added in v0.3.8

func (c *CRDEntry) HasAnyReplicaSets() bool

HasAnyReplicaSets reports whether this CRD defines any ReplicaSets in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyResourceQuotas added in v0.4.2

func (c *CRDEntry) HasAnyResourceQuotas() bool

HasAnyResourceQuotas reports whether this CRD defines any ResourceQuotas in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyRoleBindings added in v0.4.2

func (c *CRDEntry) HasAnyRoleBindings() bool

HasAnyRoleBindings reports whether this CRD defines any RoleBindings in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyRoles added in v0.4.2

func (c *CRDEntry) HasAnyRoles() bool

HasAnyRoles reports whether this CRD defines any Roles in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyRuntimeClasses added in v0.4.2

func (c *CRDEntry) HasAnyRuntimeClasses() bool

HasAnyRuntimeClasses reports whether this CRD defines any RuntimeClasses in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnySecrets added in v0.2.3

func (c *CRDEntry) HasAnySecrets() bool

HasAnySecrets reports whether this CRD defines any secrets in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyServiceAccounts added in v0.4.2

func (c *CRDEntry) HasAnyServiceAccounts() bool

HasAnyServiceAccounts reports whether this CRD defines any ServiceAccounts in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyServiceMonitors added in v0.4.2

func (c *CRDEntry) HasAnyServiceMonitors() bool

HasAnyServiceMonitors reports whether this CRD defines any ServiceMonitors in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyServices added in v0.3.9

func (c *CRDEntry) HasAnyServices() bool

HasAnyServices reports whether this CRD defines any Services in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyStatefulSets added in v0.3.8

func (c *CRDEntry) HasAnyStatefulSets() bool

HasAnyStatefulSets reports whether this CRD defines any StatefulSets in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyStorageBackups added in v0.4.2

func (c *CRDEntry) HasAnyStorageBackups() bool

HasAnyStorageBackups reports whether this CRD defines any StorageBackups in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyStorageClasses added in v0.4.2

func (c *CRDEntry) HasAnyStorageClasses() bool

HasAnyStorageClasses reports whether this CRD defines any StorageClasses in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyStorageLocations added in v0.4.2

func (c *CRDEntry) HasAnyStorageLocations() bool

HasAnyStorageLocations reports whether this CRD defines any StorageLocations in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyStoragePools added in v0.4.2

func (c *CRDEntry) HasAnyStoragePools() bool

HasAnyStoragePools reports whether this CRD defines any StoragePools in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyStorageSnapshots added in v0.4.2

func (c *CRDEntry) HasAnyStorageSnapshots() bool

HasAnyStorageSnapshots reports whether this CRD defines any StorageSnapshots in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyStorageVolumes added in v0.4.2

func (c *CRDEntry) HasAnyStorageVolumes() bool

HasAnyStorageVolumes reports whether this CRD defines any StorageVolumes in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyTLSSecrets added in v0.2.3

func (c *CRDEntry) HasAnyTLSSecrets() bool

HasAnyTLSSecrets reports whether any secret in either phase defines a TLS configuration.

func (*CRDEntry) HasAnyVolumeMounts added in v0.4.2

func (c *CRDEntry) HasAnyVolumeMounts() bool

HasAnyVolumeMounts reports whether this CRD defines any VolumeMounts (placeholder) in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAnyVolumes added in v0.4.2

func (c *CRDEntry) HasAnyVolumes() bool

HasAnyVolumes reports whether this CRD defines any Volumes (placeholder) in either OnCreate or OnReconcile phases.

func (*CRDEntry) HasAutoscaleProfile

func (c *CRDEntry) HasAutoscaleProfile() bool

HasAutoscaleProfile reports whether this crd defined autoscale profile

func (*CRDEntry) HasCRDFile added in v0.4.8

func (c *CRDEntry) HasCRDFile() bool

HasCRDFile reports whether this CRDEntry declares a CRD file to be auto-applied before the operator starts.

func (*CRDEntry) HasCRFiles added in v0.5.1

func (c *CRDEntry) HasCRFiles() bool

HasCRFiles reports whether this CRDEntry declares CR YAML files to be applied before the runtime starts.

func (*CRDEntry) HasDeletionProtectionOverride added in v0.5.3

func (c *CRDEntry) HasDeletionProtectionOverride() bool

HasDeletionProtectionOverride reports whether deletion protection override is set for this CRD.

func (*CRDEntry) HasMutationRules

func (c *CRDEntry) HasMutationRules() bool

Separate helpers for hasMutationRules and hasValidationRules

func (*CRDEntry) HasNamespaceRules added in v0.1.9

func (c *CRDEntry) HasNamespaceRules() bool

HasNamespaceRules reports whether this CRD declares any namespace rules.

func (*CRDEntry) HasOnCreate added in v0.1.9

func (c *CRDEntry) HasOnCreate() bool

HasOnCreate reports whether this CRD declares any onCreate hooks.

func (*CRDEntry) HasOnDelete added in v0.1.9

func (c *CRDEntry) HasOnDelete() bool

HasOnDelete reports whether this CRD declares any onDelete hooks.

func (*CRDEntry) HasOnReconcile added in v0.1.9

func (c *CRDEntry) HasOnReconcile() bool

HasOnReconcile reports whether this CRD declares any onReconcile hooks.

func (*CRDEntry) HasProviders

func (c *CRDEntry) HasProviders() bool

HasProviders reports whether this CRD declares any provider blocks.

func (*CRDEntry) HasRestrictedNamespaces added in v0.1.9

func (c *CRDEntry) HasRestrictedNamespaces() bool

HasRestrictedNamespaces reports if restrictedNamespaces is defined for this crd.

func (*CRDEntry) HasRollbackRules added in v0.1.9

func (c *CRDEntry) HasRollbackRules() bool

HasRollbackRules reports whether this CRD has any rollback behavior configured — either via an explicit rollback: block or the rollBackOnError: true shorthand.

func (*CRDEntry) HasSetup added in v0.5.1

func (c *CRDEntry) HasSetup() bool

HasSetup reports whether this CRDEntry declares any setup work to be done before Orkestra starts.

func (*CRDEntry) HasSleep added in v0.4.2

func (c *CRDEntry) HasSleep() bool

HasSleep reports whether any sleep declarations exist for this CRD. It is a thin convenience wrapper around CollectSleepEntries.

func (*CRDEntry) HasStatusFields added in v0.4.0

func (c *CRDEntry) HasStatusFields() bool

HasStatusFields reports whether this CRD declares any status fields.

func (*CRDEntry) HasTemplates

func (c *CRDEntry) HasTemplates() bool

HasTemplates reports whether this CRD declares any declarative hook templates. Used by `ork generate` to determine whether to emit generated runtime hooks.

func (*CRDEntry) HasValidationOrMutationRules

func (c *CRDEntry) HasValidationOrMutationRules() bool

Returns true when either validation or mutation rules are declared. Used to decide whether to create the endpoints and/or populate the admission block in the health response. Even when ENABLE_ADMISSION_WEBHOOK=true

func (*CRDEntry) HasValidationRules

func (c *CRDEntry) HasValidationRules() bool

HasValidationRules reports whether this CRD has any validation behavior configured

func (*CRDEntry) HookManagedResources added in v0.4.1

func (c *CRDEntry) HookManagedResources() []ManagedResource

HookManagedResources returns the list of managed resources declared under the hooks block. Returns nil if hooks are not declared or no resources exist.

func (*CRDEntry) InvolvedInConversion added in v0.3.1

func (c *CRDEntry) InvolvedInConversion() bool

InvolvedInConversion reports whether this CRD is involved in version conversion. A CRD is involved when it either declares conversion paths (the CRD that hosts the /convert logic) or explicitly opts in with participant: true (the stable/ storage-version CRD on the other side of the pair).

func (*CRDEntry) IsBuiltInType

func (c *CRDEntry) IsBuiltInType() bool

IsBuiltInType reports whether this CRD represents a built‑in Kubernetes resource. Built‑ins rely on enrichment to populate group, version, plural, and scope.

func (*CRDEntry) IsConversionParticipant added in v0.6.2

func (c *CRDEntry) IsConversionParticipant() bool

IsConversionParticipant reports whether this CRD is a participant-only member of a conversion pair. Participants hold no conversion paths — those live on the CRD that owns the /convert logic. Used to skip path registration so a participant entry can never clobber the real rules during Katalog load.

func (*CRDEntry) IsDynamic

func (c *CRDEntry) IsDynamic() bool

IsDynamic determines whether this CRD should operate in dynamic mode. Resolution order (first match wins):

  1. mode: dynamic explicitly declared → true
  2. mode: typed explicitly declared → false
  3. APITypes.Location is empty → true (no compiled types available)
  4. APITypes.Location is set → false (compiled types available)

func (*CRDEntry) IsEnabled

func (c *CRDEntry) IsEnabled() bool

IsEnabled reports whether this CRD is enabled. Defaults to true when omitted.

func (*CRDEntry) IsEnabledAllEndpoints

func (c *CRDEntry) IsEnabledAllEndpoints() bool

IsEnabledAllEndpoints reports whether the all endpoints are disabled for this CRD. Defaults to false when omitted.

func (*CRDEntry) IsHealthEnabled

func (c *CRDEntry) IsHealthEnabled() bool

IsHealthEnabled reports whether the /health endpoint is enabled for this CRD. Defaults to true when omitted.

func (*CRDEntry) IsInfoEnabled

func (c *CRDEntry) IsInfoEnabled() bool

IsInfoEnabled reports whether the /info endpoint is enabled for this CRD. Defaults to true when omitted.

func (*CRDEntry) IsNamespaced

func (c *CRDEntry) IsNamespaced() bool

IsNamespaced reports whether this CRD is namespaced. Defaults to true unless explicitly overridden or determined by enrichment.

func (*CRDEntry) IsNotificationEnabled

func (c *CRDEntry) IsNotificationEnabled() bool

NotificationEnabled reports whether this CRD declares the notification block Enabled by default

func (*CRDEntry) IsStatuslessType

func (c *CRDEntry) IsStatuslessType() bool

IsStatusless reports whether this CRD has no meaningful readiness semantics. These resources become "Ready" immediately upon creation.

func (*CRDEntry) IsStrictDeletionProtection added in v0.5.3

func (c *CRDEntry) IsStrictDeletionProtection(katalogStrictMode bool) bool

IsStrictDeletionProtection returns whether strict deletion‑protection semantics apply to this CRD, taking into account the katalog‑level strict mode.

Strict mode is only possible when the katalog‑level strictMode is true. If the katalog‑level strictMode is false, this function always returns false.

When katalog‑level strictMode is true:

  • If the CRD has its own StrictMode value (non‑nil), that value is returned.
  • Otherwise, default to true.

This override only applies when global deletion protection is enabled (security.deletionProtection.enabled = true).

func (*CRDEntry) NeedsResourceDecl added in v0.3.8

func (c *CRDEntry) NeedsResourceDecl() bool

NeedsResourceDecl reports whether this CRD defines any workload resources (Deployments, StatefulSets, or ReplicaSets) in either OnCreate or OnReconcile.

func (*CRDEntry) ResourceDecl added in v0.3.8

func (c *CRDEntry) ResourceDecl() *ResourceRequirements

ResourceDecl returns the first ResourceRequirements defined for this CRD. It checks OnCreate first, then OnReconcile, and searches Deployments, StatefulSets, and ReplicaSets in that order. Returns nil if none exist.

func (*CRDEntry) RestrictedNamespacesOnly added in v0.1.9

func (c *CRDEntry) RestrictedNamespacesOnly() bool

RestrictedNamespacesOnly reports if only restrictedNamespaces is defined for this crd.

func (*CRDEntry) SetQueueDepth added in v0.6.2

func (c *CRDEntry) SetQueueDepth(def int) int

SetQueueDepth resolves the queue depth for this CRD. If a per‑CRD value is provided, it is used; otherwise the Orkestra/Konduktor‑level default is applied.

func (*CRDEntry) SetResync added in v0.4.4

func (c *CRDEntry) SetResync(def time.Duration) time.Duration

SetResync resolves the resync period for this CRD. If a per‑CRD non‑zero value is set, it is used; otherwise the global default resync is applied.

func (*CRDEntry) SetWorkers

func (c *CRDEntry) SetWorkers(def int) int

SetWorkers resolves the worker count for this CRD. If a per‑CRD value is provided, it is used; otherwise the global default worker count is applied.

func (*CRDEntry) SharedQueue added in v0.4.8

func (c *CRDEntry) SharedQueue() bool

SharedQueue reports whether this CRD uses the shared default workqueue. Defaults to false when omitted.

func (*CRDEntry) ShouldEnrich added in v0.4.9

func (c *CRDEntry) ShouldEnrich(target string) bool

ShouldEnrich returns true when the given enrichment target is enabled — either via EnrichAll: true or an explicit entry in Enrich. Condition gates (when:/anyOf:) are not evaluated here — they are handled higher up by ActiveEnrichTargets before the CRDEntry reaches each enricher.

func (*CRDEntry) ShouldMutateFirst added in v0.5.1

func (c *CRDEntry) ShouldMutateFirst() bool

ShouldMutateFirst reports whether this CRD prefers mutation first or not

Default is true

func (*CRDEntry) ShouldProtectCRD added in v0.5.3

func (c *CRDEntry) ShouldProtectCRD() bool

ShouldProtectCRD reports whether the CRD *type definition* itself should be protected from deletion when global deletion protection is enabled.

Semantics:

  • When DeletionProtection is nil → default to true
  • When ProtectCRD is nil → default to true
  • When ProtectCRD is false → CRD deletion is allowed

This controls whether DELETE operations on the CRD object (apiextensions.k8s.io/v1/customresourcedefinitions/<name>) are intercepted and blocked by the deletion‑protection webhook.

func (*CRDEntry) ShouldProtectCRs added in v0.5.3

func (c *CRDEntry) ShouldProtectCRs() bool

ShouldProtectCRs reports whether *instances* of this CRD should be protected from deletion when global deletion protection is enabled.

Semantics:

  • When DeletionProtection is nil → default to true
  • When ProtectCRs is nil → default to true
  • When ProtectCRs is false → CR deletion is allowed

This controls whether DELETE operations on CR instances are blocked unless the object explicitly opts out via the orkestra.io/deletion-protection label.

func (*CRDEntry) SkipObservedGeneration

func (c *CRDEntry) SkipObservedGeneration() bool

SkipObservedGeneration reports whether this CRD should ignore the status.observedGeneration field during readiness checks.

This is applied mainly to built‑in Kubernetes resources or CRDs that do not implement observedGeneration semantics. When true, Orkestra will NOT use generation-based readiness logic for this CRD.

func (*CRDEntry) SkipStatusSubresource

func (c *CRDEntry) SkipStatusSubresource() bool

SkipStatusSubresource reports whether this CRD belongs to a list to be ignored during status patches. This is applied mainly to builtins or if specifically required by the crd through crd.IgnoreStatusPatch

func (*CRDEntry) UnconditionalEnrichTargets added in v0.6.2

func (c *CRDEntry) UnconditionalEnrichTargets() []EnrichTarget

UnconditionalEnrichTargets returns entries with no when:/anyOf: conditions. These run in phase 1 of ReadChildren so that .children.* is populated before conditional gates are evaluated.

func (*CRDEntry) UpdateCRDCaBundle added in v0.1.8

func (c *CRDEntry) UpdateCRDCaBundle() bool

UpdateCRDCaBundle reports whether this CRD declares an updateCRD field Used to update the crd when certificate is autogenerted by orkestra

func (*CRDEntry) ValidateMetricField

func (c *CRDEntry) ValidateMetricField(field string) error

ValidateMetricField returns an error if the field is not a known autoscale metric.

func (*CRDEntry) WithAnyManagedResources added in v0.4.1

func (c *CRDEntry) WithAnyManagedResources() bool

WithAnyManagedResources reports whether hooks or constructor declare resources.

func (*CRDEntry) WithConstructorDecl added in v0.2.8

func (c *CRDEntry) WithConstructorDecl() bool

WithConstructorDecl returns true if the CRD has a constructor declaration. Required when Default: false in the Katalog. The generated registry will emit a ReconcilerRegistry entry for this CRD.

func (*CRDEntry) WithConstructorManagedResources added in v0.4.1

func (c *CRDEntry) WithConstructorManagedResources() bool

WithConstructorManagedResources reports whether this CRD has a constructor that declares managed resources for RBAC generation.

func (*CRDEntry) WithHookManagedResources added in v0.4.1

func (c *CRDEntry) WithHookManagedResources() bool

WithHookManagedResources reports whether this CRD has hooks that declare managed resources for RBAC generation.

func (*CRDEntry) WithHooksDecl added in v0.2.8

func (c *CRDEntry) WithHooksDecl() bool

WithHooksDecl returns true if the CRD has a hooks declaration (HookDeclaration). Used to determine whether to generate registry entries for the HookRegistry. Does not imply anything about Default: true/false — a typed CRD can have hooks even when Default: true (generic reconciler) or false (custom reconciler).

type CRDMode

type CRDMode string

CRDMode controls how the GenericReconciler handles CR objects at runtime.

typed

Requires compiled API types via apiTypes.location.
Objects are decoded into concrete Go structs by the REST client.
Full type safety and generated DeepCopy methods.
Required when Go hooks reference typed fields directly.
Use when you have generated API types and want compile-time guarantees.

dynamic

No compiled types needed. Objects are map[string]interface{} at runtime.
Works with any CRD without code generation or controller-gen.
Required for declarative hook templates (onCreate, onReconcile, onDelete)
because field values are resolved at reconcile time via Go text/template
expressions against the live CR object map.
Use when you want zero-code operator behavior from the Katalog alone.

Auto-detection when mode is omitted:

apiTypes.location is set   → typed       (compiled types available)
apiTypes.location is empty → dynamic (no compiled types)

Override auto-detection by setting mode explicitly:

crd:
 - name: websites
   mode: dynamic   		# force dynamic even if location is set
   mode: typed          # force typed even if location is empty

func (CRDMode) String

func (m CRDMode) String() string

type CapabilitiesConfig added in v0.5.4

type CapabilitiesConfig struct {
	// Add — capabilities to add beyond the default set.
	Add []string `yaml:"add,omitempty" json:"add,omitempty"`

	// Drop — capabilities to remove from the default set.
	// Use ["ALL"] to drop every capability before selectively adding back.
	Drop []string `yaml:"drop,omitempty" json:"drop,omitempty"`
}

CapabilitiesConfig declares Linux capabilities to add or drop.

type CapabilityEntry added in v0.5.4

type CapabilityEntry struct {
	Phase        string // "onCreate", "onReconcile", "onDelete"
	Resource     string // e.g. "Deployment", "StatefulSet"
	ResourceName string
	Side         string // "add" or "drop"
	Value        string // raw capability name as written (e.g. "NET_RAW", "ALL")
}

CapabilityEntry describes a single capability value found in a ContainerSecurityContext.Capabilities block. Used to validate names against the known Linux capability set at katalog load time.

type CertManagerConfig added in v0.4.9

type CertManagerConfig struct {
	// AutoRotate controls whether Orkestra pre-emptively rotates the TLS certificate
	// before it expires. The new certificate takes effect on the next gateway restart.
	// Default: true. Set to false or TLS_AUTO_ROTATE=false to opt out.
	AutoRotate *bool `yaml:"autoRotate,omitempty" json:"autoRotate,omitempty"`

	// RotationThreshold is how far before expiry Orkestra rotates the certificate.
	// Accepts duration strings: "30d", "7d", "2w". Default: "30d".
	RotationThreshold string `yaml:"rotationThreshold,omitempty" json:"rotationThreshold,omitempty"`

	// ValidFor is the validity period of the certificate.
	// Accepts duration strings: "30d", "7d", "2w". Default: "1y".
	ValidFor string `yaml:"validFor,omitempty" json:"validFor,omitempty"`
}

CertManagerConfig controls Orkestra's built-in TLS certificate lifecycle. Only applies when certificates are auto-generated (no TLS_CERT/TLS_KEY env vars).

YAML shape:

security:
  certManager:
    autoRotate: true           # default: true — rotate cert before expiry
    rotationThreshold: "30d"   # default: 30 days before expiry

type Condition

type Condition struct {
	// Field — dot-notation path to a field in the CR object or a runtime metric.
	// e.g. "spec.environment", "metrics.queueDepth", "cross.managed-database.metrics.queueDepth"
	Field string `yaml:"field" validate:"required" json:"field"`

	// Operator — how to compare the field value.
	// See ConditionOperator constants below.
	Operator ConditionOperator `yaml:"operator,omitempty" json:"operator,omitempty"`

	// Value — the value to compare against.
	// Not used for exists/notExists operators.
	// Supports template expressions: "{{ .metadata.name }}-prod"
	Value string `yaml:"value,omitempty" json:"value,omitempty"`

	// Equals is a shorthand for operator: equals.
	Equals string `yaml:"equals,omitempty" json:"equals,omitempty"`

	// NotEquals is a shorthand for operator: notEquals.
	NotEquals string `yaml:"notEquals,omitempty" json:"notEquals,omitempty"`

	// Contains is a shorthand for operator: contains.
	Contains string `yaml:"contains,omitempty" json:"contains,omitempty"`

	// Prefix is a shorthand for operator: prefix.
	Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty"`

	// Suffix is a shorthand for operator: suffix.
	Suffix string `yaml:"suffix,omitempty" json:"suffix,omitempty"`

	// Exists is a shorthand for operator: exists.
	// When true, the condition passes when the field is present and non-empty.
	Exists *bool `yaml:"exists,omitempty" json:"exists,omitempty"`

	// NotExists is a shorthand for operator: notExists.
	// When true, the condition passes when the field is absent or empty.
	NotExists *bool `yaml:"notExists,omitempty" json:"notExists,omitempty"`

	// Numeric shorthands
	GreaterThan string `yaml:"greaterThan,omitempty" json:"greaterThan,omitempty"`
	LessThan    string `yaml:"lessThan,omitempty" json:"lessThan,omitempty"`

	// Time — active when the current time is within the declared window.
	// After and Before are both optional; omit one for a half-open range.
	//   anyOf:
	//     - time:
	//         after: "08:00"
	//         before: "20:00"
	Time *TimeWindow `yaml:"time,omitempty" json:"time,omitempty"`

	// DayOfWeek — active on the specified days of the week.
	//   anyOf:
	//     - dayOfWeek:
	//         in: [Monday, Tuesday, Wednesday, Thursday, Friday]
	DayOfWeek *DayOfWeekCondition `yaml:"dayOfWeek,omitempty" json:"dayOfWeek,omitempty"`

	// Cron — a standard cron expression (5-field) that defines when the
	// window opens. Duration defines how long the window stays open.
	// Without Duration, the window closes after one evaluation interval.
	Cron string `yaml:"cron,omitempty" json:"cron,omitempty"`

	// Duration — how long a cron-opened window remains active.
	Duration Duration `yaml:"duration,omitempty" json:"duration,omitempty"`

	// Notify declares teams to alert when this condition is true.
	Notify *NotifyBlock `yaml:"notify,omitempty" json:"notify,omitempty"`

	// Source is the HTTP fallback for cross-binary metric observation.
	// Only used when field is a cross.<crd>.metrics.* field and the CRD
	// is not registered in GlobalCrossMetricsRegistry (different binary).
	// The endpoint must be the remote operator's /katalog/{crd} URL.
	//
	//   when:
	//     - field: cross.managed-database.metrics.queueDepth
	//       greaterThan: "500"
	//       source:
	//         host: "http://orkestra-database-operator:8080"
	// 		   crd: managed-database
	//   when:
	//     - field: cross.managed-database.metrics.queueDepth
	//       greaterThan: "500"
	//       source:
	//         endpoint: "http://non-orkestra-database-operator:8080/api/managed-database/metrics"
	Source *CrossSource `yaml:"source,omitempty" json:"source,omitempty"`
}

Condition declares a single condition to evaluate against the CR or runtime state. Fields reference CR paths using dot notation: spec.environment, metadata.name.

The same type is used in:

  • when: / anyOf: on template sources (resource conditions)
  • operatorBox.autoscale.conditions.anyOf and when: (autoscale conditions)
  • operatorBox.rollback.trigger (rollback conditions)
  • notification condition blocks

type ConditionOperator

type ConditionOperator string

ConditionOperator defines how a condition's field is compared to its value.

const (
	// ConditionEquals — field value exactly equals the condition value (string comparison)
	ConditionEquals ConditionOperator = "equals"

	// ConditionNotEquals — field value does not equal the condition value
	ConditionNotEquals ConditionOperator = "notEquals"

	// ConditionContains — field value contains the condition value as a substring
	ConditionContains ConditionOperator = "contains"

	// ConditionPrefix — field value starts with the condition value
	ConditionPrefix ConditionOperator = "prefix"

	// ConditionSuffix — field value ends with the condition value
	ConditionSuffix ConditionOperator = "suffix"

	// ConditionExists — the field is present and non-empty
	// Value is ignored for this operator.
	ConditionExists ConditionOperator = "exists"

	// ConditionNotExists — the field is absent or empty
	// Value is ignored for this operator.
	// Use for: first-reconcile detection (phase not yet written).
	//   when:
	//     - field: status.phase
	//       operator: notExists
	ConditionNotExists ConditionOperator = "notExists"

	// ConditionGt — field value is numerically greater than condition value
	ConditionGt ConditionOperator = "gt"

	// ConditionLt — field value is numerically less than condition value
	ConditionLt ConditionOperator = "lt"

	// ConditionIn — field value is one of a comma-separated list.
	// Empty string matches an empty field (for first-reconcile detection).
	//   when:
	//     - field: status.phase
	//       operator: in
	//       value: ",Pending"   # empty or "Pending"
	ConditionIn ConditionOperator = "in"

	// ConditionUnique — field value is unique across all existing CR instances.
	//
	// Only valid in validation rules (deny action). Checks the informer cache
	// for any existing CR with the same field value.
	//
	//	validation:
	//	  rules:
	//	    - field: spec.domain
	//	      operator: unique
	//	      message: "spec.domain must be unique across all instances"
	//	      action: deny
	//
	// Not valid in when: blocks on template sources — uniqueness requires
	// informer access which is not available during template evaluation.
	// In when: context it is treated as always-true (see pkg/types/when/EvaluateOneCond).
	ConditionUnique ConditionOperator = "unique"

	// ConditionTypeOf — check field type
	//
	ConditionTypeOf ConditionOperator = "typeOf"

	// ConditionTypeMap — field value is a map (YAML object)
	ConditionTypeMap ConditionOperator = "typeMap"

	// ConditionTypeList — field value is a slice (YAML array)
	ConditionTypeList ConditionOperator = "typeList"

	// ConditionTypeString — field value is a string
	ConditionTypeString ConditionOperator = "typeString"

	// ConditionTypeNumber — field value is a number (int/float)
	ConditionTypeNumber ConditionOperator = "typeNumber"

	// ConditionTypeBool — field value is a boolean
	ConditionTypeBool ConditionOperator = "typeBool"

	// ConditionTypeNull — field value is null or missing
	ConditionTypeNull ConditionOperator = "typeNull"
)

func ResolveConditionOp

func ResolveConditionOp(c Condition) (ConditionOperator, string)

ResolveConditionOp resolves the effective operator and comparison value from a Condition, respecting shorthand fields. Exported so the template package can use the same resolution logic.

type ConfigMapKeyRef

type ConfigMapKeyRef struct {
	Name string `yaml:"name" json:"name"`
	Key  string `yaml:"key" json:"key"`
}

ConfigMapKeyRef selects a key from a Kubernetes ConfigMap. Both Name and Key are required.

type ConfigMapTemplateSource

type ConfigMapTemplateSource struct {
	// Version — OrkestraRegistry implementation version. Omit for latest.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Name — ConfigMap name.
	// Default when omitted: "{{ .metadata.name }}-config"
	Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"omitempty"`

	// Namespace — target namespace.
	// Default when omitted: "{{ .metadata.namespace }}"
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty" validate:"omitempty"`

	// ToNamespaces - a list of target namespaces
	// Default when omitted: "{{ .metadata.namespace }}"
	ToNamespaces []string `yaml:"toNamespaces,omitempty" json:"toNamespaces,omitempty" validate:"omitempty"`

	// Data — static key-value configuration entries.
	// Values are plain strings — template expressions are not supported here.
	Data map[string]string `yaml:"data,omitempty" json:"data,omitempty" validate:"omitempty"`

	// Labels — applied to ConfigMap metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`
	// FromConfigMap — name of an existing ConfigMap to copy data from.
	// Orkestra reads this at reconcile time — copies stay in sync with the source.
	FromConfigMap string `yaml:"fromConfigMap,omitempty" json:"fromConfigMap,omitempty" validate:"omitempty"`

	// FromNamespace — namespace where FromConfigMap lives.
	// Default: same namespace as the CR.
	FromNamespace string `yaml:"fromNamespace,omitempty" json:"fromNamespace,omitempty" validate:"omitempty"`

	// Reconcile: true — also apply this declaration as drift correction on every
	// reconcile. Equivalent to declaring the same entry under both onCreate and
	// onReconcile. When false (default), only runs on onCreate (idempotent create).
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty" validate:"omitempty"`

	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`
	// ForEach declares dynamic expansion over a list field.
	// When set, one source declaration becomes N declarations — one per list element.
	// .item and .<as> are available in template expressions within this declaration.
	ForEach *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// AnyOf holds OR conditions — at least one must pass for this resource to be created.
	// Works alongside the existing Conditions (when:) field which uses AND semantics.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

ConfigMapTemplateSource declares one ConfigMap to be managed by Orkestra.

ConfigMap data values are static — template expressions are not evaluated in ConfigMap data entries. For dynamic configuration, use a custom Go hook.

Example:

onCreate:
  configMaps:
    - name: "{{ .metadata.name }}-config"
      data:
        LOG_LEVEL: info
        MAX_CONNECTIONS: "100"

func (ConfigMapTemplateSource) GetName added in v0.4.2

func (t ConfigMapTemplateSource) GetName() string

func (ConfigMapTemplateSource) GetSleep added in v0.4.2

func (t ConfigMapTemplateSource) GetSleep() string

type ConfigMapVolumeSource added in v0.6.2

type ConfigMapVolumeSource struct {
	// Name — ConfigMap name. Supports template expressions.
	//   name: "{{ .metadata.name }}-config"
	Name string `yaml:"name" json:"name"`
}

ConfigMapVolumeSource mounts a ConfigMap as a volume.

type ConstructorDeclaration

type ConstructorDeclaration struct {
	// Location — fully qualified Go import path. Local or remote module.
	Location string `yaml:"location" json:"location" validate:"required"`

	// Version — optional module version to pin for this constructor.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Fetch — when true, ork generate will run:
	// `go get <location>@<version>` to fetch the requested version.
	Fetch bool `yaml:"fetch,omitempty" json:"fetch,omitempty"`

	// Function — exported constructor function name at Location.
	// e.g. "NewManagedNamespaceReconciler"
	Function string `yaml:"function" json:"function" validate:"required"`

	// Alias — Go import alias. Optional, auto-derived from Location if omitted.
	Alias string `yaml:"alias,omitempty" json:"alias,omitempty" validate:"omitempty"`

	// Resources — Kubernetes resource types this constructor manages (used for RBAC generation).
	Resources []ManagedResource `json:"resources,omitempty" yaml:"resources,omitempty"`
}

ConstructorDeclaration declares where a custom reconciler constructor lives. Read by ork generate to emit ReconcilerRegistry entries. The declared function must match: NewReconcilerFunc

type ContainerSecurityContext added in v0.5.4

type ContainerSecurityContext struct {
	// Profile — named security preset. One of: baseline, restricted, hardened.
	// Expands into the corresponding container security fields at katalog load time.
	Profile string `yaml:"profile,omitempty" json:"profile,omitempty"`

	// AllowPrivilegeEscalation — controls whether a process can gain more
	// privileges than its parent process. Defaults to true if unset.
	AllowPrivilegeEscalation *bool `yaml:"allowPrivilegeEscalation,omitempty" json:"allowPrivilegeEscalation,omitempty"`

	// ReadOnlyRootFilesystem — mounts the container's root filesystem as read-only.
	ReadOnlyRootFilesystem *bool `yaml:"readOnlyRootFilesystem,omitempty" json:"readOnlyRootFilesystem,omitempty"`

	// RunAsNonRoot — if true, the container must run as a non-root user.
	RunAsNonRoot *bool `yaml:"runAsNonRoot,omitempty" json:"runAsNonRoot,omitempty"`

	// RunAsUser — UID to run the container entrypoint.
	RunAsUser *int64 `yaml:"runAsUser,omitempty" json:"runAsUser,omitempty"`

	// RunAsGroup — GID to run the container entrypoint.
	RunAsGroup *int64 `yaml:"runAsGroup,omitempty" json:"runAsGroup,omitempty"`

	// Capabilities — Linux capabilities to add or drop from the container.
	Capabilities *CapabilitiesConfig `yaml:"capabilities,omitempty" json:"capabilities,omitempty"`
}

ContainerSecurityContext declares container-level security settings. Set Profile for a named preset or declare individual fields directly. Profile and explicit fields are mutually exclusive.

type ConversionConfig

type ConversionConfig struct {
	// Enabled controls whether the /convert endpoint is registered and the
	// CRD conversion webhook is active.
	// Default: ENABLE_CONVERSION env / false.
	Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`

	// ConversionWindow is the rolling window size for latency/throughput stats.
	// Default: CONVERSION_WINDOW env / 100.
	ConversionWindow int `yaml:"conversionWindow,omitempty" json:"conversionWindow,omitempty"`
}

ConversionConfig controls the /convert endpoint and CRD version conversion.

type ConversionPath

type ConversionPath struct {
	// From — the source version (bare, e.g. "v1alpha1")
	From string `yaml:"from" validate:"required" json:"from"`

	// To — the target version (bare, e.g. "v1")
	To string `yaml:"to" validate:"required" json:"to"`

	// Spec — the output spec in the target version's format.
	// Values support Go template expressions evaluated against the source object.
	// Static values are used as-is.
	Spec map[string]interface{} `yaml:"spec" validate:"required" json:"spec"`
}

ConversionPath declares one explicit conversion mapping. Both From and To are bare version strings — not full apiVersion strings.

from: v1alpha1   ← bare version, not "demo.orkestra.io/v1alpha1"
to: v1
spec:
  image: "{{ .spec.image }}"
  seo:
    enabled: false

type ConversionRules

type ConversionRules struct {
	Kind           string           `json:"kind" yaml:"kind"`
	StorageVersion string           `json:"storageVersion" yaml:"storageVersion"`
	Paths          []ConversionPath `json:"paths" yaml:"paths"`
}

ConversionRules is the runtime form of CRDConversion, keyed by Kind. Registered in the InMemoryConversionRegistry at Katalog load time.

func (*ConversionRules) FindPath

func (r *ConversionRules) FindPath(fromVersion, toVersion string) *ConversionPath

FindPath returns the conversion path for a given (from, to) pair. Both fromVersion and toVersion must be bare version strings. Returns nil when no path matches.

type ConversionVersionSpec

type ConversionVersionSpec struct {
	Version string                 `json:"version" yaml:"version"`
	Spec    map[string]interface{} `json:"spec" yaml:"spec"`
}

type CronJobTemplateSource

type CronJobTemplateSource struct {
	// Version — OrkestraRegistry implementation version. Omit for latest.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Name — CronJob name.
	// Default when omitted: "{{ .metadata.name }}-cronjob"
	Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"omitempty"`

	// Schedule — cron schedule expression. Required.
	// Static: "0 * * * *" (every hour)
	// Dynamic: "{{ .spec.schedule }}"
	Schedule string `yaml:"schedule" json:"schedule" validate:"required"`

	// Image — container image. Required.
	Image string `yaml:"image" json:"image" validate:"omitempty"`

	// ImagePullSecrets is an optional list of references to secrets in the same namespace to use
	// for pulling any of the images used by this PodSpec.
	// If specified, these secrets will be passed to individual puller implementations for them to use.
	ImagePullSecrets []string `yaml:"imagePullSecrets,omitempty" json:"imagePullSecrets,omitempty" validate:"omitempty"`

	// Command — container entrypoint. Each element supports template expressions.
	Command []string `yaml:"command,omitempty" json:"command,omitempty" validate:"omitempty"`

	// Args — container arguments. Each element supports template expressions.
	Args []string `yaml:"args,omitempty" json:"args,omitempty" validate:"omitempty"`

	// Namespace — target namespace.
	// Default when omitted: "{{ .metadata.namespace }}"
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty" validate:"omitempty"`

	// Labels — applied to CronJob metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`

	// NodeSelector is a selector which must be true for the pod to fit on a node.
	// Selector which must match a node's labels for the pod to be scheduled on that node.
	// More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
	// +optional
	// +mapType=atomic
	NodeSelector map[string]string `yaml:"nodeSelector,omitempty" json:"nodeSelector,omitempty"`

	// ServiceAccountName is the name of the ServiceAccount to use to run this pod.
	// More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
	// +optional
	ServiceAccountName string `yaml:"serviceAccountName,omitempty" json:"serviceAccountName,omitempty"`

	// Reconcile: true — also apply this declaration as drift correction on every
	// reconcile. Equivalent to declaring the same entry under both onCreate and
	// onReconcile. When false (default), only runs on onCreate (idempotent create).
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty" validate:"omitempty"`

	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`

	Suspend                    string `yaml:"suspend,omitempty" json:"suspend,omitempty"`
	SuccessfulJobsHistoryLimit string `yaml:"successfulJobsHistoryLimit,omitempty" json:"successfulJobsHistoryLimit,omitempty"`
	FailedJobsHistoryLimit     string `yaml:"failedJobsHistoryLimit,omitempty" json:"failedJobsHistoryLimit,omitempty"`
	ConcurrencyPolicy          string `yaml:"concurrencyPolicy,omitempty" json:"concurrencyPolicy,omitempty"`
	StartingDeadlineSeconds    string `yaml:"startingDeadlineSeconds,omitempty" json:"startingDeadlineSeconds,omitempty"`

	// Resources — CPU and memory requests/limits for the container.
	// Set resources.profile for a named preset, or resources.requests/limits for
	// explicit values. Profile and explicit values are mutually exclusive.
	Resources *ResourceRequirements `yaml:"resources,omitempty" json:"resources,omitempty" validate:"omitempty"`

	// ForEach declares dynamic expansion over a list field.
	// When set, one source declaration becomes N declarations — one per list element.
	// .item and .<as> are available in template expressions within this declaration.
	ForEach *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// AnyOf holds OR conditions — at least one must pass for this resource to be created.
	// Works alongside the existing Conditions (when:) field which uses AND semantics.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// WorkingDirectory sets the container's working directory (container.WorkingDir).
	// Useful for Git-backed pipelines where build/test commands must run inside
	// a checked-out repository path.
	WorkingDirectory string `yaml:"workingDirectory,omitempty" json:"workingDirectory,omitempty"`

	// SecurityContext — container-level security settings.
	// Set securityContext.profile for a named preset (baseline, restricted, hardened)
	// or declare individual fields. Profile and explicit fields are mutually exclusive.
	SecurityContext *ContainerSecurityContext `yaml:"securityContext,omitempty" json:"securityContext,omitempty"`

	// PodSecurity — pod-level security settings applied to the pod spec.
	// Set podSecurity.profile for a named preset or declare individual fields.
	PodSecurity *PodSecurityContext `yaml:"podSecurity,omitempty" json:"podSecurity,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

CronJobTemplateSource declares one CronJob to be managed by Orkestra.

Example:

onCreate:
  cronJobs:
    - name: "{{ .metadata.name }}-sync"
      schedule: "{{ .spec.syncSchedule }}"
      image: "{{ .spec.syncImage }}"
      command: ["sh", "-c", "sync.sh"]

func (CronJobTemplateSource) GetName added in v0.4.2

func (t CronJobTemplateSource) GetName() string

func (CronJobTemplateSource) GetPodSecurity added in v0.5.4

func (t CronJobTemplateSource) GetPodSecurity() *PodSecurityContext

func (CronJobTemplateSource) GetResources added in v0.4.2

func (t CronJobTemplateSource) GetResources() *ResourceRequirements

func (CronJobTemplateSource) GetSecurityContext added in v0.5.4

func (t CronJobTemplateSource) GetSecurityContext() *ContainerSecurityContext

func (CronJobTemplateSource) GetSleep added in v0.4.2

func (t CronJobTemplateSource) GetSleep() string

type CrossCRDDeclaration

type CrossCRDDeclaration struct {
	// Crd is the target CRD name (lowercase, matches the map key in spec.crds).
	//   crd: database
	Crd string `yaml:"crd" json:"crd"`

	// LabelSelector is a label key/value pair for label-based informer lookup.
	// Mutually exclusive with Kind.
	LabelSelector map[string]string `yaml:"labelSelector,omitempty" json:"labelSelector,omitempty"`

	// Selector identifies which CR instance to observe.
	Selector CrossSelector `yaml:"selector" json:"selector"`

	// As is the key under .cross.* where the result is accessible.
	//   as: database → .cross.database.status.phase
	// Default: same as Crd.
	As string `yaml:"as,omitempty" json:"as,omitempty"`

	// Strategy controls what happens when multiple CRs match the selector.
	//   first (default) — use the first match
	//   all             — put all matches in .cross.<as>[] (array)
	Strategy string `yaml:"strategy,omitempty" json:"strategy,omitempty"`

	// Source is the fallback for cross-binary or cross-cluster observation.
	// When absent, the informer cache is used (zero API calls).
	// When set, the endpoint is called when the informer is unavailable.
	Source *CrossSource `yaml:"source,omitempty" json:"source,omitempty"`
}

CrossCRDDeclaration declares one cross-CRD observation. Declared in the operatorBox config under cross: for a CRD.

type CrossField added in v0.4.5

type CrossField struct {
	CRD       string // loader, db, processor, etc.
	Category  string // metrics, health, info, events, children
	Namespace string // optional (info/events only)
	Field     string // queueDepth, lastError, status.phase, etc.
}

CrossField describes a parsed cross.<crd>.<category>.<field> reference.

func ParseCrossField added in v0.4.5

func ParseCrossField(field string) *CrossField

ParseCrossField parses a cross.* field path into a structured CrossField.

Examples:

cross.loader.metrics.queueDepth
  → CRD=loader, Category=metrics, Namespace="", Field="queueDepth"

cross.db.health.lastError
  → CRD=db, Category=health, Namespace="", Field="lastError"

cross.api.info.default.my-api.status.phase
  → CRD=api, Category=info, Namespace=default, Field="status.phase"

Returns nil if the field is not a valid cross.* reference.

type CrossSelector

type CrossSelector struct {
	// Name is the CR name to look up. Template expressions supported.
	//   name: "{{ .metadata.name }}"    → same name as the current CR
	Name string `yaml:"name,omitempty" json:"name,omitempty"`

	// Namespace is the CR namespace. Template expressions supported.
	// Default: same namespace as the current CR.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`

	// LabelSelector selects CRs by label — for 1:N or N:1 relationships.
	//   labelSelector: "tenant={{ .spec.tenant }},env={{ .spec.environment }}"
	// When set, Name and Namespace are ignored.
	LabelSelector string `yaml:"labelSelector,omitempty" json:"labelSelector,omitempty"`
}

CrossSelector identifies a CR in the target CRD. The selector block on a cross: declaration. Exactly one of Name or LabelSelector should be set per entry.

type CrossSource

type CrossSource struct {

	// Endpoint is a fully-qualified URL. If set, Orkestra uses it directly
	// and ignores Host/Type/Namespace. Template expressions supported.
	Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"`

	// Host is the base URL of a remote Orkestra runtime, e.g.:
	//   http://orkestra-runtime.loader-system:8080
	// Combined with Type to build the final URL.
	Host string `yaml:"host,omitempty" json:"host,omitempty"`

	// Type selects which Orkestra-native endpoint to call.
	// One of: "info", "metrics", "health", "events".
	// Default: "info".
	Type ONCOPType `yaml:"type,omitempty" json:"type,omitempty"`

	// Namespace overrides the CR namespace when building info/events URLs.
	// Optional — defaults to the CR's own namespace.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`

	// Token is a bearer token for the endpoint. $ENV_VAR syntax supported.
	Token string `yaml:"token,omitempty" json:"token,omitempty"`

	// CacheFor controls how long to cache the result before calling again.
	// Default: 30s — prevents hammering the endpoint on every evaluation.
	CacheFor string `yaml:"cacheFor,omitempty" json:"cacheFor,omitempty"`
}

CrossSource declares how to fetch cross-binary/cluster data for a CRD. If Endpoint is provided, it is used as-is (raw HTTP fetch). If Host is provided, Orkestra constructs the URL based on Type.

Supported Type values:

  • "info" → /katalog/<crd>/cr/<ns>/<name>
  • "metrics" → /katalog/<crd>
  • "health" → /katalog/<crd>/health
  • "events" → /katalog/<crd>/cr/<ns>/<name>/events

The endpoint must return the same JSON shape as the informer cache path — i.e., the Orkestra CR detail endpoint format. Namespace is optional; defaults to the CR's namespace when omitted.

type CustomResourceMetadata added in v0.4.6

type CustomResourceMetadata struct {
	// Name is the resource name. Must be a valid Kubernetes name after templating.
	Name string `json:"name" yaml:"name"`

	// Namespace is optional in the struct but required for namespaced CRDs.
	// Validation will enforce presence when the target GVK is namespaced.
	Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`

	// Namespaced indicates whether the target GVK is intended to be namespaced.
	// Three states are useful and intentionally supported:
	//   - nil: unspecified; reconciler should treat this as "default to namespaced"
	//          and may auto-detect the real scope via discovery at runtime.
	//   - pointer to true: explicitly namespaced; metadata.namespace is required.
	//   - pointer to false: explicitly cluster-scoped; metadata.namespace must be empty.
	//
	// Defaulting/validation contract:
	// - Validation should treat nil as "namespaced by default" for user ergonomics.
	// - At runtime the reconciler should still consult discovery/RESTMapper to
	//   confirm the actual CRD scope and register the GVK with activateMissing if
	//   the CRD is not present yet.
	// - If the user sets Namespaced=false but discovery shows the CRD is namespaced,
	//   the reconciler should surface a clear validation error.
	Namespaced *bool `json:"namespaced,omitempty" yaml:"namespaced,omitempty"`

	// Labels are used for selection, ownership, and children tracking.
	// Keys and values must conform to Kubernetes label syntax.
	Labels []ResourceLabel `json:"labels,omitempty" yaml:"labels,omitempty"`

	// Annotations are free-form metadata. Keys must conform to Kubernetes
	// annotation key syntax. Values are arbitrary strings.
	Annotations []ResourceLabel `json:"annotations,omitempty" yaml:"annotations,omitempty"`
}

CustomResourceMetadata mirrors the small subset of metav1.ObjectMeta that Orkestra needs for templating, identity, and children tracking.

Important notes:

  • Name is required after templating. The reconciler will error if Name is empty.
  • Namespace is optional in the struct but validation enforces it for namespaced CRDs. For cluster-scoped CRDs Namespace must be empty.
  • Labels and Annotations must conform to Kubernetes key/value rules. Use the existing label/annotation validators in the codebase.

type CustomResourceTemplateSource added in v0.4.6

type CustomResourceTemplateSource struct {
	// APIVersion is required and must be a group/version string (e.g. "foo.io/v1").
	// This field is used to derive the GroupVersionKind for REST mapping.
	APIVersion string `json:"apiVersion" yaml:"apiVersion"`

	// Kind is required and must be a valid Kubernetes Kind (e.g. "Bar").
	// Used together with APIVersion to resolve the GVR for dynamic client calls.
	Kind string `json:"kind" yaml:"kind"`

	// Metadata mirrors the subset of metav1.ObjectMeta Orkestra needs.
	// Implementations must ensure metadata.Name is present after templating.
	// Namespace is required for namespaced CRDs; for cluster-scoped CRDs the
	// namespace field should be empty. Whether a CRD is namespaced is determined
	// by discovery/validation and not by this struct alone.
	Metadata CustomResourceMetadata `json:"metadata" yaml:"metadata"`

	// Spec is the conventional spec block for CRDs. It is schema-agnostic and
	// may contain templated values. Only template syntax is validated by
	// Orkestra; structural/schema validation is deferred to the API server.
	Spec map[string]any `json:"spec,omitempty" yaml:"spec,omitempty"`

	// Status is allowed in the declaration for convenience (for example when
	// bootstrapping resources that expect an initial status). Orkestra will
	// only attempt to write status if HasStatus() returns true.
	// Users should prefer letting the controller that owns the CR populate status.
	Status map[string]any `json:"status,omitempty" yaml:"status,omitempty"`

	// Other captures any top-level fields that are not spec/status/metadata.
	// This supports CRDs that place configuration at the top level instead of
	// under spec. This field is inlined during YAML/JSON unmarshalling.
	Other map[string]any `json:"-" yaml:",inline"`

	// HasStatus is an explicit hint about whether the CRD exposes a status
	// subresource. Three states are useful:
	//   - nil: auto-detect via discovery at runtime
	//   - true: force status writes (patches)
	//   - false: never attempt status writes
	// Use this to avoid API errors for CRDs that do not support status.
	HasStatus *bool `json:"hasStatus,omitempty" yaml:"hasStatus,omitempty"`

	Reconcile  bool         `yaml:"reconcile" json:"reconcile,omitempty"`
	Conditions []Condition  `yaml:"when,omitempty" json:"when,omitempty"`
	AnyOf      []Condition  `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`
	ForEach    *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
	// contains filtered or unexported fields
}

CustomResourceTemplateSource represents an arbitrary Kubernetes resource declared inside onCreate/onReconcile/onDelete hooks. It is intentionally schema-agnostic and serialises to/from YAML/JSON as the user wrote it in the Katalog.

Design goals:

  • Mirror Kubernetes conventions for metadata so created objects are valid.
  • Be friendly to Orkestra's templating and dynamic client pipeline.
  • Make status semantics explicit so the reconciler knows whether to attempt status patches.
  • Allow arbitrary top-level fields for CRDs that do not follow spec/status conventions.

Notes for implementers:

  • This struct is converted to an unstructured.Unstructured before any dynamic client calls. No CRD schema validation is performed here; Kubernetes will enforce schema at API server time.
  • Validation rules (required fields, namespaced vs cluster-scoped, label and annotation format, template correctness) should be enforced by validateCustomResource() before attempting creation.
  • If the CRD is not present at runtime, the reconciler should register the GVK with the kordinator's activateMissing flow and requeue the reconcile.
  • Reconcile defaults to true; treat false as "create once, do not drift-correct".

func (*CustomResourceTemplateSource) BuildGVK added in v0.4.6

BuildGVK parses APIVersion and Kind and returns a GroupVersionKind. It caches the result on the receiver.

Behaviour: - Uses schema.ParseGroupVersion to correctly handle group/version parsing. - Returns an error if APIVersion or Kind are empty or invalid.

func (*CustomResourceTemplateSource) CustomResourceMeta added in v0.4.6

func (c *CustomResourceTemplateSource) CustomResourceMeta() CustomResourceMetadata

CustomResourceMeta returns the metadata block. It returns the concrete metadata struct rather than a pointer to encourage callers to treat the returned value as a snapshot. Mutations to the returned value do not affect the original CustomResource unless explicitly assigned back.

func (*CustomResourceTemplateSource) GVKString added in v0.4.6

func (c *CustomResourceTemplateSource) GVKString() string

GVKString returns a human-friendly GVK string. Falls back to APIVersion/Kind if building the GVK fails.

func (*CustomResourceTemplateSource) GVRString added in v0.4.6

func (c *CustomResourceTemplateSource) GVRString() string

GVRString returns a human-friendly GVR string if resolved, otherwise a placeholder.

func (CustomResourceTemplateSource) GetName added in v0.4.6

Custom Resource

func (CustomResourceTemplateSource) GetSleep added in v0.4.6

func (t CustomResourceTemplateSource) GetSleep() string

Custom Resource

func (*CustomResourceTemplateSource) HasAnnotations added in v0.4.6

func (c *CustomResourceTemplateSource) HasAnnotations() bool

HasAnnotations reports whether the resource has any annotations after templating. Use this to decide whether to merge annotations or to skip annotation-based logic.

func (*CustomResourceTemplateSource) HasLabels added in v0.4.6

func (c *CustomResourceTemplateSource) HasLabels() bool

HasLabels reports whether the resource has any labels after templating. Use this to decide whether to merge labels or to skip label-based selection.

func (*CustomResourceTemplateSource) IsNamespaced added in v0.4.6

func (c *CustomResourceTemplateSource) IsNamespaced() bool

IsNamespaced returns whether the declaration intends the resource to be namespaced. It implements Orkestra's defaulting rule: unspecified (nil) defaults to true (namespaced). Callers should still verify actual CRD scope via discovery before performing API operations.

func (*CustomResourceTemplateSource) ResolveGVR added in v0.4.6

ResolveGVR resolves the GroupVersionResource for the CR's GVK using the provided RESTMapper and caches the result.

Behaviour: - Builds the GVK if not already cached. - Calls mapper.RESTMapping(gvk.GroupKind(), gvk.Version). - Returns the resolved GVR or the underlying error from the mapper.

func (*CustomResourceTemplateSource) RuntimeGVK added in v0.4.6

RuntimeGVK returns the cached GVK if present, otherwise builds it.

func (*CustomResourceTemplateSource) RuntimeGVR added in v0.4.6

RuntimeGVR returns the cached GVR if present. If not cached, instructs the caller to call ResolveGVR with a RESTMapper first.

func (*CustomResourceTemplateSource) WithStatus added in v0.4.6

func (c *CustomResourceTemplateSource) WithStatus() bool

WithStatus returns whether Orkestra should attempt to write/patch the resource's status subresource.

Behaviour: - If HasStatus is explicitly set, return that value. - If HasStatus is nil and the user provided a non-empty Status block, return true. - Otherwise return false to indicate runtime discovery should decide.

Callers should treat false as "do not patch status" and rely on discovery to override when HasStatus is nil and the reconciler has discovered the CRD supports a status subresource.

type DayOfWeekCondition

type DayOfWeekCondition struct {
	// In — active on these days. Full English names: Monday, Tuesday, etc.
	In []string `yaml:"in,omitempty" json:"in,omitempty"`

	// NotIn — active on all days except these.
	NotIn []string `yaml:"notIn,omitempty" json:"notIn,omitempty"`
}

DayOfWeekCondition declares which days the condition is active.

type DeleteRequest

type DeleteRequest struct {
	Object         map[string]interface{}
	Declarations   []ProviderDeclaration
	Kube           KubeReader
	Logger         zerolog.Logger
	OwnerName      string
	OwnerNamespace string
}

DeleteRequest carries everything a provider needs for cleanup. Identical shape to ReconcileRequest — separate type for clarity at call sites.

type DeletionProtectionConfig

type DeletionProtectionConfig struct {
	// Enabled controls whether deletion protection is active.
	// Default: true when the deletionProtection block is declared.
	Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`

	// ServiceName is the Kubernetes Service fronting Orkestra's HTTPS server.
	// The API server sends webhook requests to this Service.
	// Default: ORK_SERVICE_NAME env / "orkestra".
	ServiceName string `yaml:"serviceName,omitempty" json:"serviceName,omitempty"`

	// FailurePolicy controls what the API server does when Orkestra is unreachable.
	// "Fail" — reject the DELETE (recommended for protection; this is the default).
	// "Ignore" — allow the DELETE through when Orkestra cannot be reached.
	// Default: "Fail".
	FailurePolicy string `yaml:"failurePolicy,omitempty" json:"failurePolicy,omitempty"`

	// CleanupOnShutdown controls whether Deletion protection webhook is deleted on graceful shutdown.
	// Default: false — Deletion protection webhook persists across restarts.
	CleanupOnShutdown bool `yaml:"cleanupOnShutdown,omitempty" json:"cleanupOnShutdown,omitempty"`

	// StrictMode controls whether removing the deletion-protection label from a resource
	// is itself treated as a deletion attempt and blocked.
	// When true, the only way to remove the label (and thus unprotect a resource) is to
	// disable strictMode in the Katalog and restart Orkestra Gateway.
	// Default: false.
	StrictMode bool `yaml:"strictMode,omitempty" json:"strictMode,omitempty"`
}

DeletionProtectionConfig controls deletion protection behaviour.

type DeletionProtectionOverride added in v0.5.3

type DeletionProtectionOverride struct {
	// ProtectCRD determines whether the CRD definition itself (the type)
	// is protected from deletion. Default true.
	ProtectCRD *bool `yaml:"protectCRD,omitempty" json:"protectCRD,omitempty"`

	// ProtectCRs determines whether instances of this CRD are protected
	// from deletion (via the orkestra.io/deletion-protection label).
	// Default true.
	ProtectCRs *bool `yaml:"protectCRs,omitempty" json:"protectCRs,omitempty"`

	// StrictMode controls whether removing the deletion-protection label from a resource
	// is itself treated as a deletion attempt and blocked.
	// When true, the only way to remove the label (and thus unprotect a resource) is to
	// disable strictMode in the Katalog and restart Orkestra Gateway.
	// Default: katalog level strictMode.
	StrictMode *bool `yaml:"strictMode,omitempty" json:"strictMode,omitempty"`
}

DeletionProtectionOverride controls per‑CRD behaviour when the global security.deletionProtection.enabled is true. Both fields default to true when omitted.

type DependencyCondtion

type DependencyCondtion string

type DependsOnCondition

type DependsOnCondition struct {
	Condition string `yaml:"condition" json:"condition"`
}

DependsOnCondition is the value in the dependsOn map. Condition values: "started" (workers running) or "healthy" (running + consecutive failures = 0).

func (*DependsOnCondition) UnmarshalYAML

func (d *DependsOnCondition) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML handles Format 2 (scalar) and Format 3 (map) for a single dependency value.

database: healthy          ← Format 2: scalar
database:                  ← Format 3: map
  condition: healthy

type DependsOnMap

type DependsOnMap map[string]DependsOnCondition

DependsOnMap is the internal representation of all dependsOn formats. All three YAML formats unmarshal into this type.

func (DependsOnMap) ConditionHealthy

func (m DependsOnMap) ConditionHealthy(name string) bool

ConditionHealthy returns true if the dependency condition is healthy

func (DependsOnMap) ConditionStarted

func (m DependsOnMap) ConditionStarted(name string) bool

ConditionStarted returns true if the dependency condition is started

func (DependsOnMap) Names

func (m DependsOnMap) Names() []string

Names returns the dependency names in sorted order.

func (*DependsOnMap) UnmarshalYAML

func (m *DependsOnMap) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML handles all three dependsOn formats:

Format 1 — list (condition defaults to "started"):
  dependsOn:
    - database

Format 2 — key-value map (condition explicit):
  dependsOn:
    database: healthy

Format 3 — full map:
  dependsOn:
    database:
      condition: healthy

type DeploymentTemplateSource

type DeploymentTemplateSource struct {
	// Version — OrkestraRegistry implementation version to use. Omit for latest.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Name — Deployment and primary container name.
	// Supports template expressions.
	// Default when omitted: "{{ .metadata.name }}-deployment"
	Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"omitempty"`

	// Image — container image. Required (must be declared here or resolvable from CR).
	// Static:  "nginx:1.25"
	// Dynamic: "{{ .spec.image }}"
	Image string `yaml:"image" json:"image" validate:"omitempty"`

	// ImagePullSecrets is an optional list of references to secrets in the same namespace to use
	// for pulling any of the images used by this PodSpec.
	// If specified, these secrets will be passed to individual puller implementations for them to use.
	ImagePullSecrets []string `yaml:"imagePullSecrets,omitempty" json:"imagePullSecrets,omitempty" validate:"omitempty"`

	// Replicas — number of pod replicas as a string.
	// Static:  "3"
	// Dynamic: "{{ .spec.replicas }}"
	// Default: "1"
	Replicas string `yaml:"replicas,omitempty" json:"replicas,omitempty" validate:"omitempty"`

	// Port — primary container port as a string.
	// Static:  "8080"
	// Dynamic: "{{ .spec.port }}"
	// Omit to expose no port.
	Port string `yaml:"port,omitempty" json:"port,omitempty" validate:"omitempty"`

	// Protocol — network protocol for the container port.
	// Accepted values: TCP (default), UDP, SCTP.
	// Omit to use TCP.
	Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty" validate:"omitempty"`

	// Namespace — target namespace for the Deployment.
	// Default when omitted: "{{ .metadata.namespace }}" (same namespace as the CR).
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty" validate:"omitempty"`

	// Labels — applied to the Deployment ObjectMeta and the pod template.
	// Label values support template expressions.
	// Orkestra always adds: managed-by=orkestra, orkestra-owner=<cr-name>
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`

	// Annotations — applied to the Deployment ObjectMeta only.
	// Annotation values support template expressions.
	Annotations []ResourceLabel `yaml:"annotations,omitempty" json:"annotations,omitempty" validate:"omitempty"`

	// Resources — CPU and memory requests/limits for the primary container.
	// Set resources.profile for a named preset, or resources.requests/limits for
	// explicit values. Profile and explicit values are mutually exclusive.
	Resources *ResourceRequirements `yaml:"resources,omitempty" json:"resources,omitempty" validate:"omitempty"`

	// Env — environment variables for the primary container, in Kubernetes-native list format.
	// Each entry has a name and either a value or a valueFrom source.
	// If omitted, no environment variables are added.
	Env EnvVarList `yaml:"env,omitempty" json:"env,omitempty"`

	EnvFrom *EnvFrom `yaml:"envFrom,omitempty" json:"envFrom,omitempty"`

	// NodeSelector is a selector which must be true for the pod to fit on a node.
	// Selector which must match a node's labels for the pod to be scheduled on that node.
	// More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
	// +optional
	// +mapType=atomic
	NodeSelector map[string]string `yaml:"nodeSelector,omitempty" json:"nodeSelector,omitempty"`

	// ServiceAccountName is the name of the ServiceAccount to use to run this pod.
	// More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
	// +optional
	ServiceAccountName string `yaml:"serviceAccountName,omitempty" json:"serviceAccountName,omitempty"`

	// Reconcile: true — also apply this declaration as drift correction on every
	// reconcile. Equivalent to declaring the same entry under both onCreate and
	// onReconcile. When false (default), only runs on onCreate (idempotent create).
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty" validate:"omitempty"`

	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`
	// ForEach declares dynamic expansion over a list field.
	// When set, one source declaration becomes N declarations — one per list element.
	// .item and .<as> are available in template expressions within this declaration.
	ForEach *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// AnyOf holds OR conditions — at least one must pass for this resource to be created.
	// Works alongside the existing Conditions (when:) field which uses AND semantics.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// WorkingDirectory sets the container's working directory (container.WorkingDir).
	// Useful for Git-backed pipelines where build/test commands must run inside
	// a checked-out repository path.
	WorkingDirectory string `yaml:"workingDirectory,omitempty" json:"workingDirectory,omitempty"`

	// Probes — startup, liveness, and readiness probe configuration.
	Probes *ProbesConfig `yaml:"probes,omitempty" json:"probes,omitempty"`

	// SecurityContext — container-level security settings.
	// Set securityContext.profile for a named preset (baseline, restricted, hardened)
	// or declare individual fields. Profile and explicit fields are mutually exclusive.
	SecurityContext *ContainerSecurityContext `yaml:"securityContext,omitempty" json:"securityContext,omitempty"`

	// PodSecurity — pod-level security settings applied to the pod spec.
	// Set podSecurity.profile for a named preset or declare individual fields.
	PodSecurity *PodSecurityContext `yaml:"podSecurity,omitempty" json:"podSecurity,omitempty"`

	// RollingUpdate — rolling update strategy for this Deployment.
	// Set rollingUpdate.profile for a named preset (safe, fast, blue-green),
	// or declare maxSurge/maxUnavailable explicitly.
	// Profile and explicit fields are mutually exclusive.
	RollingUpdate *RollingUpdateBehavior `yaml:"rollingUpdate,omitempty" json:"rollingUpdate,omitempty"`

	// Volumes — pod volumes available for mounting into the container.
	// Supports configMap, secret, emptyDir, persistentVolumeClaim, and hostPath sources.
	// Volume names support template expressions.
	Volumes []VolumeSource `yaml:"volumes,omitempty" json:"volumes,omitempty"`

	// VolumeMounts — mounts for the primary container. Each entry references a
	// volume declared in volumes: by name.
	VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

DeploymentTemplateSource declares one Deployment to be managed by Orkestra.

Declare under onCreate to create the Deployment on first reconcile. This automatically creates onReconcile Declare under onReconcile to apply drift correction on every reconcile. Declare under both to get idempotent creation and drift correction together. Or simply declare under onCreate

Minimal example — static values only:

onCreate:
  deployments:
    - image: nginx:1.25
      replicas: "3"
      port: "8080"
      resources:
        profile: burst      # Use orkestra's burst resource configuration

Full example — dynamic values from the CR:

onCreate:
  deployments:
    - name: "{{ .metadata.name }}-app"
      image: "{{ .spec.image }}"
      replicas: "{{ .spec.replicas }}"
      port: "{{ .spec.port }}"
      namespace: "{{ .metadata.namespace }}"
      labels:
        - key: app
          value: "{{ .metadata.name }}"
        - key: managed-by
          value: orkestra
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 500m
          memory: 512Mi

func (DeploymentTemplateSource) GetName added in v0.4.2

func (t DeploymentTemplateSource) GetName() string

func (DeploymentTemplateSource) GetPodSecurity added in v0.5.4

func (t DeploymentTemplateSource) GetPodSecurity() *PodSecurityContext

GetPodSecurity returns the pod-level security context for each supported workload type.

func (DeploymentTemplateSource) GetProbes added in v0.4.2

func (t DeploymentTemplateSource) GetProbes() *ProbesConfig

GetProbes returns the probe configuration for each supported workload type. Value receivers so the method is available on both values and pointers.

func (DeploymentTemplateSource) GetProtocol added in v0.6.2

func (t DeploymentTemplateSource) GetProtocol() string

func (DeploymentTemplateSource) GetResources added in v0.4.2

GetResources returns the resource requirements for each supported workload type.

func (DeploymentTemplateSource) GetRollingUpdate added in v0.5.4

func (t DeploymentTemplateSource) GetRollingUpdate() *RollingUpdateBehavior

func (DeploymentTemplateSource) GetSecurityContext added in v0.5.4

func (t DeploymentTemplateSource) GetSecurityContext() *ContainerSecurityContext

GetSecurityContext returns the container-level security context for each supported workload type.

func (DeploymentTemplateSource) GetSleep added in v0.4.2

func (t DeploymentTemplateSource) GetSleep() string

Core workload resources

type DockerHookSpec

type DockerHookSpec struct {
	// Image is the fully-qualified image reference to build.
	//
	// Examples:
	//   "registry.example.com/webapp:{{ .git.commit }}"
	//   "ghcr.io/org/service:{{ .status.version }}"
	//
	// This field supports template expressions and is required.
	Image string `yaml:"image" json:"image"`

	// WorkingDirectory is the directory used as the Docker build context.
	//
	// In most cases this is the same as the Git hook's .git.path:
	//   workingDirectory: "{{ .git.path }}"
	//
	// If omitted, Orkestra defaults to the CR's working directory (rarely useful).
	WorkingDirectory string `yaml:"workingDirectory,omitempty" json:"workingDirectory,omitempty"`

	// Dockerfile optionally overrides the Dockerfile path.
	//
	// Examples:
	//   "Dockerfile"
	//   "deploy/Dockerfile.prod"
	//
	// When empty, Orkestra uses "Dockerfile" in the working directory.
	Dockerfile string `yaml:"dockerfile,omitempty" json:"dockerfile,omitempty"`

	// Push controls whether the built image should be pushed to the registry.
	//
	// When true:
	//   • Orkestra executes `docker push <image>` after a successful build.
	//   • Push failures are surfaced via .docker.error.
	//
	// When false:
	//   • The image is built locally only.
	Push bool `yaml:"push,omitempty" json:"push,omitempty"`

	// Builder selects the OCI build tool to use.
	//
	// Supported values: "docker" (default), "kaniko", "buildah", "podman".
	// When empty, Orkestra checks the OCI_BUILDER environment variable,
	// then falls back to "docker".
	//
	// kaniko — builds without a Docker socket; works in any Kubernetes pod.
	// buildah — rootless builds via buildah bud.
	// podman  — local builds via podman build.
	Builder string `yaml:"builder,omitempty" json:"builder,omitempty"`

	// Reconcile controls whether this Docker hook runs on every reconcile.
	//
	// When true:
	//   • Docker build/push runs on every reconcile cycle.
	//   • Useful for Git-driven pipelines where .git.changed triggers rebuilds.
	//
	// When false:
	//   • Docker build/push runs only during onCreate.
	//   • Useful for one-time initialization images.
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty"`

	// ContinueOnError controls behaviour when the Docker build or push fails.
	//
	// false (default) — Docker failure returns an error and halts reconciliation.
	// true            — Docker failure injects .docker.error but reconciliation continues.
	ContinueOnError bool `yaml:"continueOnError,omitempty" json:"continueOnError,omitempty"`

	// When is an optional list of conditions that must all pass before
	// this field is written. If absent or empty, the field is always written.
	//
	// All conditions are AND-ed together.
	// To express OR logic, declare multiple StatusField entries for the same path.
	//
	// Conditions are evaluated against the full CR object map — the same
	// map available to template expressions. This means .status.phase,
	// .spec.image, .children.job.status.succeeded are all accessible.
	When []Condition `yaml:"when,omitempty"`

	AnyOf []Condition `yaml:"anyOf,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

DockerHookSpec declares a Docker build/push operation as part of a lifecycle hook.

This hook allows Orkestra to build container images directly inside the reconcile loop, using the working directory produced by a Git hook or any other source. It behaves similarly to external calls and git hooks — it is a declarative precondition that runs before resource creation.

Typical usage:

operatorBox:
  onReconcile:
    git:
      repo: "git@github.com:org/webapp.git"
      branch: "main"
      path: "services/webapp"
      reconcile: true

    docker:
      image: "registry.example.com/webapp:{{ .git.commit }}"
      workingDirectory: "{{ .git.path }}"
      push: true

    deployments:
      - name: "{{ .metadata.name }}"
        image: "{{ .docker.image }}"

Minimal v1 behaviour:

  • Executes `docker build` using workingDirectory as the build context.
  • Uses Dockerfile in workingDirectory unless overridden.
  • If push=true, executes `docker push` after a successful build.
  • Exposes results to templates under `.docker.*`: .docker.image .docker.buildSucceeded .docker.error
  • No credentials stored in the CRD — authentication is external.
  • No per-reconcile full rebuild unless reconcile=true.
  • No caching or layer reuse guarantees (future versions may add this).

This enables fully declarative CI/CD pipelines where Git → Test → Build → Push → Deploy are all expressed in YAML and executed inside the cluster.

type Duration

type Duration struct {
	time.Duration
}

Duration is a time.Duration that unmarshals from YAML strings like "15s", "2m", "1h".

func (Duration) MarshalYAML

func (d Duration) MarshalYAML() (interface{}, error)

func (*Duration) UnmarshalYAML

func (d *Duration) UnmarshalYAML(unmarshal func(interface{}) error) error

type E2E added in v0.4.8

type E2E struct {
	APIVersion string      `yaml:"apiVersion"`
	Kind       string      `yaml:"kind"`
	Metadata   E2EMeta     `yaml:"metadata"`
	Spec       E2ESpec     `yaml:"spec"`
	Imports    []E2EImport `yaml:"imports,omitempty"`
}

E2E is the top-level document type for declarative end-to-end tests. Committed alongside the katalog, it drives `ork e2e` — the same command that runs locally, in CI, and inside the GitHub Action.

type E2ECluster added in v0.4.8

type E2ECluster struct {
	// Provider is the cluster provider — currently only "kind" is supported.
	Provider string `yaml:"provider"` // default: "kind"
	// Name is the kind cluster name. Default: "ork-e2e".
	Name string `yaml:"name"`
	// Reuse controls whether an existing cluster is reused or recreated.
	// false (default) — delete and recreate for a clean state.
	// true — reuse existing cluster if it exists.
	Reuse bool `yaml:"reuse"`
}

E2ECluster controls cluster creation and selection.

type E2ECommand added in v0.4.8

type E2ECommand struct {
	// Run is a shell command string executed via sh -c.
	Run string `yaml:"run"`
	// ExitCode is the expected exit code. Default 0 (success).
	// Set to non-zero to assert the command must fail — useful for
	// admission webhook rejection tests.
	ExitCode int `yaml:"exitCode,omitempty"`
	// OutputContains asserts the combined stdout+stderr contains this substring.
	OutputContains string `yaml:"outputContains,omitempty"`
}

E2ECommand runs a shell command and asserts its result.

type E2EExpectation added in v0.4.8

type E2EExpectation struct {
	// Name is printed in the results table.
	Name string `yaml:"name"`
	// After triggers the expectation — "cr-applied" or "cr-deleted".
	After string `yaml:"after"`
	// Timeout is the maximum time to wait for the expectation to pass.
	Timeout string `yaml:"timeout"` // e.g. "60s"

	// Resources is a unified list of resource checks across any kind.
	Resources []E2EResourceCheck `yaml:"resources,omitempty"`

	// Commands are shell commands checked in the same polling loop as resources.
	Commands []E2ECommand `yaml:"commands,omitempty"`
}

E2EExpectation is one named assertion block.

type E2EImport added in v0.6.5

type E2EImport struct {
	// Path is the path to another E2E spec file (must be kind: E2E).
	Path string `yaml:"path"`
	// FreshCluster provisions a new kind cluster for this import instead of
	// reusing the parent's cluster. Default: false (share parent cluster).
	FreshCluster bool `yaml:"freshCluster,omitempty"`
	// Wait is an optional duration to sleep before this import starts.
	// Useful when the previous test leaves cluster state that needs time to
	// clear — webhook deregistration, namespace termination, cert provisioning.
	// Must be a valid Go duration string (e.g. "10s", "1m30s").
	Wait string `yaml:"wait,omitempty"`
}

E2EImport references another E2E file to run after this one completes. By default imports share the same cluster. Set freshCluster: true to provision a new cluster for that import instead.

Shorthand — a plain path string is equivalent to {path: <string>}:

imports:
  - ./auth-e2e.yaml
  - ./rbac-e2e.yaml
  - path: ./infra-e2e.yaml
    freshCluster: true

func (*E2EImport) UnmarshalYAML added in v0.6.5

func (i *E2EImport) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML allows imports to be written as a plain string path.

type E2EInit added in v0.4.8

type E2EInit struct {
	Pack    string `yaml:"pack"`
	Example string `yaml:"example"`
}

E2EInit selects a built-in example pack as the test source.

type E2EMeta added in v0.4.8

type E2EMeta struct {
	Name        string `yaml:"name"`
	Description string `yaml:"description,omitempty"`
}

type E2EResourceCheck added in v0.4.8

type E2EResourceCheck struct {
	// Kind is the resource kind: Deployment, Service, Secret, ConfigMap.
	Kind string `yaml:"kind"`
	// Name is the resource name. Empty means any resource of this kind in the namespace.
	Name string `yaml:"name,omitempty"`
	// Namespace to look in. Empty means "default".
	Namespace string `yaml:"namespace,omitempty"`
	// Count asserts the exact number of matching resources. nil means "at least 1".
	// Set to 0 to assert none exist (cleanup check).
	Count *int `yaml:"count,omitempty"`
	// Ready asserts at least one available replica (Deployments only).
	Ready bool `yaml:"ready,omitempty"`
}

E2EResourceCheck asserts the state of any Kubernetes resource. Set kind to: Deployment, Service, Secret, ConfigMap.

type E2ESpec added in v0.4.8

type E2ESpec struct {

	// Katalog is the path to the katalog.yaml file.
	// Optional when customOperator is true.
	Katalog string `yaml:"katalog,omitempty"`
	// CRD is the path to the CRD YAML file for this operator.
	// Applied before the bundle and before Orkestra starts.
	CRD string `yaml:"crd,omitempty"`
	// CR is the path to the CR YAML file to apply during the test.
	CR string `yaml:"cr,omitempty"`

	// CustomOperator declares that this test uses its own operator rather than
	// Orkestra's reconcile loop. Bundle generation and Orkestra helm install/uninstall
	// are skipped. Everything else runs unchanged: cluster setup, CRD apply, setup
	// manifests, CR apply, assertions, and cleanup.
	//
	// Use this when your operator is installed via setup.helm or is already present
	// in the cluster. See documentation/reference/schema/04-e2e/05-custom-operator.md.
	CustomOperator bool `yaml:"customOperator,omitempty"`

	// Init uses an example pack — for Orkestra's own CI.
	Init *E2EInit `yaml:"init,omitempty"`

	// Cluster controls which cluster to use.
	Cluster E2ECluster `yaml:"cluster"`

	// Setup declares prerequisite resources to apply before Orkestra starts.
	// Shorthand: a plain list of strings applies each file (backward compatible).
	// Struct form adds helm installs and resource waiting.
	Setup *SetupConfig `yaml:"setup,omitempty"`

	// Expect is the list of expectations to check after each lifecycle event.
	Expect []E2EExpectation `yaml:"expect"`
}

type EmptyDirVolumeSource added in v0.6.2

type EmptyDirVolumeSource struct{}

EmptyDirVolumeSource is an ephemeral empty directory. Use `{}` in YAML.

type EndpointsConfig

type EndpointsConfig struct {
	// Enabled if false disables all endpoints for this CRD
	// Default is true
	Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`

	// Health controls whether the /health endpoint is served.
	Health *bool `yaml:"health,omitempty" json:"health,omitempty"`

	// Info controls whether the /info endpoint is served.
	Info *bool `yaml:"info,omitempty" json:"info,omitempty"`
}

EndpointsConfig controls which HTTP endpoints are exposed by the operator.

This allows users to selectively enable/disable endpoints while keeping the configuration minimal and declarative.

type EnrichTarget added in v0.6.0

type EnrichTarget struct {
	// Key is the enrichment target name (pods, events, pvcs, etc.)
	Key string

	// When gates this enrichment using AND semantics. Template expressions
	// in field: values are evaluated against the resolver's full data map
	// so all note functions (replicasReady, hasCrashingPod, …) are available.
	// Empty: always enriches (same as shorthand).
	When  []Condition `yaml:"when,omitempty"`
	AnyOf []Condition `yaml:"anyOf,omitempty"`
}

EnrichTarget is one enrichment declaration in a CRD's enrich: list.

Shorthand (always enriches):

enrich:
  - pods

Struct form (conditional enrichment):

enrich:
  - events:
      when:
        - field: "{{ replicasReady .children.deployment }}"
          equals: "false"
  - replicasets:
      anyOf:
        - field: spec.debug
          equals: "true"

func (EnrichTarget) MarshalYAML added in v0.6.0

func (e EnrichTarget) MarshalYAML() (interface{}, error)

MarshalYAML serializes back to the shorthand form when there are no conditions, and to the struct form when conditions are present.

func (*EnrichTarget) UnmarshalYAML added in v0.6.0

func (e *EnrichTarget) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML handles both shorthand ("pods") and struct form:

  • pods → EnrichTarget{Key: "pods"}
  • events: → EnrichTarget{Key: "events", When: [...]} when: [...]

type EnrichmentOutcome

type EnrichmentOutcome int

EnrichmentOutcome describes what happened when enrichment was attempted for a CRD entry. Used by ork validate to print clear, actionable output.

const (
	// EnrichmentNotNeeded — apiTypes is already fully specified
	EnrichmentNotNeeded EnrichmentOutcome = iota

	// EnrichmentApplied — kind-only declaration resolved to a built-in
	EnrichmentApplied

	// EnrichmentFailed — kind-only declaration did not match any built-in
	// and apiTypes is incomplete
	EnrichmentFailed
)

type EnvFrom added in v0.4.7

type EnvFrom struct {
	SecretRef    []string `yaml:"secretRef,omitempty" json:"secretRef,omitempty"`
	ConfigMapRef []string `yaml:"configMapRef,omitempty" json:"configMapRef,omitempty"`
}

EnvFrom groups environment sources by type.

type EnvVar added in v0.3.9

type EnvVar struct {
	Name      string     `yaml:"name" json:"name"`
	Value     string     `yaml:"value,omitempty" json:"value,omitempty"`
	ValueFrom *ValueFrom `yaml:"valueFrom,omitempty" json:"valueFrom,omitempty"`
}

EnvVar is a single container environment variable in Kubernetes-native format.

type EnvVarList added in v0.4.7

type EnvVarList []EnvVar

EnvVarList is a []EnvVar with a custom YAML unmarshaller that detects the legacy map format (KEY:\n value: VAL) and returns a clear migration error.

func (*EnvVarList) UnmarshalYAML added in v0.4.7

func (l *EnvVarList) UnmarshalYAML(value *yaml.Node) error

type ExternalCallResult

type ExternalCallResult struct {
	// Status is the HTTP status code as a string ("200", "404", "503").
	// Empty string when the call failed before receiving a response.
	Status string `json:"status" yaml:"status"`

	// Body is the first 4096 bytes of the response body.
	// Truncated to avoid unbounded memory use.
	Body string `json:"body" yaml:"body"`

	// Error is the error message when the call failed.
	// Empty on success.
	Error string `json:"error" yaml:"error"`

	// Called is "true" when the call was made, "false" when skipped (conditions failed).
	Called string `json:"called" yaml:"called"`

	// Additional values for metrics
	StatusCode      int     `json:"statusCode" yaml:"statusCode"`
	DurationSeconds float64 `json:"durationSeconds" yaml:"durationSeconds"`
}

ExternalCallResult is the result of one HTTP call, injected into the resolver context under .external.<name>.

type ExternalCallSpec

type ExternalCallSpec struct {
	// Name is the identifier used to access the result in template expressions.
	//   name: health-check → {{ .external.health-check.status }}
	Name string `yaml:"name" json:"name"`

	// URL is the endpoint to call. Template expressions are supported.
	//   url: "{{ .spec.serviceUrl }}/health"
	//   url: "https://api.example.com/resources/{{ .metadata.name }}"
	URL string `yaml:"url" json:"url"`

	// Method is the HTTP method. Default: GET.
	Method string `yaml:"method,omitempty" json:"method,omitempty"`

	// Body is the request body for POST/PUT/PATCH requests.
	// Template expressions supported.
	//   body: '{"name": "{{ .metadata.name }}"}'
	Body string `yaml:"body,omitempty" json:"body,omitempty"`

	// Token is a bearer token for Authorization header.
	// Use $ENV_VAR syntax to reference environment variables:
	//   token: "$API_TOKEN"
	Token string `yaml:"token,omitempty" json:"token,omitempty"`

	// Headers are additional HTTP headers to include.
	Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty"`

	// Timeout is the maximum duration for this call.
	// Default: 10s. Format: "5s", "1m", "500ms"
	Timeout string `yaml:"timeout,omitempty" json:"timeout,omitempty"`

	// ExpectedStatus is the HTTP status code that signals success.
	// Default: any 2xx status.
	// When set to 200, any non-200 response is treated as a failure.
	ExpectedStatus int `yaml:"expectedStatus,omitempty" json:"expectedStatus,omitempty"`

	// ContinueOnError controls whether a failed call halts reconciliation.
	// false (default): a call failure returns an error, halting the reconcile.
	// true:            failure is logged, result has error set, reconcile continues.
	//
	// Use true for optional calls: notifications, metrics, feature flags.
	// Use false (default) for required calls: health checks, dependency readiness.
	ContinueOnError bool `yaml:"continueOnError,omitempty" json:"continueOnError,omitempty"`

	// When conditions gate this call — if conditions fail, the call is skipped.
	// The result is not injected when skipped.
	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`
	AnyOf      []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

ExternalCallSpec declares one HTTP call to make before resource reconciliation.

type FileSource

type FileSource struct {
	// URL or path — the file to load.
	// May be a local path, an HTTP(S) URL, or an $ENV_VAR reference.
	URL string `yaml:"url"`

	// Auth — optional authentication for remote sources.
	// Ignored for local paths.
	Auth *FileSourceAuth `yaml:"auth,omitempty"`
}

FileSource represents one file source entry. Supports both simple string form (just a path) and authenticated form.

YAML unmarshalling handles both forms transparently via UnmarshalYAML. Users can write either:

files:
  - ./simple/path.yaml               # simple form
  - url: https://private/katalog.yaml # authenticated form
    auth:
      type: bearer
      fromEnv: MY_TOKEN

func (*FileSource) UnmarshalYAML

func (f *FileSource) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML allows FileSource to be declared as either a plain string or a struct with url and auth fields.

Plain string:

Struct with auth:

type FileSourceAuth

type FileSourceAuth struct {
	// Type — authentication scheme.
	// Supported values: "bearer", "github", "basic"
	Type string `yaml:"type" validate:"required,oneof=bearer github basic"`

	// FromEnv — environment variable containing the bearer token or GitHub token.
	// Used when Type is "bearer" or "github".
	FromEnv string `yaml:"fromEnv,omitempty"`

	// UsernameFromEnv — environment variable containing the username.
	// Used when Type is "basic".
	UsernameFromEnv string `yaml:"usernameFromEnv,omitempty"`

	// PasswordFromEnv — environment variable containing the password.
	// Used when Type is "basic".
	PasswordFromEnv string `yaml:"passwordFromEnv,omitempty"`
}

FileSourceAuth declares how to authenticate when fetching a remote source. All credential values are resolved from environment variables at load time — credentials never appear as literal values in the Katalog YAML.

func (*FileSourceAuth) Resolve

func (a *FileSourceAuth) Resolve() (*utils.FileAuth, error)

Resolve resolves the FileSourceAuth to a utils.FileAuth. Reads environment variables and returns the resolved credentials. Returns nil if the auth block is nil (unauthenticated source).

type ForEachSpec

type ForEachSpec struct {
	// Field is the dot-notation path to a list or map field on the CR.
	//
	// List field → one item per element:
	//   field: spec.regions  → ["us-east-1", "eu-west-1"]
	//   .item = element value ("us-east-1")
	//
	// Map field → one item per key (sorted alphabetically):
	//   field: spec.regions  → {us-east-1: {replicas: 3}, eu-west-1: {replicas: 1}}
	//   .item = map key ("us-east-1"), .value = map value ({replicas: 3})
	//   .value.replicas = "3"
	Field string `yaml:"field" json:"field"`

	// As is the name used to access the current item in template expressions.
	// Default: "item" — {{ .item }}
	// When set: both {{ .item }} and {{ .<as> }} work.
	//   as: region → {{ .region }} and {{ .item }} both resolve to the current element
	As string `yaml:"as,omitempty" json:"as,omitempty"`
}

ForEachSpec declares dynamic expansion over a list or map field.

type GatewayConfig added in v0.4.9

type GatewayConfig struct {
	// Enabled declares whether the gateway should be installed for this katalog.
	// When true, this means:
	//   - Helm installation was done with '--set gateway.enabled=true'
	//   - The runtime expects a gateway to exist
	// Default: false.
	Enabled bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`

	// Standalone declares that this Katalog is deployed as a gateway-only installation
	// with no companion runtime operator. When true:
	//   - gatewayEndpoint validation is skipped (the gateway is self-contained)
	//   - spec: may be empty (no CRDs required)
	// Default: false.
	Standalone bool `yaml:"standalone,omitempty" json:"standalone,omitempty"`

	// Endpoint is the HTTP base URL of the gateway, used by the runtime to locate it.
	// Leave empty in standalone deployments.
	Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"`
}

GatewayConfig declares how the Orkestra gateway is deployed for this Katalog.

YAML shape:

gateway:
  enabled: true     # explicitly enable gateway installation
  standalone: true  # gateway runs without a companion runtime operator
  endpoint: ""      # leave empty when standalone; sets this when paired with runtime

type GitHookSpec

type GitHookSpec struct {
	// Repo is the Git repository URL.
	Repo string `yaml:"repo" json:"repo"`

	// Branch is the branch to track. Default: "main".
	Branch string `yaml:"branch,omitempty" json:"branch,omitempty"`

	// Path optionally scopes change detection to a subdirectory.
	Path string `yaml:"path,omitempty" json:"path,omitempty"`

	// Reconcile controls whether this Git hook runs on every reconcile.
	//
	// When true:
	//   • Git fetch runs on every reconcile cycle.
	//   • `.git.changed` is updated accordingly.
	//
	// When false:
	//   • Git runs only on onCreate.
	//   • Useful for one-time initialization.
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty"`

	// ContinueOnError controls behaviour when the Git operation fails.
	//
	// false (default) — Git failure returns an error and halts reconciliation.
	// true            — Git failure injects .git.error but reconciliation continues.
	//                   Subsequent when: conditions on git.changed will not fire.
	ContinueOnError bool `yaml:"continueOnError,omitempty" json:"continueOnError,omitempty"`

	// When is an optional list of conditions that must all pass before
	// this field is written. If absent or empty, the field is always written.
	//
	// All conditions are AND-ed together.
	// To express OR logic, declare multiple StatusField entries for the same path.
	//
	// Conditions are evaluated against the full CR object map — the same
	// map available to template expressions. This means .status.phase,
	// .spec.image, .children.job.status.succeeded are all accessible.
	When []Condition `yaml:"when,omitempty"`

	AnyOf []Condition `yaml:"anyOf,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

Git declares a Git-backed trigger for this lifecycle hook.

When configured, Orkestra performs a lightweight Git checkout or update before evaluating the rest of the hook. The result is exposed to templates under `.git`:

.git.commit     — latest commit hash
.git.changed    — "true" if the commit changed since last reconcile
.git.path       — absolute path to the working directory

This enables declarative, in-cluster CI/CD pipelines where Git acts as the source of build/test/deploy logic.

Minimal v1 behaviour:

  • On first reconcile: clone repo into a per-CRD working directory.
  • On subsequent reconciles: fetch + fast-forward.
  • If HEAD changed: mark `.git.changed = "true"`.
  • No per-reconcile full clone.
  • No credentials stored in CRD.
  • No aggressive polling — relies on CRD-level resync.

Future versions may add shallow clones, webhook triggers, caching, subdirectory diffing, and credential sources without breaking this contract.

type HPABehavior added in v0.5.4

type HPABehavior struct {
	// Profile — named behavior preset. Expands into scaleUp, scaleDown, and
	// targetCPUUtilizationPercentage at katalog load time.
	// Allowed: web, api, latency-sensitive, batch, cost-optimized.
	Profile string `yaml:"profile,omitempty" json:"profile,omitempty"`

	// ScaleUp — controls how aggressively the HPA adds replicas.
	ScaleUp *HPAScalingRules `yaml:"scaleUp,omitempty" json:"scaleUp,omitempty"`

	// ScaleDown — controls how conservatively the HPA removes replicas.
	ScaleDown *HPAScalingRules `yaml:"scaleDown,omitempty" json:"scaleDown,omitempty"`
}

HPABehavior configures scale-up and scale-down behavior for a HorizontalPodAutoscaler. Set profile for a complete preset, or configure scaleUp/scaleDown explicitly. Profile and explicit fields are mutually exclusive.

type HPAProfileEntry added in v0.5.4

type HPAProfileEntry struct {
	Phase        string // "onCreate", "onReconcile", "onDelete"
	ResourceName string // HPA name template (may be empty)
	Profile      string // raw profile name as written in the katalog
	Mixed        bool   // true when profile is set alongside explicit scaleUp or scaleDown
}

HPAProfileEntry describes a single behavior.profile reference found in an HPATemplateSource. Used by katalog validation to fail fast on unknown profiles and to enforce mutual exclusivity with explicit scaleUp/scaleDown fields.

type HPAScalingPolicy added in v0.5.4

type HPAScalingPolicy struct {
	// Type — "Pods" (absolute count) or "Percent" (percentage of current replicas).
	Type string `yaml:"type" json:"type"`

	// Value — number of pods or percentage to scale per period.
	Value int32 `yaml:"value" json:"value"`

	// PeriodSeconds — time window for this policy (15–1800).
	PeriodSeconds int32 `yaml:"periodSeconds" json:"periodSeconds"`
}

HPAScalingPolicy declares a single scaling action per period.

type HPAScalingRules added in v0.5.4

type HPAScalingRules struct {
	// StabilizationWindowSeconds — how long the HPA observes metrics before acting.
	// Prevents flapping. ScaleDown default: 300s. ScaleUp default: 0s.
	StabilizationWindowSeconds int32 `yaml:"stabilizationWindowSeconds,omitempty" json:"stabilizationWindowSeconds,omitempty"`

	// Policies — one or more scaling policies evaluated each interval.
	// The winning policy is selected by SelectPolicy.
	Policies []HPAScalingPolicy `yaml:"policies,omitempty" json:"policies,omitempty"`

	// SelectPolicy — how to choose among policies when multiple apply.
	// "Max" (default for scaleUp), "Min" (default for scaleDown), or "Disabled".
	SelectPolicy string `yaml:"selectPolicy,omitempty" json:"selectPolicy,omitempty"`
}

HPAScalingRules configures one scaling direction (up or down).

type HPATemplateSource added in v0.1.9

type HPATemplateSource struct {
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// Name — HPA resource name. Default: "{{ .metadata.name }}-hpa"
	Name string `yaml:"name,omitempty" json:"name,omitempty"`

	// Namespace — target namespace. Default: CR namespace.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`

	// ScaleTargetRef — the target workload this HPA scales.
	// Supports Deployment, ReplicaSet, StatefulSet, or any scalable resource.
	// Supports template expressions: "{{ .metadata.name }}"
	ScaleTargetRef ScaleTargetRef `yaml:"scaleTargetRef,omitempty" json:"scaleTargetRef,omitempty"`

	// MinReplicas — minimum replica count as a string. Supports template expressions.
	MinReplicas string `yaml:"minReplicas,omitempty" json:"minReplicas,omitempty"`

	// MaxReplicas — maximum replica count as a string. Supports template expressions.
	MaxReplicas string `yaml:"maxReplicas,omitempty" json:"maxReplicas,omitempty"`

	// TargetCPUUtilizationPercentage — CPU utilization target (0-100). Supports templates.
	// When behavior.profile is set and this field is empty, the profile provides the default.
	TargetCPUUtilizationPercentage string `yaml:"targetCPUUtilizationPercentage,omitempty" json:"targetCPUUtilizationPercentage,omitempty"`

	// Behavior — scale-up and scale-down behavior configuration.
	// Set profile for a complete preset, or configure scaleUp/scaleDown explicitly.
	// Profile and explicit fields are mutually exclusive.
	Behavior *HPABehavior `yaml:"behavior,omitempty" json:"behavior,omitempty"`

	// Labels applied to HPA metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty"`

	Reconcile  bool         `yaml:"reconcile,omitempty" json:"reconcile,omitempty"`
	Conditions []Condition  `yaml:"when,omitempty" json:"when,omitempty"`
	AnyOf      []Condition  `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`
	ForEach    *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

HPATemplateSource declares one HorizontalPodAutoscaler to be managed by Orkestra.

Example:

onReconcile:
  hpa:
    - name: "{{ .metadata.name }}-hpa"
      deploymentRef: "{{ .metadata.name }}"
      minReplicas: "{{ .spec.minReplicas }}"
      maxReplicas: "{{ .spec.maxReplicas }}"
      targetCPUUtilizationPercentage: "80"
      forEach:
        field: spec.services
        as: item

func (HPATemplateSource) GetHPABehavior added in v0.5.4

func (t HPATemplateSource) GetHPABehavior() *HPABehavior

func (HPATemplateSource) GetName added in v0.4.2

func (t HPATemplateSource) GetName() string

func (HPATemplateSource) GetSleep added in v0.4.2

func (t HPATemplateSource) GetSleep() string

Autoscaling, disruption, scheduling

type HelmSource

type HelmSource struct {
	// Repo — Helm repository URL.
	// e.g. "https://charts.myorg.io"
	Repo string `yaml:"repo" validate:"required"`

	// Chart — chart name within the repository.
	// e.g. "platform-crds"
	Chart string `yaml:"chart" validate:"required"`

	// Version — chart version to use. Required for reproducibility.
	// And also used as git ref
	// e.g. "1.2.0"
	Version string `yaml:"version" validate:"required"`

	// Path — chart path within git repo
	Path string `yaml:"path"       validate:"omitempty"`

	// ValueFiles — list of values files to apply when rendering the chart.
	// Each entry can be a local path or a remote URL.
	// Supports environment variable references: $MY_VALUES_FILE
	// Applied in order — later files override earlier ones (same as helm -f).
	ValueFiles []string `yaml:"valueFiles,omitempty"`

	// Values — inline key-value pairs applied after valueFiles.
	// Same as helm --set key=value.
	Values map[string]interface{} `yaml:"values,omitempty"`
}

HelmSource declares a Helm chart that produces Katalog CRD definitions. The chart must render at least one template with kind: Katalog.

Example chart template (templates/katalog.yaml):

apiVersion: orkestra.orkspace.io/v1
kind: Katalog
spec:
  crds:
    {{- range .Values.crds }}
    - name: {{ .name }}
      enabled: {{ .enabled }}
      ...
    {{- end }}

type HookDeclaration

type HookDeclaration struct {
	// Location — fully qualified Go import path. Local or remote module.
	// e.g. "github.com/myorg/hooks" or "github.com/orkspace/orkestra/pkg/reconciler/hooks"
	Location string `yaml:"location" json:"location" validate:"required"`

	// Version — optional module version to pin for this hook.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Fetch — when true, ork generate will run:
	// `go get <location>@<version>` to fetch the requested version.
	Fetch bool `yaml:"fetch,omitempty" json:"fetch,omitempty"`

	// Function — exported function name at Location that returns hooks.
	// e.g. "ProjectHooks"
	Function string `yaml:"function" json:"function" validate:"required"`

	// Alias — Go import alias. Optional, auto-derived from Location if omitted.
	// e.g. "projecthooks"
	Alias string `yaml:"alias,omitempty" json:"alias,omitempty" validate:"omitempty"`

	// Resources — Kubernetes resource types this hook manages (used for RBAC generation).
	Resources []ManagedResource `json:"resources,omitempty" yaml:"resources,omitempty"`
}

HookDeclaration declares where a Go hook function lives. Read by ork generate to emit HookRegistry entries in zz_generated_runtime_registry.go. The declared function must match the signature: func() domain.AnyReconcileHooks

type HookTemplates

type HookTemplates struct {
	Deployments              []DeploymentTemplateSource     `yaml:"deployments,omitempty" json:"deployments,omitempty" validate:"omitempty"`
	ReplicaSets              []ReplicaSetTemplateSource     `yaml:"replicaSets,omitempty" json:"replicaSets,omitempty" validate:"omitempty"`
	Services                 []ServiceTemplateSource        `yaml:"services,omitempty" json:"services,omitempty" validate:"omitempty"`
	Pods                     []PodTemplateSource            `yaml:"pods,omitempty" json:"pods,omitempty" validate:"omitempty"`
	Jobs                     []JobTemplateSource            `yaml:"jobs,omitempty" json:"jobs,omitempty" validate:"omitempty"`
	CronJobs                 []CronJobTemplateSource        `yaml:"cronJobs,omitempty" json:"cronJobs,omitempty" validate:"omitempty"`
	Secrets                  []SecretTemplateSource         `yaml:"secrets,omitempty" json:"secrets,omitempty" validate:"omitempty"`
	ConfigMaps               []ConfigMapTemplateSource      `yaml:"configMaps,omitempty" json:"configMaps,omitempty" validate:"omitempty"`
	ServiceAccounts          []ServiceAccountTemplateSource `yaml:"serviceAccounts,omitempty" json:"serviceAccounts,omitempty" validate:"omitempty"`
	StatefulSets             []StatefulSetTemplateSource    `yaml:"statefulSets,omitempty" json:"statefulSets,omitempty" validate:"omitempty"`
	Ingresses                []IngressTemplateSource        `yaml:"ingresses,omitempty" json:"ingresses,omitempty" validate:"omitempty"`
	PersistentVolumes        []PVTemplateSource             `yaml:"persistentVolumes,omitempty" json:"persistentVolumes,omitempty" validate:"omitempty"`
	PersistentVolumeClaims   []PVCTemplateSource            `yaml:"persistentVolumeClaims,omitempty" json:"persistentVolumeClaims,omitempty" validate:"omitempty"`
	HorizontalPodAutoscalers []HPATemplateSource            `yaml:"hpa,omitempty" json:"hpa,omitempty" validate:"omitempty"`
	PodDisruptionBudgets     []PDBTemplateSource            `yaml:"pdb,omitempty" json:"pdb,omitempty" validate:"omitempty"`
	Namespaces               []NamespaceTemplateSource      `yaml:"namespaces,omitempty" json:"namespaces,omitempty" validate:"omitempty"`
	Roles                    []RoleTemplateSource           `yaml:"roles,omitempty" json:"roles,omitempty" validate:"omitempty"`
	RoleBindings             []RoleBindingTemplateSource    `yaml:"roleBindings,omitempty" json:"roleBindings,omitempty" validate:"omitempty"`
	CustomResource           []CustomResourceTemplateSource `yaml:"custom,omitempty" json:"custom,omitempty" validate:"omitempty"`

	// External declares HTTP calls to make before resource creation.
	// Results available as .external.<n>.status, .body, .error
	External []ExternalCallSpec `yaml:"external,omitempty" json:"external,omitempty"`

	// Git declares optional Git-backed reconcile behaviour for this CRD.
	//
	// When configured, Orkestra:
	//   - Maintains a local working copy of the repository.
	//   - Periodically checks the target branch for new commits.
	//   - Enqueues reconciles for all CRs of this type when the branch tip changes.
	//
	// This enables declarative, in-cluster CI/CD pipelines where Git acts
	// as the source of pipeline logic and the CRs provide parameters.
	//
	// When omitted, reconcile behaviour is unchanged and no Git traffic
	// is generated for this CRD.
	Git *GitHookSpec `yaml:"git,omitempty" json:"git,omitempty"`

	// Docker declares optional Docker-backed reconcile behaviour for this CRD.
	//
	// When configured
	//	- Builds and optionally pushes a docker image
	Docker *DockerHookSpec `yaml:"docker,omitempty" json:"docker,omitempty"`

	// Ordered controls whether deletion happens sequentially with verification.
	// true  — delete groups in order, verify each is gone before proceeding
	// false — delete all resources via owner references (default, parallel)
	Ordered bool `yaml:"ordered,omitempty" json:"ordered,omitempty"`

	// Groups declares sequential deletion stages for ordered deletes.
	// Each element is a full HookTemplates block whose resources are deleted
	// as a unit. Orkestra deletes stage N, waits until all resources are gone,
	// then deletes stage N+1. Omit when Ordered is false.
	// When Ordered is true and Groups is empty, the flat resource fields above
	// (Jobs, Deployments, …) are treated as a single implicit group.
	Groups []HookTemplates `yaml:"groups,omitempty" json:"groups,omitempty"`

	// Timeout is the maximum time to wait for each deletion group to complete.
	// Defaults to 5m when Ordered is true. Ignored when Ordered is false.
	Timeout *Duration `yaml:"timeout,omitempty" json:"timeout,omitempty"`

	// TODO with placeholer
	Volumes                     []PlaceholderSource `yaml:"volumes,omitempty" json:"volumes,omitempty" validate:"omitempty"`
	VolumeMounts                []PlaceholderSource `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty" validate:"omitempty"`
	ClusterRoles                []PlaceholderSource `yaml:"clusterRoles,omitempty" json:"clusterRoles,omitempty" validate:"omitempty"`
	ClusterRoleBindings         []PlaceholderSource `yaml:"clusterRoleBindings,omitempty" json:"clusterRoleBindings,omitempty" validate:"omitempty"`
	ServiceMonitors             []PlaceholderSource `yaml:"serviceMonitors,omitempty" json:"serviceMonitors,omitempty" validate:"omitempty"`
	PodSecurityPolicies         []PlaceholderSource `yaml:"podSecurityPolicies,omitempty" json:"podSecurityPolicies,omitempty" validate:"omitempty"`
	PriorityClasses             []PlaceholderSource `yaml:"priorityClasses,omitempty" json:"priorityClasses,omitempty" validate:"omitempty"`
	LimitRanges                 []PlaceholderSource `yaml:"limitRanges,omitempty" json:"limitRanges,omitempty" validate:"omitempty"`
	ResourceQuotas              []PlaceholderSource `yaml:"resourceQuotas,omitempty" json:"resourceQuotas,omitempty" validate:"omitempty"`
	RuntimeClasses              []PlaceholderSource `yaml:"runtimeClasses,omitempty" json:"runtimeClasses,omitempty" validate:"omitempty"`
	PriorityLevelConfigurations []PlaceholderSource `yaml:"priorityLevelConfigurations,omitempty" json:"priorityLevelConfigurations,omitempty" validate:"omitempty"`
	PodTemplates                []PlaceholderSource `yaml:"podTemplates,omitempty" json:"podTemplates,omitempty" validate:"omitempty"`
	DaemonSets                  []PlaceholderSource `yaml:"daemonSets,omitempty" json:"daemonSets,omitempty" validate:"omitempty"`
	NetworkPolicies             []PlaceholderSource `yaml:"networkPolicies,omitempty" json:"networkPolicies,omitempty" validate:"omitempty"`

	// Storage
	StorageClasses   []PlaceholderSource `yaml:"storageClasses,omitempty" json:"storageClasses,omitempty" validate:"omitempty"`
	StorageLocations []PlaceholderSource `yaml:"storageLocations,omitempty" json:"storageLocations,omitempty" validate:"omitempty"`
	StoragePools     []PlaceholderSource `yaml:"storagePools,omitempty" json:"storagePools,omitempty" validate:"omitempty"`
	StorageBackups   []PlaceholderSource `yaml:"storageBackups,omitempty" json:"storageBackups,omitempty" validate:"omitempty"`
	StorageSnapshots []PlaceholderSource `yaml:"storageSnapshots,omitempty" json:"storageSnapshots,omitempty" validate:"omitempty"`
	StorageVolumes   []PlaceholderSource `yaml:"storageVolumes,omitempty" json:"storageVolumes,omitempty" validate:"omitempty"`
}

── HookTemplates ───────────────────────────────────────────────────────────── Declares the complete set of resources Orkestra manages at each lifecycle event. All resource type slices are optional — omit any type you do not need. Resources not declared in HookTemplates are never created, updated, or deleted by Orkestra — they are invisible to the reconciler.

All resources created via hook templates receive owner references pointing to the CR. This means Kubernetes garbage collection handles deletion automatically when the CR is deleted — no onDelete declaration is needed for cleanup in most cases.

Lifecycle events:

onCreate
  Runs on every reconcile. Create calls are idempotent — if the resource
  already exists it is skipped without error.
  Declare all long-lived child resources here.
  Resources are created in the order declared within each type slice.

onReconcile
  Runs on every reconcile, after onCreate.
  Use for drift correction — re-applies desired state when child resources
  have been manually modified, scaled, or deleted outside of Orkestra.
  Omit entirely if onCreate alone is sufficient (no drift correction needed).

onDelete
  Runs when the CR has a DeletionTimestamp set, before Orkestra removes finalizers.
  Use only for resources that need explicit cleanup beyond owner references:
    - External resources not in Kubernetes (cloud provider APIs, DNS records, etc.)
    - Jobs that must complete successfully before the CR can be considered deleted
    - Notification or archival tasks that must run before deletion is finalized

func (HookTemplates) FilterResources added in v0.6.4

func (h HookTemplates) FilterResources(fn func(conditions, anyOf []Condition) (keep bool, newConditions, newAnyOf []Condition)) HookTemplates

FilterResources returns a new HookTemplates containing only the resources that pass fn, with their conditions updated to whatever fn returns.

fn receives the current (conditions, anyOf) for a resource and returns:

  • keep: whether to include the resource in the output
  • conditions: the conditions to set on the kept resource
  • anyOf: the anyOf conditions to set on the kept resource

Callers use this to separate motif-time static conditions (evaluated now) from runtime conditions (preserved on the resource for the reconciler).

External calls are copied unchanged — their when: conditions are always runtime conditions evaluated by the reconciler, never by the expander.

func (HookTemplates) IsEmpty added in v0.4.3

func (h HookTemplates) IsEmpty() bool

IsEmpty reports whether this HookTemplates has no resource declarations.

func (*HookTemplates) MergeFrom added in v0.6.4

func (h *HookTemplates) MergeFrom(src *HookTemplates)

MergeFrom appends all resources from src into h.

func (*HookTemplates) VisitResources added in v0.4.2

func (h *HookTemplates) VisitResources(fn func(res interface{}))

VisitResources calls fn for every resource template in this HookTemplates. It abstracts over all resource slices (Deployments, Services, Jobs, etc.) so callers can perform generic operations like detecting Sleep, validating fields, or scanning for managed-resource contracts.

type HostPathVolumeSource added in v0.6.2

type HostPathVolumeSource struct {
	// Path — path on the host.
	Path string `yaml:"path" json:"path"`

	// Type — optional host path type. Values: DirectoryOrCreate, Directory,
	// FileOrCreate, File, Socket, CharDevice, BlockDevice.
	// Default: no type check.
	Type string `yaml:"type,omitempty" json:"type,omitempty"`
}

HostPathVolumeSource mounts a path from the host node.

type IngressTLSSpec added in v0.1.9

type IngressTLSSpec struct {
	// Create — when true, create a TLS secret and populate ingress.spec.tls.
	Create bool `yaml:"create,omitempty" json:"create,omitempty"`

	// SecretName — name of the TLS secret. Supports template expressions.
	// Default: "{{ .metadata.name }}-tls"
	SecretName string `yaml:"secretName,omitempty" json:"secretName,omitempty"`

	// Hosts — list of hostnames to include in the TLS certificate SANs.
	// Each element supports template expressions.
	Hosts []string `yaml:"hosts,omitempty" json:"hosts,omitempty"`

	// ValidFor — certificate validity duration (e.g. "1y", "90d"). Default: "1y".
	ValidFor string `yaml:"validFor,omitempty" json:"validFor,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

IngressTLSSpec configures TLS for an Ingress resource. When Create is true, Orkestra generates a kubernetes.io/tls Secret before the Ingress is applied so the Ingress can reference it immediately.

type IngressTemplateSource added in v0.1.9

type IngressTemplateSource struct {
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// Name — Ingress resource name. Default: "{{ .metadata.name }}-ingress"
	Name string `yaml:"name,omitempty" json:"name,omitempty"`

	// Namespace — target namespace. Default: CR namespace.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`

	// Host — virtual host name for the Ingress rule.
	Host string `yaml:"host,omitempty" json:"host,omitempty"`

	// ServiceName — backend Service name this Ingress routes to.
	ServiceName string `yaml:"serviceName,omitempty" json:"serviceName,omitempty"`

	// ServicePort — backend Service port as a string. Supports template expressions.
	ServicePort string `yaml:"servicePort,omitempty" json:"servicePort,omitempty"`

	// Path — HTTP path prefix. Default: "/"
	Path string `yaml:"path,omitempty" json:"path,omitempty"`

	// PathType — Kubernetes IngressPathType: Prefix, Exact, ImplementationSpecific.
	// Default: Prefix.
	PathType string `yaml:"pathType,omitempty" json:"pathType,omitempty"`

	// IngressClass — Ingress class name (nginx, traefik, etc.). Optional.
	IngressClass string `yaml:"className,omitempty" json:"className,omitempty"`

	// Labels applied to Ingress metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty"`

	// Annotations applied to Ingress metadata. Values support template expressions.
	Annotations []ResourceLabel `yaml:"annotations,omitempty" json:"annotations,omitempty"`

	// TLS — optional TLS configuration. When tls.enabled is true, Orkestra
	// generates a self-signed TLS Secret before creating the Ingress.
	TLS *IngressTLSSpec `yaml:"tls,omitempty" json:"tls,omitempty"`

	Reconcile  bool         `yaml:"reconcile,omitempty" json:"reconcile,omitempty"`
	Conditions []Condition  `yaml:"when,omitempty" json:"when,omitempty"`
	AnyOf      []Condition  `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`
	ForEach    *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

IngressTemplateSource declares one Ingress to be managed by Orkestra.

Example:

onReconcile:
  ingresses:
    - name: "{{ .metadata.name }}-ingress"
      host: "{{ .spec.hostname }}"
      serviceName: "{{ .metadata.name }}-svc"
      servicePort: "{{ .spec.port }}"
      path: /
      pathType: Prefix
      className: nginx
      tls:
        enabled: true
        secretName: "{{ .metadata.name }}-tls"
        hosts:
          - "{{ .spec.hostname }}"

func (IngressTemplateSource) GetName added in v0.4.2

func (t IngressTemplateSource) GetName() string

func (IngressTemplateSource) GetSleep added in v0.4.2

func (t IngressTemplateSource) GetSleep() string

type JobTemplateSource

type JobTemplateSource struct {
	// Version — OrkestraRegistry implementation version. Omit for latest.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Name — Job name.
	// Default when omitted: "{{ .metadata.name }}-job"
	Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"omitempty"`

	// Image — container image. Required.
	Image string `yaml:"image" json:"image" validate:"omitempty"`

	// ImagePullSecrets is an optional list of references to secrets in the same namespace to use
	// for pulling any of the images used by this PodSpec.
	// If specified, these secrets will be passed to individual puller implementations for them to use.
	ImagePullSecrets []string `yaml:"imagePullSecrets,omitempty" json:"imagePullSecrets,omitempty" validate:"omitempty"`

	// Command — container entrypoint command.
	// Each element is resolved independently — template expressions are supported per element.
	// e.g. ["sh", "-c", "echo cleaning up {{ .metadata.name }}"]
	Command []string `yaml:"command,omitempty" json:"command,omitempty" validate:"omitempty"`

	// Args — arguments passed to the container command.
	// Each element supports template expressions independently.
	Args []string `yaml:"args,omitempty" json:"args,omitempty" validate:"omitempty"`

	// BackoffLimit — number of Pod restart attempts before the Job is marked Failed.
	// Default: 3.
	BackoffLimit int `yaml:"backoffLimit,omitempty" json:"backoffLimit,omitempty" validate:"omitempty"`

	// Namespace — target namespace.
	// Default when omitted: "{{ .metadata.namespace }}"
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty" validate:"omitempty"`

	// Labels — applied to Job metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`

	// NodeSelector is a selector which must be true for the pod to fit on a node.
	// Selector which must match a node's labels for the pod to be scheduled on that node.
	// More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
	// +optional
	// +mapType=atomic
	NodeSelector map[string]string `yaml:"nodeSelector,omitempty" json:"nodeSelector,omitempty"`

	// ServiceAccountName is the name of the ServiceAccount to use to run this pod.
	// More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
	// +optional
	ServiceAccountName string `yaml:"serviceAccountName,omitempty" json:"serviceAccountName,omitempty"`

	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`

	// Reconcile: true — also apply this declaration as drift correction on every
	// reconcile. Equivalent to declaring the same entry under both onCreate and
	// onReconcile. When false (default), only runs on onCreate (idempotent create).
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty" validate:"omitempty"`

	// ForEach declares dynamic expansion over a list field.
	// When set, one source declaration becomes N declarations — one per list element.
	// .item and .<as> are available in template expressions within this declaration.
	ForEach *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// AnyOf holds OR conditions — at least one must pass for this resource to be created.
	// Works alongside the existing Conditions (when:) field which uses AND semantics.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// WorkingDirectory sets the container's working directory (container.WorkingDir).
	// Useful for Git-backed pipelines where build/test commands must run inside
	// a checked-out repository path.
	WorkingDirectory string `yaml:"workingDirectory,omitempty" json:"workingDirectory,omitempty"`

	// Resources — CPU and memory requests/limits for the container.
	// Set resources.profile for a named preset, or resources.requests/limits for
	// explicit values. Profile and explicit values are mutually exclusive.
	Resources *ResourceRequirements `yaml:"resources,omitempty" json:"resources,omitempty" validate:"omitempty"`

	// SecurityContext — container-level security settings.
	// Set securityContext.profile for a named preset (baseline, restricted, hardened)
	// or declare individual fields. Profile and explicit fields are mutually exclusive.
	SecurityContext *ContainerSecurityContext `yaml:"securityContext,omitempty" json:"securityContext,omitempty"`

	// PodSecurity — pod-level security settings applied to the pod spec.
	// Set podSecurity.profile for a named preset or declare individual fields.
	PodSecurity *PodSecurityContext `yaml:"podSecurity,omitempty" json:"podSecurity,omitempty"`

	// Volumes — pod volumes available for mounting into the container.
	Volumes []VolumeSource `yaml:"volumes,omitempty" json:"volumes,omitempty"`

	// VolumeMounts — mounts for the primary container.
	VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

JobTemplateSource declares one Job to be run by Orkestra.

Most commonly used under onDelete for cleanup tasks that must complete before Orkestra removes finalizers from the CR:

  • Draining queues or buffers
  • Archiving state to external storage
  • Notifying external systems of deletion
  • Running database migrations before removing a CRD instance

Can also be used under onCreate for one-time provisioning tasks.

Example (cleanup on delete):

onDelete:
  jobs:
    - name: "{{ .metadata.name }}-cleanup"
      image: busybox
      command: ["sh", "-c", "echo cleaning up {{ .metadata.name }}"]
      backoffLimit: 3

func (JobTemplateSource) GetName added in v0.4.2

func (t JobTemplateSource) GetName() string

func (t NetworkPolicyTemplateSource) GetName() string { return t.Name }

func (JobTemplateSource) GetPodSecurity added in v0.5.4

func (t JobTemplateSource) GetPodSecurity() *PodSecurityContext

func (JobTemplateSource) GetResources added in v0.4.2

func (t JobTemplateSource) GetResources() *ResourceRequirements

func (JobTemplateSource) GetSecurityContext added in v0.5.4

func (t JobTemplateSource) GetSecurityContext() *ContainerSecurityContext

func (JobTemplateSource) GetSleep added in v0.4.2

func (t JobTemplateSource) GetSleep() string

Batch

type KatalogFile

type KatalogFile struct {
	APIVersion string          `yaml:"apiVersion"`
	Kind       string          `yaml:"kind"`
	Metadata   KatalogMeta     `yaml:"metadata"`
	Imports    *KatalogSources `yaml:"imports,omitempty"`
	Spec       KatalogSpec     `yaml:"spec"`
	Security   KatalogSecurity `yaml:"security"`

	// CrossAccess sets the default cross-read policy for all CRDs in this Katalog.
	// When false, no other Katalog may read any CRD in this one via cross:.
	// Individual CRDs may override with their own crossAccess field.
	// Defaults to true (open) when not declared.
	CrossAccess *bool `yaml:"crossAccess,omitempty" json:"crossAccess,omitempty"`

	// Gateway declares how the gateway is deployed for this Katalog.
	// When gateway.standalone: true, the gateway runs without a runtime operator
	// and spec: may be empty.
	Gateway *GatewayConfig `yaml:"gateway,omitempty" json:"gateway,omitempty"`

	// Notification holds the top-level alerting configuration for this Katalog.
	// Defines channels (email, Slack) and per-team routing rules that fire when
	// a managed CRD's conditions transition. When a Komposer references multiple
	// source Katalogs, notification blocks are merged — source teams are inherited
	// and the Komposer's own teams win on name conflict.
	Notification *KatalogNotification `yaml:"notification,omitempty"`

	// Providers declares which external provider libraries this Katalog requires.
	// Top-level alongside spec: and security: — providers represent a distinct
	// operational concern (infrastructure dependencies) separate from CRD definitions.
	//
	//   providers:
	//     - name: aws
	//       required: true
	//       auth:
	//         accessKeyId: "$AWS_ACCESS_KEY_ID"
	//         secretAccessKey: "$AWS_SECRET_ACCESS_KEY"
	//         region: "$AWS_REGION"
	//     - name: mongodb
	//       required: true
	//       auth:
	//         mongoUri: "$MONGODB_URL"
	Providers []KatalogProviderRequirement `yaml:"providers,omitempty"`
}

KatalogFile is the top-level structure of a crd-katalog.yaml file. It contains optional sources (files and helm charts) plus inline CRDs. Orkestra's in-built merger resolves all sources and merges everything into one KatalogSpec.

type KatalogForUI

type KatalogForUI struct {
	APIVersion string                       `json:"apiVersion"`          // Orkestra API version
	Kind       string                       `json:"kind"`                // Always "Katalog" at runtime
	Metadata   KatalogMeta                  `json:"metadata"`            // Katalog metadata (name, description, etc.)
	Spec       KatalogSpecForUI             `json:"spec"`                // CRD definitions
	Security   KatalogSecurity              `json:"security"`            // Security settings
	Providers  []KatalogProviderRequirement `json:"providers,omitempty"` // Provider requirements
}

KatalogForUI is a UI-friendly representation of the merged Katalog. It contains only the fields needed for display in the Control Center, excluding internal runtime fields.

type KatalogMeta

type KatalogMeta struct {
	// Name is the required unique identifier of the Katalog.
	Name string `yaml:"name" json:"name,omitempty"`

	// Namespace scopes this Katalog to a logical tenant or team within a single
	// runtime. Defaults to "default" when not declared — identical to Kubernetes
	// namespace semantics. The Control Center groups CRDs by namespace so each
	// team sees only its own panel.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`

	// ClusterName identifies the cluster this Katalog runs in.
	// Used by the Control Center for cluster-level filtering when multiple
	// runtimes are connected. Katalog value takes precedence over the
	// CLUSTER_NAME env var. Empty when neither is set.
	ClusterName string `yaml:"clusterName,omitempty" json:"clusterName,omitempty"`

	// Description provides a human-readable explanation of the Katalog's purpose.
	Description string `yaml:"description,omitempty" json:"description,omitempty"`

	// Version follows semantic versioning (e.g., "1.2.3") for the Katalog schema or content.
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// Author identifies the creator or maintainer of the Katalog.
	Author string `yaml:"author,omitempty" json:"author,omitempty"`

	// License describes the licensing terms under which the Katalog is distributed.
	License string `yaml:"license,omitempty" json:"license,omitempty"`

	// Tags are optional keywords for categorising the Katalog in the Orkestra Registry.
	// They aid discovery (e.g., "database", "stateful", "security") when using
	// `ork registry list --tag <tag>` and for indexing in Artifact Hub.
	// Tags have no effect on runtime behaviour.
	Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"`

	// CreatedBy indicates which client or command generated this Katalog metadata.
	// It influences the UI presented by the Control Center:
	//   - If empty or "operator" (default) → shows an operator‑focused UI with
	//     detailed infrastructure and workload controls.
	//   - If "orkdoctor" → indicates a developer context; the Control Center
	//     shows a simplified, developer‑oriented UI with only the terminology
	//     and actions relevant to application developers (hides low‑level operator details).
	// Other values may be introduced in the future for different workflows.
	CreatedBy string `yaml:"createdBy,omitempty" json:"createdBy,omitempty"`

	// Projects holds developer-side metadata injected by ork-doctor at generation
	// time. The operator and runtime ignore this field — it is purely for
	// persona-aware tooling and Control Center UI.
	Projects map[string]interface{} `yaml:"projects,omitempty" json:"projects,omitempty"`
}

KatalogMeta holds identifying metadata for a Katalog.

type KatalogNotification

type KatalogNotification struct {
	// Enabled gates all notification dispatch. Default: true when the
	// notification: block is declared. Set false to silence all channels
	// without removing the configuration.
	Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`

	// Standalone controls whether notifications are dispatched directly from the
	// runtime process rather than delegated to a gateway.
	//
	// When true: the runtime calls SMTP/Slack directly — no gateway required.
	// When false (or unset in-cluster): a gateway endpoint must be configured.
	//
	// Defaults to true when not running inside a Kubernetes cluster so that
	// local development and CLI usage work without standing up a gateway.
	// In-cluster, set standalone: true explicitly to opt out of the gateway
	// requirement (e.g. single-binary deployments that do not use gateway features).
	Standalone *bool `yaml:"standalone,omitempty" json:"standalone,omitempty"`

	// Defaults defines global notification behavior applied when a team does
	// not specify its own override.
	Defaults *NotificationDefaults `yaml:"defaults,omitempty" json:"defaults,omitempty"`

	// Teams declares named notification targets. Conditions and rollback blocks
	// reference teams by name via notify: ["platform", "oncall"].
	Teams map[string]*NotificationTeam `yaml:"teams,omitempty" json:"teams,omitempty"`
}

KatalogNotification holds the complete notification configuration for a Katalog. Declared at the same level as spec:, metadata:, and security:.

func (*KatalogNotification) EffectiveInterval

func (n *KatalogNotification) EffectiveInterval(teamName string) Duration

EffectiveInterval returns the notification interval for the given team. Resolution: team.Interval → defaults.Interval → fallback (15m).

func (*KatalogNotification) EffectiveMessage added in v0.1.9

func (n *KatalogNotification) EffectiveMessage(teamName string) string

EffectiveMessage returns the notification message template for a team, falling back to the default format when none is declared.

func (*KatalogNotification) EffectiveSlackWebhook added in v0.1.9

func (n *KatalogNotification) EffectiveSlackWebhook(teamName string) string

EffectiveSlackWebhook returns the Slack webhook URL for the given team. Resolution: team.SlackWebhookUrl → defaults.SlackWebhookUrl → "".

func (*KatalogNotification) HasEmailTargets

func (n *KatalogNotification) HasEmailTargets(teamName string) bool

HasEmailTargets returns true when the team has at least one email recipient.

func (*KatalogNotification) HasSlackTargets

func (n *KatalogNotification) HasSlackTargets(teamName string) bool

HasSlackTargets returns true when the team has Slack channels AND a webhook URL.

func (*KatalogNotification) HasTeams added in v0.1.9

func (n *KatalogNotification) HasTeams() bool

HasTeams returns true when at least one team is declared.

func (*KatalogNotification) IsEmailEnabled added in v0.1.9

func (n *KatalogNotification) IsEmailEnabled(hasSMTPConfig bool) bool

IsEmailEnabled returns true when email is usable for at least one team. hasSMTPConfig is passed from pkg/konfig — avoids importing konfig here.

func (*KatalogNotification) IsEnabled added in v0.1.9

func (n *KatalogNotification) IsEnabled() bool

IsEnabled returns true when notifications are configured and not explicitly disabled.

func (*KatalogNotification) IsSlackEnabled added in v0.1.9

func (n *KatalogNotification) IsSlackEnabled() bool

IsSlackEnabled returns true when Slack is usable for at least one team.

func (*KatalogNotification) IsStandalone added in v0.4.9

func (n *KatalogNotification) IsStandalone() bool

IsStandalone returns whether standalone mode is explicitly declared. Does NOT apply the in-cluster implicit default — use Katalog.IsNotificationStandalone() for that.

type KatalogProviderRequirement

type KatalogProviderRequirement struct {
	// Name is the YAML block key used under operatorBox.providers.
	// Must match the Name() return value of the registered Provider.
	// e.g. "aws", "mongodb", "stripe"
	Name string `yaml:"name" json:"name"`

	// Required controls whether `ork validate` hard-fails on missing registration.
	// true  → validation error if not registered (operator will not function correctly)
	// false → validation warning only (provider blocks are skipped at runtime)
	Required bool `yaml:"required" json:"required"`

	// Auth holds the provider credentials. Values support $ENV_VAR expansion —
	// use "$MY_SECRET" and Orkestra will substitute os.Getenv("MY_SECRET") at startup.
	//
	// AWS example:
	//   auth:
	//     accessKeyId: "$AWS_ACCESS_KEY_ID"
	//     secretAccessKey: "$AWS_SECRET_ACCESS_KEY"
	//     region: "us-east-1"
	//
	// MongoDB example:
	//   auth:
	//     mongoUri: "$MONGODB_URL"
	Auth map[string]string `yaml:"auth,omitempty" json:"auth,omitempty"`

	// Version is the expected provider library version.
	// Used by `ork provider install` to pull the correct OCI artifact.
	// Optional — if absent, the latest version is used.
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// Library is the OCI artifact reference for this provider.
	// e.g. "oci://registry.orkestra.io/providers/aws:1.8.0"
	// Used by `ork provider install`. Optional for locally registered providers.
	//
	// Future
	Library string `yaml:"library,omitempty" json:"library,omitempty"`
}

KatalogProviderRequirement declares that this Katalog uses a named provider. Declared at the top-level providers[] in the Katalog YAML.

Purpose:

  • `ork validate` warns when a required provider is not registered at runtime
  • Supplies credentials (with $ENV_VAR expansion) to the provider at startup
  • `ork provider install` pulls the OCI artifact for this provider
  • Documentation: makes explicit what external systems this Katalog touches

Only providers declared here are registered. Per-CRD provider blocks for undeclared providers are silently skipped with a warning log.

func (KatalogProviderRequirement) ResolvedAuth

func (r KatalogProviderRequirement) ResolvedAuth() map[string]string

ResolvedAuth returns a copy of Auth with all $ENV_VAR values substituted. Values that do not start with "$" are returned unchanged. Called at startup before credentials are passed to the provider constructor.

type KatalogSecurity

type KatalogSecurity struct {
	// ServiceName defines the runtime and gateway service names for the Orkestra deployment.
	ServiceName *ServiceName `yaml:"serviceName,omitempty" json:"serviceName,omitempty"`

	// DeletionProtection controls whether Orkestra registers a webhook that
	// blocks deletion of its managed CRDs, deployment, service, etc.
	//
	// When enabled (default when block is present):
	//   - Registers /deletion-protection endpoint on the HTTPS server
	//   - Creates ValidatingWebhookConfiguration "orkestra-deletion-protection"
	//   - Entry 1: broad rule for CRDs; handler filters by ProtectedCRDNames()
	//   - Entry 2: ObjectSelector-gated rule for deployment, service, etc
	//
	// To decommission an operator with deletion protection:
	//   1. Set enabled: false
	//   2. Redeploy Orkestra (webhook removed on startup)
	//   3. Delete resources normally
	//
	// nil pointer: not enabled (not declared in YAML).
	DeletionProtection *DeletionProtectionConfig `yaml:"deletionProtection,omitempty" json:"deletionProtection,omitempty"`

	// Webhooks controls the admission webhook settings (ValidatingWebhookConfiguration,
	// MutatingWebhookConfiguration). These apply globally — there is no per-CRD switch.
	// CRDs declare validation/mutation rules; the webhook is enabled or not globally.
	//
	// nil pointer: admission webhooks not configured; ENV vars drive behavior.
	Webhooks *WebhooksConfig `yaml:"webhooks,omitempty" json:"webhooks,omitempty"`

	// Conversion controls the /convert endpoint and CRD version conversion.
	// Separate from admission webhooks — conversion has its own endpoint and
	// configuration (window size for stats, etc.).
	//
	// nil pointer: conversion not configured; ENV vars drive behavior.
	Conversion *ConversionConfig `yaml:"conversion,omitempty" json:"conversion,omitempty"`

	// NamespaceProtection controls the optional validating webhook that prevents
	// Orkestra-managed CRs from being created or updated in forbidden namespaces.
	//
	// This is an admission-time safeguard only. When enabled:
	//   - Registers /namespace-protection endpoint on the HTTPS server
	//   - Creates ValidatingWebhookConfiguration "orkestra-namespace-protection"
	//   - Enforces allowedNamespaces / restrictedNamespaces declared by each CRD
	//
	// If disabled or omitted, namespace rules are not enforced at apply time.
	// Existing CRs in forbidden namespaces will still be reconciled normally.
	//
	// nil pointer: namespace protection not configured; ENV vars drive behavior.
	NamespaceProtection *NamespaceProtectionConfig `yaml:"namespaceProtection,omitempty" json:"namespaceProtection,omitempty"`

	// CertManager controls the lifecycle of Orkestra's auto-generated TLS certificate.
	// Only applies when certificates are auto-generated (TLS_CERT/TLS_KEY not set).
	//
	// nil pointer: use ENV defaults (TLS_AUTO_ROTATE, TLS_ROTATION_THRESHOLD).
	CertManager *CertManagerConfig `yaml:"certManager,omitempty" json:"certManager,omitempty"`
}

KatalogSecurity holds the full security configuration for a Katalog.

func (*KatalogSecurity) CertRotationThresholdVal added in v0.4.9

func (s *KatalogSecurity) CertRotationThresholdVal(envDefault string) string

CertRotationThresholdVal returns the effective rotation threshold string. Falls back to the provided ENV default.

func (*KatalogSecurity) DeletionProtectionFailurePolicy

func (s *KatalogSecurity) DeletionProtectionFailurePolicy() string

DeletionProtectionFailurePolicy returns the effective failure policy string. Falls back to "Fail" when not configured — protecting by default.

func (*KatalogSecurity) DeletionProtectionServiceName

func (s *KatalogSecurity) DeletionProtectionServiceName(envDefault string) string

DeletionProtectionServiceName returns the effective service name for deletion protection. Falls back to the provided ENV default.

func (*KatalogSecurity) GatewayServiceName added in v0.4.9

func (s *KatalogSecurity) GatewayServiceName(envDefault string) string

GatewayServiceName returns the effective service name for orkestra gateway. Falls back to the provided ENV default.

func (*KatalogSecurity) IsAdmissionEnabled

func (s *KatalogSecurity) IsAdmissionEnabled() bool

IsAdmissionEnabled returns true when admission webhooks are globally enabled.

func (*KatalogSecurity) IsCertAutoRotateEnabled added in v0.4.9

func (s *KatalogSecurity) IsCertAutoRotateEnabled() bool

IsCertAutoRotateEnabled returns the effective auto-rotate setting. Default: true — rotation is on unless explicitly disabled.

func (*KatalogSecurity) IsConversionEnabled

func (s *KatalogSecurity) IsConversionEnabled() bool

IsConversionEnabled returns true when the conversion webhook is globally enabled.

func (*KatalogSecurity) IsDeletionProtectionEnabled

func (s *KatalogSecurity) IsDeletionProtectionEnabled() bool

IsDeletionProtectionEnabled returns the effective deletion protection setting.

func (*KatalogSecurity) IsNamespaceProtectionEnabled added in v0.1.9

func (s *KatalogSecurity) IsNamespaceProtectionEnabled() bool

IsNamespaceProtectionEnabled returns the effective namespace protection setting.

func (*KatalogSecurity) NamespaceProtectionFailurePolicy added in v0.1.9

func (s *KatalogSecurity) NamespaceProtectionFailurePolicy() string

NamespaceProtectionFailurePolicy returns the effective failure policy string. Falls back to "Fail" when not configured — protecting by default.

func (*KatalogSecurity) NamespaceProtectionServiceName added in v0.1.9

func (s *KatalogSecurity) NamespaceProtectionServiceName(envDefault string) string

NamespaceProtectionServiceName returns the effective service name for namespace protection. Falls back to the provided ENV default.

func (*KatalogSecurity) RuntimeServiceName added in v0.4.9

func (s *KatalogSecurity) RuntimeServiceName(envDefault string) string

RuntimeServiceName returns the effective service name for orkestra runtime. Falls back to the provided ENV default.

func (*KatalogSecurity) ValidForVal added in v0.4.9

func (s *KatalogSecurity) ValidForVal(envDefault string) string

ValidForVal returns the effective validity string. Falls back to the provided ENV default.

func (*KatalogSecurity) WebhooksFailurePolicy

func (s *KatalogSecurity) WebhooksFailurePolicy(envDefault string) string

WebhooksFailurePolicy returns the effective failure policy for admission webhooks. Falls back to "Ignore" — not blocking when Orkestra is unreachable.

func (*KatalogSecurity) WebhooksServiceName

func (s *KatalogSecurity) WebhooksServiceName(envDefault string) string

WebhooksServiceName returns the effective service name for admission webhooks. Falls back to the provided ENV default.

type KatalogSources

type KatalogSources struct {
	// Files — local paths, remote URLs, or environment variable references.
	// Each entry must be a valid Katalog YAML (apiVersion, kind, spec.crds).
	// Supports environment variable references: $MY_KATALOG_URL
	//
	// Simple form: just a path string (no auth)
	//   files:
	//     - ./katalogs/project.yaml
	//     - https://public.url/katalog.yaml
	//     - $MY_KATALOG_URL
	//
	// Authenticated form: a FileSource struct with auth block
	//   files:
	//     - url: https://private.url/katalog.yaml
	//       auth:
	//         type: bearer
	//         fromEnv: MY_TOKEN
	Files []FileSource `yaml:"files,omitempty"`

	// Helm — Helm chart sources. Each chart is rendered with the provided
	// value files and the resulting Katalog templates are extracted and merged.
	Helm []HelmSource `yaml:"helm,omitempty"`

	// Registry - Registry sources.
	Registry []RegistrySource `yaml:"registry,omitempty"`
}

KatalogSources declares where to load CRD definitions from. Sources are loaded before spec.crds — inline CRDs are merged last and win on name conflict (allowing local overrides of remote definitions).

Only valid on kind: Komposer documents.

type KatalogSpec

type KatalogSpec struct {
	// Finalizers — Katalog-level finalizers applied to all CRDs
	// unless overridden at the CRD level.
	Finalizers []string `yaml:"finalizers,omitempty"`

	// CRDs — the CRD entries managed by this Orkestra instance.
	// Map key is the CRD name; Name field is injected from the key during loading.
	CRDs map[string]CRDEntry `yaml:"crds"`
}

KatalogSpec holds the actual CRD definitions. This is what the merger produces after resolving all sources.

type KatalogSpecForUI

type KatalogSpecForUI struct {
	CRDs map[string]CRDEntry `json:"crds"` // Map of CRD name to CRD definition
}

KatalogSpecForUI contains the CRD definitions for UI display.

type KubeReader

type KubeReader interface {
	// GetSecret reads a Secret's data by name in the given namespace.
	// Returns the decoded data map (base64 already decoded).
	GetSecret(ctx context.Context, namespace, name string) (map[string][]byte, error)

	// GetConfigMap reads a ConfigMap's data by name in the given namespace.
	GetConfigMap(ctx context.Context, namespace, name string) (map[string]string, error)
}

KubeReader provides read-only access to cluster resources. Providers must not write Kubernetes resources — Orkestra owns cluster state.

type ManagedResource added in v0.4.1

type ManagedResource struct {
	// Kind is the Kubernetes Kind of the resource (e.g. "StatefulSet",
	// "Service", "CronJob"). This is the primary identifier and is required.
	Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`

	// APIVersion is optional and only needed when the Kind cannot be resolved
	// from Orkestra's built‑in registry. Example: "apps/v1", "batch/v1",
	// "widgets.example.com/v1alpha1".
	APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`

	// Group is optional and used for custom resources or non‑core API groups
	// when you want to fully specify the GroupVersionResource explicitly.
	// Example: "widgets.example.com".
	Group string `json:"group,omitempty" yaml:"group,omitempty"`

	// Version is optional and used together with Group for custom resources.
	// Example: "v1alpha1".
	Version string `json:"version,omitempty" yaml:"version,omitempty"`

	// Plural is optional and used when the plural name cannot be inferred
	// from Orkestra's built‑in registry or CRD metadata. Example: "widgets".
	Plural string `json:"plural,omitempty" yaml:"plural,omitempty"`
}

ManagedResource describes a Kubernetes resource type that a typed extension (either a hook or a constructor) will manage.

Orkestra uses this information to generate RBAC rules for the operator ServiceAccount. Each declared resource results in permissions to get/list/watch/create/update/patch/delete that resource type.

For built‑in Kubernetes resources, Kind alone is sufficient because Orkestra resolves the full GroupVersionResource from its internal registry.

For custom resources or non‑core API groups, APIVersion and/or explicit group/version/plural may be provided.

Example (in katalog.yaml):

hooks:
  resources:
    - kind: StatefulSet
    - kind: Service
    - kind: CronJob
    - kind: Widget
      group: widgets.example.com
      version: v1alpha1
      plural: widgets

type Motif added in v0.3.9

type Motif struct {
	APIVersion string          `yaml:"apiVersion" json:"apiVersion"`
	Kind       string          `yaml:"kind" json:"kind"`
	Metadata   MotifMeta       `yaml:"metadata" json:"metadata"`
	Inputs     []MotifInput    `yaml:"inputs,omitempty" json:"inputs,omitempty"`
	Resources  *MotifResources `yaml:"resources,omitempty" json:"resources,omitempty"`
	Status     *StatusConfig   `yaml:"status,omitempty" json:"status,omitempty"`
	Admission  *Admission      `yaml:"admission,omitempty" json:"admission,omitempty"`
}

Motif is the smallest reusable primitive in Orkestra's composition model. A Motif declares named inputs and resource blocks. It cannot run alone — it must be imported by a Katalog that provides its inputs via with:.

YAML:

apiVersion: orkestra.orkspace.io/v1
kind: Motif
metadata:
  name: postgres
inputs:
  - name: image
  - name: volumeSize
resources: ...
status: ...
admission:
  validation:
    rules:
      - field: spec.image
        prefix: "myregistry.com/"
        action: deny
  mutation:
    rules:
      - field: spec.replicas
        default: "2"

type MotifImport added in v0.3.9

type MotifImport struct {
	// Motif is the registry URL, file path, or short name.
	// Same formats as RegistrySource.URL:
	//   File:  ./postgres/motif.yaml
	//   OCI:   ghcr.io/orkspace/orkestra-registry/postgres@v16
	//   Git:   https://github.com/myorg/postgres-motif@main
	// @ shorthand encodes the version inline: url@version
	Motif string `yaml:"motif" json:"motif,omitempty"`

	// Version — explicit version (tag, branch, or SHA).
	// Ignored when @ shorthand is used in Motif.
	// Defaults to "latest" for OCI, "main" for Git.
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// OCI — when true, pull the Motif artifact via OCI/ORAS protocol.
	// When false (default), pull via Git (GitHub raw URL, GitLab, or git clone).
	OCI bool `yaml:"oci,omitempty" json:"oci,omitempty"`

	// Auth — optional credentials for the registry.
	// Same auth model as RegistrySource.Auth — resolved from environment variables.
	Auth *FileSourceAuth `yaml:"auth,omitempty" json:"auth,omitempty"`

	// With binds the Motif's declared inputs to values.
	// Values are template expressions evaluated in the CRD's reconcile context.
	// Required inputs not provided here are a validation error.
	// Optional inputs not provided use their Motif-declared defaults.
	With map[string]string `yaml:"with,omitempty" json:"with,omitempty"`
}

MotifImport declares one Motif import inside an operatorBox. Follows the same resolution semantics as RegistrySource in a Komposer — if you know how to pull a pattern, you already know how to pull a Motif.

YAML inside operatorBox:

File (developer path):

imports:
  - motif: ./motifs/postgres/motif.yaml
    with:
      image: "postgres:16"

OCI registry (the Orkestra registry houses both patterns and motifs):

imports:
  - motif: ghcr.io/orkspace/orkestra-registry/postgres@v16
    oci: true
    with:
      image: "{{ .spec.postgresImage }}"

Git registry:

imports:
  - motif: https://github.com/myorg/postgres-motif@main
    with:
      image: "{{ .spec.postgresImage }}"

type MotifInput added in v0.3.9

type MotifInput struct {
	// Name is the input identifier referenced in templates as inputs.Name.
	Name string `yaml:"name" json:"name"`

	// Description explains what this input controls.
	Description string `yaml:"description,omitempty" json:"description,omitempty"`

	// Required — when true, the importing Katalog must provide this input
	// in its with: block. Validation fails if required inputs are missing.
	Required bool `yaml:"required,omitempty" json:"required,omitempty"`

	// Type hints at the expected type of the input value. Not currently enforced,
	// but reserved for future type checking or schema generation.
	Type string `yaml:"type,omitempty" json:"type,omitempty"`

	// Default is the value used when the input is not provided in with:.
	// Only valid when Required is false.
	Default string `yaml:"default,omitempty" json:"default,omitempty"`
}

MotifInput declares one input parameter for a Motif.

type MotifMeta added in v0.3.9

type MotifMeta struct {
	Name        string   `yaml:"name" json:"name"`
	Version     string   `yaml:"version,omitempty" json:"version,omitempty"`
	Description string   `yaml:"description,omitempty" json:"description,omitempty"`
	Author      string   `yaml:"author,omitempty" json:"author,omitempty"`
	License     string   `yaml:"license,omitempty" json:"license,omitempty"`
	Tags        []string `yaml:"tags,omitempty" json:"tags,omitempty"`
}

MotifMeta holds Motif identity fields.

type MotifResources added in v0.4.3

type MotifResources struct {
	// OnCreate groups resources that must only be processed during creation —
	// never updated on subsequent reconciles. Secrets with once: true belong here.
	OnCreate *HookTemplates `yaml:"onCreate,omitempty" json:"onCreate,omitempty"`

	// All remaining HookTemplates fields are promoted to the resources: level
	// and merged into the CRD's onReconcile phase.
	HookTemplates `yaml:",inline"`
}

MotifResources groups the resources a Motif contributes to a CRD entry. Resources declared directly under resources: are merged into onReconcile. Resources declared under resources.onCreate: are merged into onCreate, making them immune to the update=true path (correct for once: true secrets).

type MutationConfig

type MutationConfig struct {
	// Rules — applied in declaration order.
	Rules []MutationRule `yaml:"rules,omitempty" json:"rules,omitempty"`

	// MutateFirst — when true, mutation runs before validation at reconcile
	// time. Default true (mutate first, then validate valid objects).
	//
	// At admission time, mutation always runs first — this mirrors the
	// Kubernetes webhook ordering (MutatingWebhookConfiguration fires before
	// ValidatingWebhookConfiguration). This field only affects reconcile ordering.
	MutateFirst bool `yaml:"mutateFirst,omitempty" json:"mutateFirst,omitempty"`
}

MutationConfig holds all mutation rules for a CRD.

type MutationRule

type MutationRule struct {
	// Field — dot-notation path to the CR field to mutate.
	Field string `yaml:"field" json:"field" validate:"required"`

	// Default — set only if the field is absent or empty.
	// Supports template expressions.
	Default interface{} `yaml:"default,omitempty"` // accepts int, bool, string from YAML

	// Override — always set, regardless of current value.
	// Supports template expressions.
	Override interface{} `yaml:"override,omitempty"` // accepts int, bool, string from YAML

	// Value type
	ValueType string `yaml:"valueType,omitempty"` // "string", "int" or "integer", "float" or "number", "bool" or "boolean"
}

MutationRule declares one field mutation.

Two mutation types:

default  — set the field only if it is absent or empty.
           At admission time: applied before validation runs.
           At reconcile time: applied on first reconcile cycle.

override — always set the field, regardless of current value.
           Use with caution — overwrites user-provided values.

Both types support Go template expressions resolved against the CR object:

default: "{{ .metadata.name }}-default"
override: "myorg/{{ .metadata.name }}:latest"

Example:

mutation:
  - field: spec.replicas
    default: "2"
  - field: spec.logLevel
    default: "info"
  - field: spec.image
    override: "myorg/{{ .metadata.name }}:latest"

type NamespaceProtectionConfig added in v0.1.9

type NamespaceProtectionConfig struct {
	// Enabled controls whether namespace protection is active.
	// Default: true when the namespaceProtection block is declared.
	Enabled *bool `yaml:"enabled,omitempty" json:"enabled,omitempty"`

	// ServiceName is the Kubernetes Service fronting Orkestra's HTTPS server.
	// The API server sends webhook requests to this Service.
	// Default: ORK_SERVICE_NAME env / "orkestra".
	ServiceName string `yaml:"serviceName,omitempty" json:"serviceName,omitempty"`

	// FailurePolicy controls what the API server does when Orkestra is unreachable.
	// "Fail"   — reject the CREATE/UPDATE (recommended; this is the default).
	// "Ignore" — allow the request through when Orkestra cannot be reached.
	// Default: "Fail".
	FailurePolicy string `yaml:"failurePolicy,omitempty" json:"failurePolicy,omitempty"`

	// RestrictedNamespaces — deny-list applied to every CRD in this Katalog.
	// Merged additively with per-CRD restrictedNamespaces — more specific levels
	// add to, not replace, broader levels.
	RestrictedNamespaces RestrictedNamespaces `yaml:"restrictedNamespaces,omitempty" json:"restrictedNamespaces,omitempty"`

	// AllowedNamespaces — allow-list applied to every CRD in this Katalog.
	// Merged additively with per-CRD allowedNamespaces.
	AllowedNamespaces AllowedNamespaces `yaml:"allowedNamespaces,omitempty" json:"allowedNamespaces,omitempty"`

	// CleanupOnShutdown controls whether Namespace protection webhook is deleted on graceful shutdown.
	// Default: false — Namespace protection webhook persists across restarts.
	CleanupOnShutdown bool `yaml:"cleanupOnShutdown,omitempty" json:"cleanupOnShutdown,omitempty"`
}

NamespaceProtectionConfig controls namespace-protection webhook behaviour.

type NamespaceTemplateSource added in v0.2.3

type NamespaceTemplateSource struct {
	// Version — OrkestraRegistry implementation version. Omit for latest.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Name — ServiceAccount name.
	// Default when omitted: "{{ .metadata.name }}-sa"
	Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"omitempty"`

	Finalizers []string `yaml:"finalizers,omitempty" json:"finalizers,omitempty" validate:"omitempty"`

	// Labels — applied to ServiceAccount metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`

	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`

	// Reconcile: true — also apply this declaration as drift correction on every
	// reconcile. Equivalent to declaring the same entry under both onCreate and
	// onReconcile. When false (default), only runs on onCreate (idempotent create).
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty" validate:"omitempty"`

	// ForEach declares dynamic expansion over a list field.
	// When set, one source declaration becomes N declarations — one per list element.
	// .item and .<as> are available in template expressions within this declaration.
	ForEach *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// AnyOf holds OR conditions — at least one must pass for this resource to be created.
	// Works alongside the existing Conditions (when:) field which uses AND semantics.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

NamespaceTemplateSource declares one Namespace to be managed by Orkestra.

Example:

onCreate:
  namespaces:
    - name: "{{ .metadata.name }}-sa"
      labels:
        - key: app
          value: "{{ .metadata.name }}"

func (NamespaceTemplateSource) GetName added in v0.4.2

func (t NamespaceTemplateSource) GetName() string

func (NamespaceTemplateSource) GetSleep added in v0.4.2

func (t NamespaceTemplateSource) GetSleep() string

type NewReconcilerFunc

type NewReconcilerFunc func(
	kube kubeclient.KubeClient,
	inf cache.SharedIndexInformer,
	ev event.Recorder,
) domain.Reconciler

type NormalizeChange added in v0.6.2

type NormalizeChange struct {
	Field string      `json:"field"`
	From  interface{} `json:"from,omitempty"`
	To    interface{} `json:"to,omitempty"`
}

NormalizeChange records a single field transformation during normalize. Available in status templates as ._normalizeChanges when audit: true.

type NormalizeConfig

type NormalizeConfig struct {
	// Spec contains field-level normalization templates.
	// Example:
	//
	//   normalize:
	//     spec:
	//       schedule: >
	//         {{ if typeMap .spec.schedule }}
	//           {{ cronFromMap .spec.schedule }}
	//         {{ else }}
	//           {{ cronNormalize .spec.schedule }}
	//         {{ end }}
	//
	// Spec maps a dot-notation field path to a template expression.
	// The template sees the raw CR (before any normalization of other fields).
	// Results are coerced to the appropriate Go type via YAML parsing:
	//   "3"     → int
	//   "true"  → bool
	//   "*/5 * * * *" → string
	// Empty result ("") sets the field to empty string — not nil.
	Spec map[string]string `yaml:"spec,omitempty" json:"spec,omitempty"`

	// Audit enables per-field change tracking during normalize.
	// When true, Orkestra records which spec fields were transformed and what
	// value they held before normalization. The changes are available in status
	// field templates under ._normalizeChanges as a list of {field, from, to}.
	//
	// Example:
	//
	//   normalize:
	//     audit: true
	//     spec:
	//       environment: '{{ default "production" .spec.environment | toLower }}'
	//
	//   status:
	//     fields:
	//       - path: normalizeChanges
	//         value: "{{ toJson ._normalizeChanges }}"
	Audit bool `yaml:"audit,omitempty" json:"audit,omitempty"`

	// Types declares the expected output type for specific spec fields.
	// When a field is listed here, its rendered value is cast to the declared
	// type instead of being inferred via YAML parsing. This is more precise:
	//   - An empty string ("") for a typed field writes nil (omits the field)
	//     rather than an empty string, which would fail integer/boolean schema validation.
	//   - "0" declared as bool → false, not int64(0).
	//   - "false" declared as bool → false even when YAML would parse it correctly.
	//
	// Accepted type values: "int", "integer", "bool", "boolean", "float", "number", "string".
	//
	// Example:
	//
	//   normalize:
	//     spec:
	//       replicas: "{{ default 1 .spec.replicas }}"
	//       suspend:  "{{ default false .spec.suspend }}"
	//     types:
	//       replicas: int
	//       suspend:  bool
	Types map[string]string `yaml:"types,omitempty" json:"types,omitempty"`
}

NormalizeConfig declares template-driven spec normalization. This phase runs BEFORE mutation, validation, and reconciliation.

Purpose:

  • Accept multiple user-facing shapes (string vs map, list vs scalar, etc.)
  • Collapse them into a single canonical spec used internally.
  • Avoid drift where the CR stores one shape but children require another.
  • Provide a declarative alternative to conversion webhooks.

Behavior:

  • normalize.spec is a map of field → template string.
  • Each template is evaluated against the RAW CR object.
  • The rendered values overwrite the corresponding fields in .spec.
  • Only declared fields are overwritten; others remain untouched.
  • The normalized object is passed to NewResolver() and all downstream phases.
  • The stored CR in etcd is NOT modified.

Nested paths are supported:

normalize:
  spec:
    resources.requests.cpu: "{{ default .spec.resources.requests.cpu \"100m\" }}"
    containers.0.image: "{{ .spec.image }}:{{ .spec.tag }}"

NormalizeConfig declares field normalizations that run before mutation, validation, and template rendering.

Keys are dot-notation paths into spec (e.g. "schedule", "resources.limits.cpu"). Values are template expressions evaluated against the raw CR. Results are written back into the in-memory spec copy.

type NotificationDefaults

type NotificationDefaults struct {
	// Interval is the minimum time between notifications for the same
	// condition+team pair while the condition remains true. Default: 15m.
	Interval Duration `yaml:"interval,omitempty" json:"interval,omitempty"`

	// SlackWebhookUrl is the global default Slack incoming webhook URL.
	// Used when a team declares slack: channels but no slackWebhookUrl.
	// Can be overridden per team.
	SlackWebhookUrl string `yaml:"slackWebhookUrl,omitempty" json:"slackWebhookUrl,omitempty"`
}

NotificationDefaults defines global defaults applied when a team does not override specific settings.

type NotificationTeam

type NotificationTeam struct {
	// Email is the list of email recipients. SMTP config comes from pkg/konfig
	// env vars (SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, SMTP_FROM).
	Email []string `yaml:"email,omitempty" json:"email,omitempty"`

	// Slack is the list of Slack channels to notify (e.g. "#platform-alerts").
	// Requires SlackWebhookUrl (team or global default) to be configured.
	Slack []string `yaml:"slack,omitempty" json:"slack,omitempty"`

	// SlackWebhookUrl is the incoming webhook URL for this team's Slack workspace.
	// Overrides notification.defaults.slackWebhookUrl for this team.
	// Required when Slack is non-empty and no global default is set.
	SlackWebhookUrl string `yaml:"slackWebhookUrl,omitempty" json:"slackWebhookUrl,omitempty"`

	// Interval overrides the global default for this team. Zero duration falls
	// back to notification.defaults.interval or the built-in default of 15m.
	Interval Duration `yaml:"interval,omitempty" json:"interval,omitempty"`

	// Message is a Go template expression evaluated against the full resolver
	// data (.spec.*, .metadata.*, .status.*, .children.*, metrics.*).
	// When empty, Orkestra uses a default message format:
	//   "[orkestra] {katalogName}/{crdKind} {crName}: {condition.Field} {op} {value}"
	Message string `yaml:"message,omitempty" json:"message,omitempty"`
}

NotificationTeam defines channels and behavior for one named notification target.

type NotifyBlock added in v0.1.9

type NotifyBlock struct {
	// Teams is the list of team names (from notification.teams) to alert.
	Teams []string `yaml:"teams" json:"teams"`
	// Message is a Go template expression for the notification body.
	// Overrides the team's own message template.
	// When empty, uses the team's configured message or the system default.
	Message string `yaml:"message,omitempty" json:"message,omitempty"`
}

NotifyBlock declares notification targets and an optional message override for a specific condition.

type ONCOPType added in v0.4.5

type ONCOPType string

ONCOPType defines the category of cross-operator data being fetched.

const (
	ONCOPMetrics ONCOPType = "metrics"
	ONCOPHealth  ONCOPType = "health"
	ONCOPInfo    ONCOPType = "info"
	ONCOPCR      ONCOPType = "cr"
	ONCOPEvents  ONCOPType = "events"
)

func CRType added in v0.4.5

func CRType() ONCOPType

func EventsType added in v0.4.5

func EventsType() ONCOPType

func HealthType added in v0.4.5

func HealthType() ONCOPType

func InfoType added in v0.4.5

func InfoType() ONCOPType

func MetricsType added in v0.4.5

func MetricsType() ONCOPType

func (ONCOPType) String added in v0.4.5

func (t ONCOPType) String() string

String returns the string representation of the ONCOPType. This ensures fmt.Printf, logs, and YAML marshaling behave predictably.

type OperatorBoxConfig

type OperatorBoxConfig struct {
	// Default controls which reconciler implementation is used for this CRD.
	//
	// true  — GenericReconciler manages the full lifecycle automatically.
	//         Handles: finalizer add/remove, Kubernetes events, metrics, health state.
	//         HookFactory is optional — set for custom business logic.
	//         OnCreate/OnReconcile/OnDelete templates are only valid when Default: true.
	//
	// false — Custom reconciler. The user provides the full reconcile implementation.
	//         Constructor must be declared (in YAML mode) or set directly (Go mode).
	//         GenericReconciler is not used — the user owns the entire lifecycle.
	Default *bool `yaml:"default,omitempty" json:"default,omitempty" validate:"omitempty"`

	// Finalizers — per-CRD finalizer list. Overrides the Katalog-level finalizer.
	// Applied by GenericReconciler when a CR is first created.
	// Stripped one-by-one before delete to unblock Kubernetes garbage collection.
	// If empty, falls back to the Katalog-level finalizer declaration.
	Finalizers []string `yaml:"finalizers,omitempty" json:"finalizers,omitempty" validate:"omitempty"`

	// Hooks — declares a Go hook function for Default: true CRDs in typed or dynamic mode.
	// The function at Location.Function must match: func() domain.AnyReconcileHooks
	// Use this when you want full Go control over reconcile logic.
	// For declarative resource management without Go code, use OnCreate/OnReconcile/OnDelete.
	// Only one of Hooks or OnCreate/OnReconcile/OnDelete should be used — not both.
	Hooks *HookDeclaration `yaml:"hooks,omitempty" json:"hooks,omitempty" validate:"omitempty"`

	// ConstructorDecl — declares a custom reconciler constructor for Default: false CRDs.
	// The function at Location.Function must match: NewReconcilerFunc
	// Required when Default: false in YAML mode.
	ConstructorDecl *ConstructorDeclaration `yaml:"constructor,omitempty" json:"constructor,omitempty" validate:"omitempty"`

	// OnCreate — resources to create when the CR is first reconciled.
	OnCreate *HookTemplates `yaml:"onCreate,omitempty" json:"onCreate,omitempty" validate:"omitempty"`

	// OnReconcile — drift correction resources applied on every reconcile.
	// Omit if onCreate alone is sufficient.
	OnReconcile *HookTemplates `yaml:"onReconcile,omitempty" json:"onReconcile,omitempty" validate:"omitempty"`

	// OnDelete — cleanup resources applied before finalizer removal.
	// Omit for resources covered by owner reference cascade deletion.
	OnDelete *HookTemplates `yaml:"onDelete,omitempty" json:"onDelete,omitempty" validate:"omitempty"`

	// HookFactory — called once at startCRDWorkers time to produce typed hooks.
	// nil → GenericReconciler runs with no user hooks.
	//       Finalizers, events, and metrics are still handled automatically.
	HookFactory func() domain.AnyReconcileHooks `yaml:"-" json:"-"`

	// Constructor — called once at startCRDWorkers time to build a custom reconciler.
	// Must not be nil when Default: false — enforced by Katalog validation at startup.
	Constructor NewReconcilerFunc `yaml:"-" json:"-"`

	// Status declares how Orkestra manages the CR's /status subresource.
	// nil (default): Layer 1 only — standard Ready condition after every reconcile.
	// non-nil: Layer 1 + Layer 2 declarative fields from Status.Fields.
	Status *StatusConfig `yaml:"status,omitempty" json:"status,omitempty"`

	// ProviderBlocks holds the parsed provider declarations from the Katalog.
	// Populated during Katalog loading via ParseProviderBlocks.
	// Not a YAML field — parsed from RawProviders after unmarshal.
	ProviderBlocks []ProviderBlock `yaml:"-" json:"-"`

	// RawProviders is the raw YAML map, populated during unmarshal.
	// Converted to ProviderBlocks in the Katalog loading step.
	RawProviders map[string][]map[string]interface{} `yaml:"providers,omitempty" json:"providers,omitempty"`

	// Cross declares cross-CRD observations.
	// Read before any resource groups — results available as .cross.<as>.status.*
	Cross []CrossCRDDeclaration `yaml:"cross,omitempty" json:"cross,omitempty"`

	// Autoscale declares runtime autoscale behavior for this operatorbox.
	// When declared, the autoscaler evaluates conditions on a ticker and applies
	// or restores worker/queue/resync overrides automatically.
	// nil → no autoscaling; CRD runs with its declared static worker count.
	Autoscale *AutoscaleSpec `yaml:"autoscale,omitempty" json:"autoscale,omitempty"`

	// Rollback declares failure-recovery behavior for this operatorbox.
	// When declared, Orkestra tracks consecutive reconcile failures and re-applies
	// the last known good spec when the trigger threshold is crossed.
	// nil → no rollback; failures are retried indefinitely.
	Rollback *RollbackBlock `yaml:"rollback,omitempty" json:"rollback,omitempty"`

	// RollBackOnError is a zero-config rollback shorthand.
	//
	// When true, Orkestra automatically rolls back to the previous spec whenever
	// the default trigger threshold is reached (3 consecutive failures), without
	// requiring a separate rollback: block.
	//
	// The rollback templates are derived from all resource declarations that have
	// reconcile: true in onCreate: and onReconcile:. Those same templates are
	// re-applied using the previous spec as the base context — .spec.* resolves
	// to the previous spec values, so no .previous.spec.* references are needed.
	//
	// Resources with once: true are excluded — they are never regenerated by rollback.
	//
	// Combine with an explicit rollback.trigger to adjust the threshold without
	// redeclaring the rollback templates:
	//
	//	operatorBox:
	//	  rollBackOnError: true
	//	  rollback:
	//	    trigger:
	//	      consecutiveFailures: 5
	//	      withinDuration: 10m
	//
	// Declare rollback.onRollback alongside rollBackOnError: true to override the
	// derived templates for specific resources while keeping the shorthand trigger.
	RollBackOnError bool `yaml:"rollBackOnError,omitempty" json:"rollBackOnError,omitempty"`

	// When is an optional list of conditions that must all pass before
	// this field is written. If absent or empty, the field is always written.
	//
	// All conditions are AND-ed together.
	// To express OR logic, declare multiple StatusField entries for the same path.
	//
	// Conditions are evaluated against the full CR object map — the same
	// map available to template expressions. This means .status.phase,
	// .spec.image, .children.job.status.succeeded are all accessible.
	When []Condition `yaml:"when,omitempty"`

	AnyOf []Condition `yaml:"anyOf,omitempty"`
}

func (*OperatorBoxConfig) DerivedRollback added in v0.3.2

func (c *OperatorBoxConfig) DerivedRollback() *RollbackBlock

DerivedRollback returns the effective RollbackBlock for this operatorbox, merging rollBackOnError: true shorthand with any explicit rollback: declaration.

Resolution order:

  1. Neither rollBackOnError nor rollback set → nil (no rollback)
  2. rollBackOnError: false, rollback set → explicit block returned as-is
  3. rollBackOnError: true → synthetic block derived from reconcile:true resources; explicit rollback.trigger and rollback.onRollback take precedence when set

type PDBBehavior added in v0.5.4

type PDBBehavior struct {
	// Profile — named preset. Expands into MinAvailable or MaxUnavailable at load time.
	// Allowed: zero-downtime, rolling, relaxed.
	Profile string `yaml:"profile,omitempty" json:"profile,omitempty"`

	// MinAvailable — minimum pods that must remain available during voluntary disruptions.
	// Accepts integer string ("1") or percentage string ("100%").
	// Mutually exclusive with MaxUnavailable.
	MinAvailable string `yaml:"minAvailable,omitempty" json:"minAvailable,omitempty"`

	// MaxUnavailable — maximum pods that may be unavailable during voluntary disruptions.
	// Accepts integer string ("1") or percentage string ("25%").
	// Mutually exclusive with MinAvailable.
	MaxUnavailable string `yaml:"maxUnavailable,omitempty" json:"maxUnavailable,omitempty"`
}

PDBBehavior configures PodDisruptionBudget disruption limits. Set Profile for a named preset, or MinAvailable/MaxUnavailable explicitly. Profile and explicit fields are mutually exclusive.

type PDBProfileEntry added in v0.5.4

type PDBProfileEntry struct {
	Phase        string // "onCreate", "onReconcile", "onDelete"
	ResourceName string // PDB name template (may be empty)
	Profile      string // raw profile name as written in the katalog
	Mixed        bool   // true when profile is set alongside explicit minAvailable or maxUnavailable
}

PDBProfileEntry describes a single behavior.profile reference found in a PDBTemplateSource. Used by katalog validation to fail fast on unknown profiles and to enforce mutual exclusivity with explicit minAvailable/maxUnavailable.

type PDBTemplateSource added in v0.1.9

type PDBTemplateSource struct {
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// Name — PDB resource name. Default: "{{ .metadata.name }}-pdb"
	Name string `yaml:"name,omitempty" json:"name,omitempty"`

	// Namespace — target namespace. Default: CR namespace.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`

	// Selector — label selector identifying the pods this PDB protects.
	// Keys are static; values support template expressions.
	Selector SelectorMap `yaml:"selector,omitempty" json:"selector,omitempty"`

	// MinAvailable — minimum number of pods that must remain available.
	// Accepts integer strings ("1") or percentage strings ("50%").
	// Mutually exclusive with MaxUnavailable.
	MinAvailable string `yaml:"minAvailable,omitempty" json:"minAvailable,omitempty"`

	// MaxUnavailable — maximum number of pods that may be unavailable.
	// Accepts integer strings ("1") or percentage strings ("25%").
	// Mutually exclusive with MinAvailable.
	MaxUnavailable string `yaml:"maxUnavailable,omitempty" json:"maxUnavailable,omitempty"`

	// Labels applied to PDB metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty"`

	// Behavior — disruption limit configuration.
	// Set behavior.profile for a named preset, or declare minAvailable/maxUnavailable explicitly.
	// Profile and explicit fields are mutually exclusive.
	Behavior *PDBBehavior `yaml:"behavior,omitempty" json:"behavior,omitempty"`

	Reconcile  bool         `yaml:"reconcile,omitempty" json:"reconcile,omitempty"`
	Conditions []Condition  `yaml:"when,omitempty" json:"when,omitempty"`
	AnyOf      []Condition  `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`
	ForEach    *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

PDBTemplateSource declares one PodDisruptionBudget to be managed by Orkestra.

Example:

onReconcile:
  pdb:
    - name: "{{ .metadata.name }}-pdb"
      minAvailable: "1"
      selector:
        app: "{{ .metadata.name }}"
      forEach:
        field: spec.services
        as: item

func (PDBTemplateSource) GetName added in v0.4.2

func (t PDBTemplateSource) GetName() string

func (PDBTemplateSource) GetPDBBehavior added in v0.5.4

func (t PDBTemplateSource) GetPDBBehavior() *PDBBehavior

func (PDBTemplateSource) GetSleep added in v0.4.2

func (t PDBTemplateSource) GetSleep() string

type PVCTemplateSource added in v0.1.9

type PVCTemplateSource struct {
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// Name — PVC name. Required.
	Name string `yaml:"name,omitempty" json:"name,omitempty"`

	// Namespace — target namespace. Default: CR namespace.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`

	// StorageClassName — storage class to use. Empty means cluster default.
	StorageClassName string `yaml:"storageClassName,omitempty" json:"storageClassName,omitempty"`

	// AccessModes — access modes. Default: ["ReadWriteOnce"].
	// Supports: ReadWriteOnce, ReadOnlyMany, ReadWriteMany, ReadWriteOncePod.
	AccessModes []string `yaml:"accessModes,omitempty" json:"accessModes,omitempty"`

	// Storage — requested storage size (e.g. "10Gi"). Required.
	Storage string `yaml:"storage,omitempty" json:"storage,omitempty" validate:"required"`

	// VolumeMode — Filesystem or Block. Default: Filesystem.
	VolumeMode string `yaml:"volumeMode,omitempty" json:"volumeMode,omitempty"`

	// VolumeName — bind to a specific PV by name.
	VolumeName string `yaml:"volumeName,omitempty" json:"volumeName,omitempty"`

	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty"`

	Reconcile  bool         `yaml:"reconcile,omitempty" json:"reconcile,omitempty"`
	Conditions []Condition  `yaml:"when,omitempty" json:"when,omitempty"`
	AnyOf      []Condition  `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`
	ForEach    *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

PVCTemplateSource declares one PersistentVolumeClaim to be managed by Orkestra.

func (PVCTemplateSource) GetName added in v0.4.2

func (t PVCTemplateSource) GetName() string

func (PVCTemplateSource) GetSleep added in v0.4.2

func (t PVCTemplateSource) GetSleep() string

type PVCVolumeSource added in v0.6.2

type PVCVolumeSource struct {
	// ClaimName — name of the PVC. Supports template expressions.
	ClaimName string `yaml:"claimName" json:"claimName"`

	// ReadOnly — mount the PVC read-only. Default: false.
	ReadOnly bool `yaml:"readOnly,omitempty" json:"readOnly,omitempty"`
}

PVCVolumeSource mounts an existing PersistentVolumeClaim.

type PVTemplateSource added in v0.1.9

type PVTemplateSource struct {
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// Name — PV name. Required.
	Name string `yaml:"name,omitempty" json:"name,omitempty"`

	// StorageClassName — storage class name.
	StorageClassName string `yaml:"storageClassName,omitempty" json:"storageClassName,omitempty"`

	// Capacity — storage capacity (e.g. "10Gi"). Required.
	Capacity string `yaml:"capacity,omitempty" json:"capacity,omitempty" validate:"required"`

	// AccessModes — access modes. Default: ["ReadWriteOnce"].
	AccessModes []string `yaml:"accessModes,omitempty" json:"accessModes,omitempty"`

	// ReclaimPolicy — Retain, Delete, or Recycle. Default: Retain.
	ReclaimPolicy string `yaml:"reclaimPolicy,omitempty" json:"reclaimPolicy,omitempty"`

	// HostPath — host path for HostPath volume type. Used for local/dev PVs.
	HostPath string `yaml:"hostPath,omitempty" json:"hostPath,omitempty"`

	// CSI driver fields for cloud/CSI volumes.
	CSIDriver       string `yaml:"csiDriver,omitempty" json:"csiDriver,omitempty"`
	CSIVolumeHandle string `yaml:"csiVolumeHandle,omitempty" json:"csiVolumeHandle,omitempty"`

	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty"`

	Reconcile  bool         `yaml:"reconcile,omitempty" json:"reconcile,omitempty"`
	Conditions []Condition  `yaml:"when,omitempty" json:"when,omitempty"`
	AnyOf      []Condition  `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`
	ForEach    *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

PVTemplateSource declares one PersistentVolume to be managed by Orkestra. PersistentVolumes are cluster-scoped — Namespace is ignored.

func (PVTemplateSource) GetName added in v0.4.2

func (t PVTemplateSource) GetName() string

func (PVTemplateSource) GetSleep added in v0.4.2

func (t PVTemplateSource) GetSleep() string

Storage

type PlaceholderSource

type PlaceholderSource struct{}

Placeholder for resources yet to be added to orkestra internal registry pkg/resources

type PodSecurityContext added in v0.5.4

type PodSecurityContext struct {
	// Profile — named security preset. One of: baseline, restricted, hardened.
	// Expands into the corresponding pod security fields at katalog load time.
	Profile string `yaml:"profile,omitempty" json:"profile,omitempty"`

	// RunAsNonRoot — if true, the pod's containers must run as a non-root user.
	RunAsNonRoot *bool `yaml:"runAsNonRoot,omitempty" json:"runAsNonRoot,omitempty"`

	// RunAsUser — UID to run the entrypoint of all containers.
	RunAsUser *int64 `yaml:"runAsUser,omitempty" json:"runAsUser,omitempty"`

	// RunAsGroup — GID to run the entrypoint of all containers.
	RunAsGroup *int64 `yaml:"runAsGroup,omitempty" json:"runAsGroup,omitempty"`

	// FSGroup — supplemental GID applied to all containers.
	// Volumes owned by the pod will be owned by this GID.
	FSGroup *int64 `yaml:"fsGroup,omitempty" json:"fsGroup,omitempty"`
}

PodSecurityContext declares pod-level security settings. Set Profile for a named preset or declare individual fields directly. Profile and explicit fields are mutually exclusive.

type PodTemplateSource

type PodTemplateSource struct {
	// Version — OrkestraRegistry implementation version. Omit for latest.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Name — Pod name.
	// Default when omitted: "{{ .metadata.name }}-pod"
	Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"omitempty"`

	// Image — container image. Required.
	// Static: "busybox:1.35" or Dynamic: "{{ .spec.image }}"
	Image string `yaml:"image" json:"image" validate:"omitempty"`

	// ImagePullSecrets is an optional list of references to secrets in the same namespace to use
	// for pulling any of the images used by this PodSpec.
	// If specified, these secrets will be passed to individual puller implementations for them to use.
	ImagePullSecrets []string `yaml:"imagePullSecrets,omitempty" json:"imagePullSecrets,omitempty" validate:"omitempty"`

	// Port — container port as a string.
	// Static: "8080" or Dynamic: "{{ .spec.port }}"
	Port string `yaml:"port,omitempty" json:"port,omitempty" validate:"omitempty"`

	// Protocol — network protocol for the container port.
	// Accepted values: TCP (default), UDP, SCTP. Omit to use TCP.
	Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty" validate:"omitempty"`

	// Namespace — target namespace.
	// Default when omitted: "{{ .metadata.namespace }}"
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty" validate:"omitempty"`

	// Labels — applied to Pod metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`

	// Annotations — applied to Pod metadata. Values support template expressions.
	Annotations []ResourceLabel `yaml:"annotations,omitempty" json:"annotations,omitempty" validate:"omitempty"`

	// Resources — CPU and memory requests/limits for the primary container.
	// Set resources.profile for a named preset, or resources.requests/limits for
	// explicit values. Profile and explicit values are mutually exclusive.
	Resources *ResourceRequirements `yaml:"resources,omitempty" json:"resources,omitempty" validate:"omitempty"`

	// NodeSelector is a selector which must be true for the pod to fit on a node.
	// Selector which must match a node's labels for the pod to be scheduled on that node.
	// More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
	// +optional
	// +mapType=atomic
	NodeSelector map[string]string `yaml:"nodeSelector,omitempty" json:"nodeSelector,omitempty"`

	// ServiceAccountName is the name of the ServiceAccount to use to run this pod.
	// More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
	// +optional
	ServiceAccountName string `yaml:"serviceAccountName,omitempty" json:"serviceAccountName,omitempty"`

	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`

	// ForEach declares dynamic expansion over a list field.
	// When set, one source declaration becomes N declarations — one per list element.
	// .item and .<as> are available in template expressions within this declaration.
	ForEach *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// AnyOf holds OR conditions — at least one must pass for this resource to be created.
	// Works alongside the existing Conditions (when:) field which uses AND semantics.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// Probes — startup, liveness, and readiness probe configuration.
	Probes *ProbesConfig `yaml:"probes,omitempty" json:"probes,omitempty"`

	// Reconcile: true — also apply this declaration as drift correction on every
	// reconcile, not just on create. Equivalent to declaring the same entry under
	// onReconcile. When false (default), only runs on onCreate (idempotent create).
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty" validate:"omitempty"`

	// SecurityContext — container-level security settings.
	// Set securityContext.profile for a named preset (baseline, restricted, hardened)
	// or declare individual fields. Profile and explicit fields are mutually exclusive.
	SecurityContext *ContainerSecurityContext `yaml:"securityContext,omitempty" json:"securityContext,omitempty"`

	// PodSecurity — pod-level security settings applied to the pod spec.
	// Set podSecurity.profile for a named preset or declare individual fields.
	PodSecurity *PodSecurityContext `yaml:"podSecurity,omitempty" json:"podSecurity,omitempty"`

	// Volumes — pod volumes available for mounting into the container.
	Volumes []VolumeSource `yaml:"volumes,omitempty" json:"volumes,omitempty"`

	// VolumeMounts — mounts for the primary container.
	VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

PodTemplateSource declares one Pod to be managed by Orkestra.

Prefer DeploymentTemplateSource for long-running workloads. Deployments manage Pod restarts, rolling updates, and replica sets automatically. Use PodTemplateSource only when you need direct, single-instance Pod control.

Example:

onCreate:
  pods:
    - name: "{{ .metadata.name }}-worker"
      image: "{{ .spec.workerImage }}"
      port: "9090"

func (PodTemplateSource) GetName added in v0.4.2

func (t PodTemplateSource) GetName() string

Additional common types

func (PodTemplateSource) GetPodSecurity added in v0.5.4

func (t PodTemplateSource) GetPodSecurity() *PodSecurityContext

func (PodTemplateSource) GetProbes added in v0.4.2

func (t PodTemplateSource) GetProbes() *ProbesConfig

func (PodTemplateSource) GetProtocol added in v0.6.2

func (t PodTemplateSource) GetProtocol() string

func (PodTemplateSource) GetResources added in v0.4.2

func (t PodTemplateSource) GetResources() *ResourceRequirements

func (PodTemplateSource) GetSecurityContext added in v0.5.4

func (t PodTemplateSource) GetSecurityContext() *ContainerSecurityContext

func (PodTemplateSource) GetSleep added in v0.4.2

func (t PodTemplateSource) GetSleep() string

func (t DaemonSetTemplateSource) GetSleep() string { return t.Sleep }

type PolicyRuleSpec added in v0.3.9

type PolicyRuleSpec struct {
	APIGroups     []string `yaml:"apiGroups,omitempty" json:"apiGroups,omitempty"`
	Resources     []string `yaml:"resources,omitempty" json:"resources,omitempty"`
	Verbs         []string `yaml:"verbs,omitempty" json:"verbs,omitempty"`
	ResourceNames []string `yaml:"resourceNames,omitempty" json:"resourceNames,omitempty"`
}

PolicyRuleSpec declares one RBAC policy rule. String values within slices support template expressions.

type PortProtocolEntry added in v0.6.2

type PortProtocolEntry struct {
	Phase        string // "onCreate", "onReconcile", "onDelete"
	ResourceName string // template name field (may be a template expression)
	Protocol     string // raw protocol string as written in the katalog
}

PortProtocolEntry describes a single port protocol declaration found in a resource template. Used by katalog validation to catch invalid protocol values early at load time.

type ProbeConfig added in v0.4.2

type ProbeConfig struct {
	// Type — probe mechanism. "http" uses an HTTP GET, "tcp" opens a TCP socket.
	// When path is set and type is omitted, http is assumed.
	Type string `yaml:"type,omitempty" json:"type,omitempty"`

	// Path — HTTP GET path. Required when type is "http".
	Path string `yaml:"path,omitempty" json:"path,omitempty"`

	// Port — override port for the probe. Defaults to the container's declared port.
	Port int32 `yaml:"port,omitempty" json:"port,omitempty"`

	// Profile — timing profile name. Allowed values: fast, standard, patient, slow-start.
	// Defaults to "standard" when omitted.
	Profile string `yaml:"profile,omitempty" json:"profile,omitempty"`

	// Explicit timing overrides — use when profiles are not granular enough.
	InitialDelaySeconds *int32 `yaml:"initialDelaySeconds,omitempty" json:"initialDelaySeconds,omitempty"`
	PeriodSeconds       *int32 `yaml:"periodSeconds,omitempty" json:"periodSeconds,omitempty"`
	FailureThreshold    *int32 `yaml:"failureThreshold,omitempty" json:"failureThreshold,omitempty"`
	SuccessThreshold    *int32 `yaml:"successThreshold,omitempty" json:"successThreshold,omitempty"`
	TimeoutSeconds      *int32 `yaml:"timeoutSeconds,omitempty" json:"timeoutSeconds,omitempty"`
}

ProbeConfig configures a single Kubernetes probe (startup, liveness, or readiness). Supports HTTP GET and TCP socket checks, with timing driven by named profiles or explicit field overrides.

Examples:

probes:
  startup:
    type: http
    path: /health
    profile: slow-start
  liveness:
    type: http
    path: /health
    profile: standard
  readiness:
    type: http
    path: /ready
    profile: standard

probes:
  liveness:
    type: tcp
    profile: standard

type ProbeProfileEntry added in v0.4.2

type ProbeProfileEntry struct {
	Phase        string // "onCreate", "onReconcile", "onDelete"
	Resource     string // e.g. "Deployment", "StatefulSet"
	ResourceName string // template name field (may be empty)
	ProbeType    string // "startup", "liveness", "readiness"
	Profile      string // raw profile name as written in the katalog
	Mixed        bool   // true when profile is set alongside explicit timing overrides
}

ProbeProfileEntry describes a single probe profile reference found in a HookTemplates resource. Used by validation to fail fast on unknown profiles and to enforce mutual exclusivity between profile and explicit timing fields.

type ProbesConfig added in v0.4.2

type ProbesConfig struct {
	Startup   *ProbeConfig `yaml:"startup,omitempty" json:"startup,omitempty"`
	Liveness  *ProbeConfig `yaml:"liveness,omitempty" json:"liveness,omitempty"`
	Readiness *ProbeConfig `yaml:"readiness,omitempty" json:"readiness,omitempty"`
}

ProbesConfig groups startup, liveness, and readiness probe declarations.

type Provider

type Provider interface {
	// Name returns the YAML block key this provider handles.
	// Must be unique across all registered providers.
	// Convention: lowercase, no hyphens (e.g. "aws", "database", "stripe").
	Name() string

	// Reconcile is called after all Kubernetes resources are reconciled.
	// It should bring external resources into alignment with the declared state.
	// Must be idempotent — called on every resync, not just on first creation.
	//
	// Return nil when:
	//   - External resource already matches desired state (no-op)
	//   - External resource was successfully created or updated
	//   - Resource is still provisioning (check again next cycle)
	//   - Declaration kind is unknown (log a warning, skip, return nil)
	//
	// Return non-nil error when:
	//   - External API is unreachable
	//   - Credentials are invalid or expired
	//   - A hard quota is exceeded
	//   - Any condition that will not resolve on the next retry without intervention
	Reconcile(ctx context.Context, req ReconcileRequest) error

	// Delete is called during finalizer execution before the CR is removed.
	// It should delete all external resources created for this CR.
	// Must be idempotent — if the resource does not exist, return nil.
	//
	// The finalizer is NOT removed until Delete returns nil.
	// Returning an error leaves the CR stuck in deletion — ensure
	// transient errors are retried and permanent errors are surfaced clearly.
	Delete(ctx context.Context, req DeleteRequest) error
}

Provider handles one named block in the Katalog's provider sections.

Implement this interface to extend Orkestra with external resource management. Register your implementation at startup via ProviderRegistry.Register.

Both Reconcile and Delete must be idempotent. They are called on every reconcile cycle and every finalizer execution respectively.

type ProviderBlock

type ProviderBlock struct {
	// Name is the provider block key — matches Provider.Name().
	Name string

	// Declarations is the ordered list of resource declarations in this block.
	// Each declaration specifies one external resource to manage.
	Declarations []RawProviderDeclaration
}

ProviderBlock is one named provider section from the operatorBox.providers map. The Name comes from the map key ("aws", "mongodb"). Declarations come from the list under that key.

This is the parsed, structured form used at runtime. The raw YAML map is parsed into this during Katalog loading.

func ParseProviderBlocks

func ParseProviderBlocks(raw map[string][]map[string]interface{}) ([]ProviderBlock, error)

ParseProviderBlocks converts the raw YAML map from the providers: key into a structured []ProviderBlock. Called during Katalog loading after YAML unmarshal.

Input (from YAML unmarshal):

map[string][]map[string]interface{}{
  "aws": [
    {"s3": {"bucket": "my-bucket", "region": "us-east-1"}},
    {"rds": {"instanceClass": "db.t3.micro", "engine": "postgres"}},
  ],
  "mongodb": [
    {"database": {"name": "mydb"}},
  ],
}

Output:

[]ProviderBlock{
  {Name: "aws", Declarations: [
    {Kind: "s3", Fields: {"bucket": "my-bucket", "region": "us-east-1"}},
    {Kind: "rds", Fields: {"instanceClass": "db.t3.micro", "engine": "postgres"}},
  ]},
  {Name: "mongodb", Declarations: [
    {Kind: "database", Fields: {"name": "mydb"}},
  ]},
}

type ProviderDeclaration

type ProviderDeclaration struct {
	// Kind is the first key in the YAML map entry: "rds", "s3", "product", "widget".
	Kind string

	// Fields are the resolved key-value pairs. Values are always strings —
	// template resolution produces strings; type conversion is the provider's
	// responsibility.
	Fields map[string]string
}

ProviderDeclaration is one resolved declaration from the YAML block.

For this Katalog block:

aws:
  - rds:
      instanceClass: "{{ .spec.instanceClass }}"
      engine: postgres
  - s3:
      bucket: "my-bucket"

Orkestra produces two ProviderDeclarations:

{Kind: "rds", Fields: {"instanceClass": "db.t3.micro", "engine": "postgres"}}
{Kind: "s3",  Fields: {"bucket": "my-bucket"}}

Template expressions have been resolved — Fields values are plain strings. Nested YAML maps are flattened with dot notation:

credentials:
  secretName: my-secret

becomes Fields["credentials.secretName"] = "my-secret"

func (ProviderDeclaration) Field

func (d ProviderDeclaration) Field(key, defaultValue string) string

Field returns a field value with a default if the key is absent.

func (ProviderDeclaration) Require

func (d ProviderDeclaration) Require(key string) (string, error)

Require returns a field value or an error if the key is absent or empty. Use for required fields that must be present for the provider to proceed.

type ProviderRegistry

type ProviderRegistry interface {
	// Register adds a provider. Panics if a provider with the same name is
	// already registered — fail fast at startup rather than silently ignoring.
	Register(p Provider)

	// Get returns the provider for the given block name and true, or nil and
	// false if no provider is registered for that name.
	Get(name string) (Provider, bool)

	// Names returns all registered provider names.
	// Used by the validator to warn on unknown blocks in the Katalog.
	Names() []string

	// Len returns the number of registered providers.
	Len() int
}

ProviderRegistry holds all registered providers. Thread-safe — providers are registered at startup and read concurrently during reconcile.

func NewProviderRegistry

func NewProviderRegistry() ProviderRegistry

NewProviderRegistry returns an empty ProviderRegistry.

func NoOpProviderRegistry

func NoOpProviderRegistry() ProviderRegistry

NoOpProviderRegistry returns a registry with no providers registered. Used in tests and in reconcilers that do not use provider blocks.

type Queue

type Queue struct {
	// Shared — use the shared default workqueue instead of a per-CRD queue.
	// Default: false (each CRD gets its own isolated queue).
	Shared *bool `yaml:"shared,omitempty" json:"shared,omitempty"`

	// MaxDepth — max items in the queue before new items are dropped.
	// 0 → uses QUEUE_DEPTH env var (default: 100).
	MaxDepth int `yaml:"maxDepth,omitempty" json:"maxDepth,omitempty" validate:"omitempty,gte=0"`

	// FailureThreshold — consecutive failures before CRD health degrades.
	// 0 → uses FAILURE_THRESHOLD env var.
	FailureThreshold int `yaml:"failureThreshold,omitempty" json:"failureThreshold,omitempty" validate:"omitempty,gte=0"`
}

type RawProviderDeclaration

type RawProviderDeclaration struct {
	// Kind is the resource type within the provider block.
	// Derived from the single key in the YAML map entry.
	// Examples: "s3", "rds", "route53", "database", "user", "collection"
	Kind string

	// Fields are the raw (unresolved) key-value pairs for this declaration.
	// Nested YAML maps are flattened with dot notation:
	//   credentials:
	//     secretName: my-secret
	// becomes Fields["credentials.secretName"] = "my-secret"
	//
	// Values may contain template expressions — resolved by the template
	// resolver before the provider is called.
	Fields map[string]string

	// Conditions are the when: conditions from this declaration (AND semantics).
	// Evaluated by Orkestra before calling the provider — declarations
	// whose conditions fail are removed from the list before dispatch.
	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`

	// AnyOf holds OR conditions — at least one must pass.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`
}

RawProviderDeclaration is one item in a provider block list. At parse time, template expressions are NOT yet resolved — they contain raw strings like "{{ .metadata.name }}" which are resolved at reconcile time.

YAML shape (one list item under aws: or mongodb:):

  • s3: bucket: "{{ .metadata.name }}-assets" region: "{{ .spec.region }}" versioning: "true" when:
  • field: spec.enableStorage equals: "true"

Parses into:

RawProviderDeclaration{
    Kind: "s3",
    Fields: map[string]string{
        "bucket":     "{{ .metadata.name }}-assets",
        "region":     "{{ .spec.region }}",
        "versioning": "true",
    },
    Conditions: []Condition{{Field: "spec.enableStorage", Equals: "true"}},
}

type ReconcileRequest

type ReconcileRequest struct {
	// Object is the full CR as an unstructured map.
	// Identical to the data available in Katalog template expressions.
	// Access patterns:
	//   spec:     obj["spec"].(map[string]interface{})["fieldName"]
	//   status:   obj["status"].(map[string]interface{})["phase"]
	//   children: obj["children"].(map[string]interface{})["deployment"]
	Object map[string]interface{}

	// Declarations are the pre-resolved provider block declarations.
	// Template expressions have already been evaluated against the CR.
	// Conditions have already been evaluated — only passing declarations arrive.
	// Each entry corresponds to one item in the YAML list.
	Declarations []ProviderDeclaration

	// Kube provides read-only access to cluster resources.
	// Use to read Secrets for credentials and ConfigMaps for configuration.
	Kube KubeReader

	// Logger is a structured logger pre-tagged with crd, resource, request_id.
	Logger zerolog.Logger

	// OwnerName is the CR's metadata.name.
	OwnerName string

	// OwnerNamespace is the CR's metadata.namespace.
	OwnerNamespace string
}

ReconcileRequest carries everything a provider needs for one reconcile cycle.

type RegistryRef

type RegistryRef struct {
	// Branch — track a branch (e.g. "main", "develop").
	// The latest commit on the branch is fetched.
	Branch string `yaml:"branch,omitempty" json:"branch,omitempty"`

	// Version — pin to a release tag (e.g. "v1.2.0", "v2").
	// Git tags are fetched — version is used as the tag name.
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// SHA — pin to an exact commit hash.
	// The full or partial SHA works (Git resolves partial SHAs).
	SHA string `yaml:"sha,omitempty" json:"sha,omitempty"`
}

RegistryRef declares how to resolve a specific item from the registry. Exactly one of Branch, SHA, or Version should be set. When none are set, defaults to the default branch of the registry.

Example:

website:
  branch: main        # track a branch

platform-namespace:
  version: v1.2.0     # pin to a release tag

application:
  sha: abc123def456   # pin to an exact commit

func (RegistryRef) IsDefault

func (r RegistryRef) IsDefault() bool

IsDefault reports whether no ref is explicitly set.

func (RegistryRef) Ref

func (r RegistryRef) Ref() string

Ref returns the effective git ref for this RegistryRef. Priority: SHA > Version > Branch > "main" (default).

type RegistrySource

type RegistrySource struct {
	// URL — the registry URL.
	//
	// Git:  https://github.com/myorg/orkestra-registry
	// OCI:  ghcr.io/orkspace/orkestra-registry/postgres
	//
	// Shorthand — embed version with @:
	//   ghcr.io/orkspace/orkestra-registry/postgres@v14
	//   https://github.com/myorg/registry@main
	//
	// When @ is present, Version field is ignored.
	URL string `yaml:"url" validate:"required" json:"url"`

	// Version — the version, tag, branch, or SHA to pull.
	//
	// For OCI:  semantic version tag    "v14", "v14.2.0"
	// For Git:  branch, tag, or SHA     "main", "v1.0.0", "abc123"
	//
	// Ignored when URL contains @.
	// Defaults to "main" for Git, "latest" for OCI when not set.
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// OCI — when true, pull the pattern as an OCI artifact.
	// When false (default), pull via Git clone or raw file fetch.
	//
	// OCI artifacts are pulled using the ORAS protocol.
	// GitHub and GitLab URLs with oci: false use raw file HTTP — no clone needed.
	// Other Git URLs with oci: false use git clone.
	OCI bool `yaml:"oci,omitempty" json:"oci,omitempty"`

	// UseKomposer — when true, load komposer.yaml from the pulled pattern.
	// When false (default), load katalog.yaml.
	//
	// Exactly one file is loaded — not both.
	//
	// UseKomposer: false (default)
	//   Use this when you want the CRD definitions and will override them
	//   inline in your own Komposer. This is the common case.
	//
	// UseKomposer: true
	//   Use this when you want to accept the upstream operator's full
	//   source tree as-is — their sources, their defaults, everything.
	//   Useful for internal teams with a canonical registry where the
	//   upstream Komposer is exactly what you want to run.
	//
	// Warning: loading a Komposer from a registry source means that
	// Komposer's own sources are also resolved. A Komposer that sources
	// other Katalogs will pull those too. Understand the upstream
	// dependency tree before enabling this.
	UseKomposer bool `yaml:"useKomposer,omitempty" json:"useKomposer,omitempty"`

	// Auth — optional authentication for the registry.
	// When empty, requests are unauthenticated.
	// Auth credentials are resolved from environment variables — never literals.
	Auth *FileSourceAuth `yaml:"auth,omitempty" json:"auth,omitempty"`

	// Katalog — map of katalog names to their version references.
	// Key: katalog name (directory name under registry/katalogs/).
	// Value: version reference (branch, sha, or version tag).
	Katalog map[string]RegistryRef `yaml:"katalog,omitempty" json:"katalog,omitempty"`
}

RegistrySource is one entry in imports.registry.

func (RegistrySource) ResolvedURL

func (r RegistrySource) ResolvedURL() (cleanURL, version string)

ResolvedURL returns the effective URL with the version extracted. Handles both the @ shorthand and the explicit Version field.

Returns (cleanURL, version). cleanURL is the URL without the @ suffix. version is the resolved version string (never empty).

func (RegistrySource) SourceFile

func (r RegistrySource) SourceFile() string

SourceFile returns the filename Orkestra should load after pulling the pattern. Either "katalog.yaml" or "komposer.yaml" — never both.

type ReplicaSetTemplateSource added in v0.2.3

type ReplicaSetTemplateSource struct {
	// Version — OrkestraRegistry implementation version to use. Omit for latest.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Name — ReplicaSet and primary container name.
	// Supports template expressions.
	// Default when omitted: "{{ .metadata.name }}-replicaset"
	Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"omitempty"`

	// Image — container image. Required (must be declared here or resolvable from CR).
	// Static:  "nginx:1.25"
	// Dynamic: "{{ .spec.image }}"
	Image string `yaml:"image" json:"image" validate:"omitempty"`

	// ImagePullSecrets is an optional list of references to secrets in the same namespace to use
	// for pulling any of the images used by this PodSpec.
	// If specified, these secrets will be passed to individual puller implementations for them to use.
	ImagePullSecrets []string `yaml:"imagePullSecrets,omitempty" json:"imagePullSecrets,omitempty" validate:"omitempty"`

	// Replicas — number of pod replicas as a string.
	// Static:  "3"
	// Dynamic: "{{ .spec.replicas }}"
	// Default: "1"
	Replicas string `yaml:"replicas,omitempty" json:"replicas,omitempty" validate:"omitempty"`

	// Port — primary container port as a string.
	// Static:  "8080"
	// Dynamic: "{{ .spec.port }}"
	// Omit to expose no port.
	Port string `yaml:"port,omitempty" json:"port,omitempty" validate:"omitempty"`

	// Protocol — network protocol for the container port.
	// Accepted values: TCP (default), UDP, SCTP. Omit to use TCP.
	Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty" validate:"omitempty"`

	// Namespace — target namespace for the ReplicaSet.
	// Default when omitted: "{{ .metadata.namespace }}" (same namespace as the CR).
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty" validate:"omitempty"`

	// Labels — applied to the ReplicaSet ObjectMeta and the pod template.
	// Label values support template expressions.
	// Orkestra always adds: managed-by=orkestra, orkestra-owner=<cr-name>
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`

	// Annotations — applied to the ReplicaSet ObjectMeta only.
	// Annotation values support template expressions.
	Annotations []ResourceLabel `yaml:"annotations,omitempty" json:"annotations,omitempty" validate:"omitempty"`

	// Resources — CPU and memory requests/limits for the primary container.
	// Set resources.profile for a named preset, or resources.requests/limits for
	// explicit values. Profile and explicit values are mutually exclusive.
	Resources *ResourceRequirements `yaml:"resources,omitempty" json:"resources,omitempty" validate:"omitempty"`

	// Env — environment variables for the primary container, in Kubernetes-native list format.
	Env EnvVarList `yaml:"env,omitempty" json:"env,omitempty"`

	EnvFrom *EnvFrom `yaml:"envFrom,omitempty" json:"envFrom,omitempty"`

	// NodeSelector is a selector which must be true for the pod to fit on a node.
	// Selector which must match a node's labels for the pod to be scheduled on that node.
	// More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
	// +optional
	// +mapType=atomic
	NodeSelector map[string]string `yaml:"nodeSelector,omitempty" json:"nodeSelector,omitempty"`

	// ServiceAccountName is the name of the ServiceAccount to use to run this pod.
	// More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
	// +optional
	ServiceAccountName string `yaml:"serviceAccountName,omitempty" json:"serviceAccountName,omitempty"`

	// Reconcile: true — also apply this declaration as drift correction on every
	// reconcile. Equivalent to declaring the same entry under both onCreate and
	// onReconcile. When false (default), only runs on onCreate (idempotent create).
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty" validate:"omitempty"`

	// Conditions (when) — AND semantics.
	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`

	// ForEach declares dynamic expansion over a list field.
	ForEach *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// AnyOf holds OR conditions — at least one must pass for this resource.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// WorkingDirectory sets the container's working directory (container.WorkingDir).
	WorkingDirectory string `yaml:"workingDirectory,omitempty" json:"workingDirectory,omitempty"`

	// Probes — startup, liveness, and readiness probe configuration.
	Probes *ProbesConfig `yaml:"probes,omitempty" json:"probes,omitempty"`

	// SecurityContext — container-level security settings.
	// Set securityContext.profile for a named preset (baseline, restricted, hardened)
	// or declare individual fields. Profile and explicit fields are mutually exclusive.
	SecurityContext *ContainerSecurityContext `yaml:"securityContext,omitempty" json:"securityContext,omitempty"`

	// PodSecurity — pod-level security settings applied to the pod spec.
	// Set podSecurity.profile for a named preset or declare individual fields.
	PodSecurity *PodSecurityContext `yaml:"podSecurity,omitempty" json:"podSecurity,omitempty"`

	// RollingUpdate — rolling update strategy for this ReplicaSet.
	// Set rollingUpdate.profile for a named preset (safe, fast, blue-green),
	// or declare maxSurge/maxUnavailable explicitly.
	RollingUpdate *RollingUpdateBehavior `yaml:"rollingUpdate,omitempty" json:"rollingUpdate,omitempty"`

	// Volumes — pod volumes available for mounting into the container.
	Volumes []VolumeSource `yaml:"volumes,omitempty" json:"volumes,omitempty"`

	// VolumeMounts — mounts for the primary container.
	VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

ReplicaSetTemplateSource declares one ReplicaSet to be managed by Orkestra.

Declare under onCreate to create the ReplicaSet on first reconcile. Declare under onReconcile to apply drift correction on every reconcile. Declare under both to get idempotent creation and drift correction together.

Minimal example — static values only:

onCreate:
  replicasets:
    - image: nginx:1.25
      replicas: "3"
      port: "8080"

Full example — dynamic values from the CR:

onCreate:
  replicasets:
    - name: "{{ .metadata.name }}-app"
      image: "{{ .spec.image }}"
      replicas: "{{ .spec.replicas }}"
      port: "{{ .spec.port }}"
      namespace: "{{ .metadata.namespace }}"
      labels:
        - key: app
          value: "{{ .metadata.name }}"
        - key: managed-by
          value: orkestra
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 500m
          memory: 512Mi

func (ReplicaSetTemplateSource) GetName added in v0.4.2

func (t ReplicaSetTemplateSource) GetName() string

func (ReplicaSetTemplateSource) GetPodSecurity added in v0.5.4

func (t ReplicaSetTemplateSource) GetPodSecurity() *PodSecurityContext

func (ReplicaSetTemplateSource) GetProbes added in v0.4.2

func (t ReplicaSetTemplateSource) GetProbes() *ProbesConfig

func (ReplicaSetTemplateSource) GetProtocol added in v0.6.2

func (t ReplicaSetTemplateSource) GetProtocol() string

func (ReplicaSetTemplateSource) GetResources added in v0.4.2

func (ReplicaSetTemplateSource) GetRollingUpdate added in v0.5.4

func (t ReplicaSetTemplateSource) GetRollingUpdate() *RollingUpdateBehavior

func (ReplicaSetTemplateSource) GetSecurityContext added in v0.5.4

func (t ReplicaSetTemplateSource) GetSecurityContext() *ContainerSecurityContext

func (ReplicaSetTemplateSource) GetSleep added in v0.4.2

func (t ReplicaSetTemplateSource) GetSleep() string

type ResourceLabel

type ResourceLabel struct {
	Key   string `yaml:"key" json:"key" validate:"required"`
	Value string `yaml:"value" json:"value" validate:"required"`
}

ResourceLabel is a single key-value label or annotation pair. When used in hook template declarations, values support Go text/template expressions evaluated against the live CR at reconcile time. e.g. {key: "app", value: "{{ .metadata.name }}"}

func (ResourceLabel) String

func (l ResourceLabel) String() string

type ResourceProfileEntry added in v0.4.2

type ResourceProfileEntry struct {
	Phase        string // "onCreate", "onReconcile", "onDelete"
	Resource     string // e.g. "Deployment", "StatefulSet"
	ResourceName string // template name field (may be empty)
	Profile      string // raw profile name as written in the katalog
	Mixed        bool   // true when profile is set alongside explicit requests/limits
}

ResourceProfileEntry describes a single resources.profile reference found in a HookTemplates resource. Used by validation to fail fast on unknown profiles and to enforce mutual exclusivity between profile and explicit resource fields.

type ResourceRequirements

type ResourceRequirements struct {
	Profile  string            `yaml:"profile,omitempty" json:"profile,omitempty" validate:"omitempty"`
	Requests map[string]string `yaml:"requests,omitempty" json:"requests,omitempty" validate:"omitempty"`
	Limits   map[string]string `yaml:"limits,omitempty" json:"limits,omitempty" validate:"omitempty"`
}

ResourceRequirements mirrors Kubernetes resource requests and limits. Values are static Kubernetes quantity strings — template expressions are not supported here. e.g. requests: {cpu: "100m", memory: "128Mi"}

Profile is mutually exclusive with Requests and Limits. When Profile is set, it expands into a complete ResourceRequirements at reconcile time.

type ResourceSelector

type ResourceSelector []ResourceLabel

func (ResourceSelector) String

func (s ResourceSelector) String() string

Stringifier

type RestrictedNamespaces

type RestrictedNamespaces []string

RestrictedNamespaces holds the set of restricted namespace patterns.

func (RestrictedNamespaces) IsRestricted

func (r RestrictedNamespaces) IsRestricted(namespace string) bool

IsRestricted reports whether a given namespace matches any restriction. Supports exact matches and simple glob patterns (* prefix or suffix).

func (RestrictedNamespaces) Merge

Merge combines two RestrictedNamespaces sets, deduplicating entries. Used when merging Komposer-level and CRD-level restrictions. Since restrictions are additive, a namespace restricted at any level is restricted at all levels — more specific levels cannot remove restrictions.

type RoleBindingTemplateSource added in v0.3.9

type RoleBindingTemplateSource struct {
	Version    string          `yaml:"version,omitempty" json:"version,omitempty"`
	Name       string          `yaml:"name,omitempty" json:"name,omitempty"`
	Namespace  string          `yaml:"namespace,omitempty" json:"namespace,omitempty"`
	Labels     []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty"`
	RoleRef    RoleRefSpec     `yaml:"roleRef,omitempty" json:"roleRef,omitempty"`
	Subjects   []SubjectSpec   `yaml:"subjects,omitempty" json:"subjects,omitempty"`
	Conditions []Condition     `yaml:"when,omitempty" json:"when,omitempty"`
	Reconcile  bool            `yaml:"reconcile,omitempty" json:"reconcile,omitempty"`
	ForEach    *ForEachSpec    `yaml:"forEach,omitempty" json:"forEach,omitempty"`
	AnyOf      []Condition     `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

RoleBindingTemplateSource declares one RoleBinding to be managed by Orkestra.

Example:

onCreate:
  roleBindings:
    - name: "{{ .metadata.name }}-rolebinding"
      namespace: "{{ .metadata.name }}-ns"
      roleRef:
        name: "{{ .metadata.name }}-role"
      subjects:
        - kind: ServiceAccount
          name: "{{ .metadata.name }}-sa"
          namespace: "{{ .metadata.name }}-ns"

func (RoleBindingTemplateSource) GetName added in v0.4.2

func (t RoleBindingTemplateSource) GetName() string

func (RoleBindingTemplateSource) GetSleep added in v0.4.2

func (t RoleBindingTemplateSource) GetSleep() string

type RoleRefSpec added in v0.3.9

type RoleRefSpec struct {
	Name string `yaml:"name,omitempty" json:"name,omitempty"`
	Kind string `yaml:"kind,omitempty" json:"kind,omitempty"` // Role | ClusterRole; defaults to Role
}

RoleRefSpec names the Role (or ClusterRole) being bound. Name supports template expressions. Kind defaults to "Role".

type RoleTemplateSource added in v0.3.9

type RoleTemplateSource struct {
	Version    string           `yaml:"version,omitempty" json:"version,omitempty"`
	Name       string           `yaml:"name,omitempty" json:"name,omitempty"`
	Namespace  string           `yaml:"namespace,omitempty" json:"namespace,omitempty"`
	Labels     []ResourceLabel  `yaml:"labels,omitempty" json:"labels,omitempty"`
	Rules      []PolicyRuleSpec `yaml:"rules,omitempty" json:"rules,omitempty"`
	Conditions []Condition      `yaml:"when,omitempty" json:"when,omitempty"`
	Reconcile  bool             `yaml:"reconcile,omitempty" json:"reconcile,omitempty"`
	ForEach    *ForEachSpec     `yaml:"forEach,omitempty" json:"forEach,omitempty"`
	AnyOf      []Condition      `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

RoleTemplateSource declares one namespaced Role to be managed by Orkestra.

Example:

onCreate:
  roles:
    - name: "{{ .metadata.name }}-role"
      namespace: "{{ .metadata.name }}-ns"
      rules:
        - apiGroups: ["apps"]
          resources: ["deployments"]
          verbs: ["get", "list", "watch", "update", "patch"]
          resourceNames: ["{{ .metadata.name }}"]

func (RoleTemplateSource) GetName added in v0.4.2

func (t RoleTemplateSource) GetName() string

func (RoleTemplateSource) GetSleep added in v0.4.2

func (t RoleTemplateSource) GetSleep() string

type RollbackBlock added in v0.1.9

type RollbackBlock struct {
	// Trigger declares when rollback activates.
	// Both fields are optional — set one or both.
	// When both are set: triggers when ConsecutiveFailures failures
	// occur AND those failures all happened within WithinDuration.
	Trigger RollbackTrigger `yaml:"trigger" json:"trigger"`

	// OnRollback declares the resource groups to apply when rollback is active.
	// Uses the same grammar as OnReconcile — deployments, services, configMaps, etc.
	// Templates may reference .previous.spec.*, .previous.metadata.*, etc.
	// which are hydrated from the previous-spec annotation.
	OnRollback *HookTemplates `yaml:"onRollback,omitempty" json:"onRollback,omitempty"`
}

RollbackBlock declares the rollback behavior for one operatorbox. Declared inside OperatorBoxConfig as Rollback *RollbackBlock.

type RollbackPhase added in v0.1.9

type RollbackPhase string

RollbackPhase represents the reconciler's rollback state machine. Stored in status.phase — the reconciler reads this on every cycle.

const (
	// RollbackPhaseNone — normal reconciliation, no rollback active.
	RollbackPhaseNone RollbackPhase = ""

	// RollbackPhaseActive — rollback is active. Normal reconciliation blocked.
	// The previous spec is being applied. Exits when spec generation changes.
	RollbackPhaseActive RollbackPhase = "RolledBack"
)

type RollbackTrigger added in v0.1.9

type RollbackTrigger struct {
	// ConsecutiveFailures is the number of consecutive reconcile failures
	// that triggers rollback. Default: 3.
	ConsecutiveFailures int `yaml:"consecutiveFailures,omitempty" json:"consecutiveFailures,omitempty"`

	// WithinDuration is the time window within which ConsecutiveFailures
	// must occur for rollback to trigger.
	// When omitted: any ConsecutiveFailures consecutive failures trigger rollback,
	// regardless of how long ago the first failure occurred.
	// When set: only triggers if all failures occurred within this window.
	// Example: 3 failures within 5m = trigger; 3 failures over 2 hours = no trigger.
	WithinDuration *Duration `yaml:"withinDuration,omitempty" json:"withinDuration,omitempty"`
}

RollbackTrigger declares the conditions that activate rollback.

func (*RollbackTrigger) EffectiveConsecutiveFailures added in v0.1.9

func (t *RollbackTrigger) EffectiveConsecutiveFailures() int

EffectiveConsecutiveFailures returns the consecutive failure threshold, applying the default of 3 when not declared.

func (*RollbackTrigger) ShouldTrigger added in v0.1.9

func (t *RollbackTrigger) ShouldTrigger(failureTimes []time.Time) bool

ShouldTrigger returns true when the failure history meets the rollback criteria.

failures is the list of failure timestamps in reverse chronological order (most recent first). The function checks whether the required number of consecutive failures have occurred within the configured window.

type RollingUpdateBehavior added in v0.5.4

type RollingUpdateBehavior struct {
	// Profile — named preset. Expands into MaxSurge and MaxUnavailable at load time.
	// Allowed: safe, fast, blue-green.
	Profile string `yaml:"profile,omitempty" json:"profile,omitempty"`

	// MaxSurge — maximum pods that can be scheduled above the desired replica count
	// during a rolling update. Accepts integer string ("1") or percentage string ("25%").
	MaxSurge string `yaml:"maxSurge,omitempty" json:"maxSurge,omitempty"`

	// MaxUnavailable — maximum pods that can be unavailable during a rolling update.
	// Accepts integer string ("0") or percentage string ("25%").
	MaxUnavailable string `yaml:"maxUnavailable,omitempty" json:"maxUnavailable,omitempty"`
}

RollingUpdateBehavior configures a Deployment's rolling update strategy. Set Profile for a named preset, or MaxSurge/MaxUnavailable explicitly. Profile and explicit fields are mutually exclusive.

type RollingUpdateProfileEntry added in v0.5.4

type RollingUpdateProfileEntry struct {
	Phase        string // "onCreate", "onReconcile", "onDelete"
	ResourceName string // Deployment name template (may be empty)
	Profile      string // raw profile name as written in the katalog
	Mixed        bool   // true when profile is set alongside explicit maxSurge or maxUnavailable
}

RollingUpdateProfileEntry describes a single rollingUpdate.profile reference found in a DeploymentTemplateSource. Used by katalog validation to fail fast on unknown profiles and to enforce mutual exclusivity with explicit maxSurge/maxUnavailable.

type ScaleTargetRef added in v0.2.3

type ScaleTargetRef struct {
	APIVersion string `yaml:"apiVersion" json:"apiVersion"`
	Kind       string `yaml:"kind" json:"kind"`
	Name       string `yaml:"name" json:"name"`
}

type SecretKeyRef

type SecretKeyRef struct {
	Name string `yaml:"name" json:"name"`
	Key  string `yaml:"key" json:"key"`
}

SecretKeyRef selects a key from a Kubernetes Secret. Both Name and Key are required.

type SecretTemplateSource

type SecretTemplateSource struct {
	// Version — OrkestraRegistry implementation version. Omit for latest.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Name — Secret name.
	// Default when omitted: "{{ .metadata.name }}-secret"
	Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"omitempty"`

	// Namespace — target namespace.
	// Default when omitted: "{{ .metadata.namespace }}"
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty" validate:"omitempty"`

	// Type — Kubernetes Secret type.
	// Default: "Opaque"
	Type string `yaml:"type,omitempty" json:"type,omitempty" validate:"omitempty"`

	// Data — static key-value entries.
	// Values are plain strings — template expressions are not supported here.
	// If you need templated or dynamic values, use a custom Go hook.
	Data map[string]string `yaml:"data,omitempty" json:"data,omitempty" validate:"omitempty"`

	// Labels — applied to Secret metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`

	// Annotations — applied to Secret metadata.
	Annotations map[string]string `yaml:"annotations,omitempty" json:"annotations,omitempty"`

	// FromSecret — name of an existing Secret to copy data from.
	// Orkestra reads this at reconcile time — copies stay in sync with the source.
	FromSecret string `yaml:"fromSecret,omitempty" json:"fromSecret,omitempty" validate:"omitempty"`

	// FromNamespace — namespace where FromSecret lives.
	// Default: same namespace as the CR.
	FromNamespace string `yaml:"fromNamespace,omitempty" json:"fromNamespace,omitempty" validate:"omitempty"`

	// ToNamespaces - a list of target namespaces
	// Default when omitted: "{{ .metadata.namespace }}"
	ToNamespaces []string `yaml:"toNamespaces,omitempty" json:"toNamespaces,omitempty" validate:"omitempty"`

	// Reconcile: true — also apply this declaration as drift correction on every
	// reconcile. Equivalent to declaring the same entry under both onCreate and
	// onReconcile. When false (default), only runs on onCreate (idempotent create).
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty" validate:"omitempty"`

	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`

	// ForEach declares dynamic expansion (same as other resource types)
	ForEach *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// AnyOf holds OR conditions (same as other resource types)
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// Once controls idempotent secret generation.
	// true  — evaluate templates and create only when the Secret does not exist.
	//         Use with random notes (randomAlphanumeric, randomHex, randomBase64).
	// false — standard create/update behavior (default).
	Once bool `yaml:"once,omitempty" json:"once,omitempty"`

	// RotateAfter declares a time-based rotation threshold.
	// When set alongside once: true, the Secret is recreated when its age
	// exceeds this duration. The creation time is tracked via the annotation:
	//   orkestra.orkspace.io/generated-at: "2026-04-06T08:00:00Z"
	//
	// Supported formats: 30s, 5m, 12h, 90d, 1y
	// Days (d) and years (y) are extensions beyond Go's standard duration format.
	//
	// Example:
	//   secrets:
	//     - name: "{{ .metadata.name }}-credentials"
	//       once: true
	//       rotateAfter: 90d
	//       data:
	//         password: "{{ randomAlphanumeric 32 }}"
	RotateAfter string `yaml:"rotateAfter,omitempty" json:"rotateAfter,omitempty"`

	// TLS declares self-signed CA and server certificate generation.
	// When set, the data: block is ignored — the Secret is created as type
	// kubernetes.io/tls with fields: tls.crt, tls.key, ca.crt
	//
	// Default Secret name when name is empty: "orkestra-tls"
	// Default validFor when empty: same as rotateAfter, or "1y"
	//
	// Example:
	//   secrets:
	//     - name: "{{ .metadata.name }}-tls"
	//       once: true
	//       rotateAfter: 1y
	//       tls:
	//         commonName: "{{ .metadata.name }}.{{ .metadata.namespace }}.svc"
	//         dnsNames:
	//           - "{{ .metadata.name }}"
	//           - "{{ .metadata.name }}.{{ .metadata.namespace }}"
	//           - "{{ .metadata.name }}.{{ .metadata.namespace }}.svc"
	//           - "{{ .metadata.name }}.{{ .metadata.namespace }}.svc.cluster.local"
	//         validFor: 1y
	TLS *TLSSpec `yaml:"tls,omitempty" json:"tls,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

SecretTemplateSource declares one Secret to be managed by Orkestra.

Secret data values are static — template expressions are not evaluated in Secret data entries. For dynamic configuration, use a custom Go hook.

Example:

onCreate:
  secrets:
    - name: "{{ .metadata.name }}-credentials"
      type: Opaque
      data:
        USERNAME: admin
        PASSWORD: "supersecret"

You may also copy from an existing Secret using FromSecret.

func (SecretTemplateSource) GetName added in v0.4.2

func (t SecretTemplateSource) GetName() string

func (SecretTemplateSource) GetSleep added in v0.4.2

func (t SecretTemplateSource) GetSleep() string

Config & identity

type SecretVolumeSource added in v0.6.2

type SecretVolumeSource struct {
	// Name — Secret name. Supports template expressions.
	//   name: "{{ .metadata.name }}-creds"
	Name string `yaml:"name" json:"name"`
}

SecretVolumeSource mounts a Secret as a volume.

type SecurityProfileEntry added in v0.5.4

type SecurityProfileEntry struct {
	Phase        string // "onCreate", "onReconcile", "onDelete"
	Resource     string // e.g. "Deployment", "StatefulSet"
	ResourceName string // template name field (may be empty)
	Kind         string // "container" or "pod"
	Profile      string // raw profile name as written in the katalog
	Mixed        bool   // true when profile is set alongside explicit fields
}

SecurityProfileEntry describes a single security profile reference found in a HookTemplates resource. Used by validation to fail fast on unknown profiles and to enforce mutual exclusivity between profile and explicit security fields.

type SelectorMap

type SelectorMap map[string]string

Selector map

func (SelectorMap) String

func (m SelectorMap) String() string

Stringifier

type ServiceAccountTemplateSource

type ServiceAccountTemplateSource struct {
	// Version — OrkestraRegistry implementation version. Omit for latest.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Name — ServiceAccount name.
	// Default when omitted: "{{ .metadata.name }}-sa"
	Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"omitempty"`

	// Namespace — target namespace.
	// Default when omitted: "{{ .metadata.namespace }}"
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty" validate:"omitempty"`

	// Labels — applied to ServiceAccount metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`

	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`

	// Reconcile: true — also apply this declaration as drift correction on every
	// reconcile. Equivalent to declaring the same entry under both onCreate and
	// onReconcile. When false (default), only runs on onCreate (idempotent create).
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty" validate:"omitempty"`

	// ForEach declares dynamic expansion over a list field.
	// When set, one source declaration becomes N declarations — one per list element.
	// .item and .<as> are available in template expressions within this declaration.
	ForEach *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// AnyOf holds OR conditions — at least one must pass for this resource to be created.
	// Works alongside the existing Conditions (when:) field which uses AND semantics.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

ServiceAccountTemplateSource declares one ServiceAccount to be managed by Orkestra.

Example:

onCreate:
  serviceAccounts:
    - name: "{{ .metadata.name }}-sa"
      namespace: "{{ .metadata.namespace }}"
      labels:
        - key: app
          value: "{{ .metadata.name }}"

func (ServiceAccountTemplateSource) GetName added in v0.4.2

func (ServiceAccountTemplateSource) GetSleep added in v0.4.2

func (t ServiceAccountTemplateSource) GetSleep() string

type ServiceName added in v0.4.9

type ServiceName struct {
	// Runtime is the internal service name used by the operator and runtime
	// components. This is typically the name used for wiring and enrichment.
	Runtime string `json:"runtime,omitempty" yaml:"runtime,omitempty"`

	// Gateway is the externally visible service name used by ingress, gateway,
	// or routing layers. This may differ from the runtime name.
	Gateway string `json:"gateway,omitempty" yaml:"gateway,omitempty"`
}

ServiceName defines the canonical names used to reference a service within Orkestra. Runtime is the internal name used inside the operator, while Gateway is the externally exposed name used by ingress or gateway layers. Both fields are optional and omitted when empty.

type ServiceTemplateSource

type ServiceTemplateSource struct {
	// Version — OrkestraRegistry implementation version. Omit for latest.
	Version string `yaml:"version,omitempty" json:"version,omitempty" validate:"omitempty"`

	// Name — Service name.
	// Default when omitted: "{{ .metadata.name }}-svc"
	Name string `yaml:"name,omitempty" json:"name,omitempty" validate:"omitempty"`

	// Type — Kubernetes Service type.
	// Accepted values: ClusterIP, NodePort, LoadBalancer.
	// Default: ClusterIP.
	Type string `yaml:"type,omitempty" json:"type,omitempty" validate:"omitempty"`

	// Headless — when true, the Service is created without a clusterIP (clusterIP: None).
	// Used primarily for StatefulSets to enable stable network identities and per‑pod DNS:
	//   <podname>.<service>.<namespace>.svc.cluster.local
	// Set this to true when the Service is meant to back a StatefulSet or provide
	// direct pod‑to‑pod addressing rather than load‑balanced traffic.
	Headless bool `yaml:"headless,omitempty" json:"headless,omitempty" validate:"omitempty"`

	// Protocol defines network protocols supported for things like container ports.
	// "TCP", "UDP", "SCTP"
	Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty" validate:"omitempty"`

	// Port — Service port as a string.
	// Static: "80" or Dynamic: "{{ .spec.servicePort }}"
	Port string `yaml:"port" json:"port" validate:"omitempty"`

	// TargetPort — container port the Service routes traffic to.
	// Static: "8080" or Dynamic: "{{ .spec.containerPort }}"
	TargetPort string `yaml:"targetPort,omitempty" json:"targetPort,omitempty" validate:"omitempty"`

	// Namespace — target namespace.
	// Default when omitted: "{{ .metadata.namespace }}"
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty" validate:"omitempty"`

	// Labels — applied to Service metadata. Values support template expressions.
	Labels []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty" validate:"omitempty"`

	// Selector filters which pods this service will route traffic to
	// Useful in forEach situations where the labels would likely be the same
	Selector SelectorMap `yaml:"selector,omitempty" json:"selector,omitempty" validate:"omitempty"`

	// Reconcile: true — also apply this declaration as drift correction on every
	// reconcile. Equivalent to declaring the same entry under both onCreate and
	// onReconcile. When false (default), only runs on onCreate (idempotent create).
	Reconcile bool `yaml:"reconcile,omitempty" json:"reconcile,omitempty" validate:"omitempty"`

	Conditions []Condition `yaml:"when,omitempty" json:"when,omitempty"`

	// ForEach declares dynamic expansion over a list field.
	// When set, one source declaration becomes N declarations — one per list element.
	// .item and .<as> are available in template expressions within this declaration.
	ForEach *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// AnyOf holds OR conditions — at least one must pass for this resource to be created.
	// Works alongside the existing Conditions (when:) field which uses AND semantics.
	AnyOf []Condition `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

ServiceTemplateSource declares one Service to be managed by Orkestra.

Example:

onCreate:
  services:
    - name: "{{ .metadata.name }}-svc"
      type: ClusterIP
      port: "80"
      targetPort: "8080"
      namespace: "{{ .metadata.namespace }}"
      labels:
        - key: app
          value: "{{ .metadata.name }}"

func (ServiceTemplateSource) GetName added in v0.4.2

func (t ServiceTemplateSource) GetName() string

func (t DaemonSetTemplateSource) GetName() string { return t.Name }

func (ServiceTemplateSource) GetSleep added in v0.4.2

func (t ServiceTemplateSource) GetSleep() string

Services & networking

type SetupConfig added in v0.6.0

type SetupConfig struct {
	// Apply is an ordered list of YAML file paths to kubectl-apply.
	// Applied first, before helm installs, after the CRD is installed.
	Apply []string `yaml:"apply,omitempty"`

	// Helm is an ordered list of Helm charts to install before Orkestra starts.
	// Executed as helm upgrade --install — not rendered for Katalog extraction.
	Helm []SetupHelmInstall `yaml:"helm,omitempty"`

	// Wait blocks until all listed resources exist and satisfy conditions.
	// Runs last. If any wait times out, setup fails and the operator does not start.
	Wait []SetupWait `yaml:"wait,omitempty"`
}

SetupConfig declares prerequisite resources to apply before Orkestra starts.

Shorthand — a plain list of strings is equivalent to setup.apply:

setup:
  - ./prereqs/secret.yaml

Struct form:

setup:
  apply:
    - ./prereqs/secret.yaml
  helm:
    - repo: https://charts.cert-manager.io
      chart: cert-manager
      version: v1.14.0
  wait:
    - kind: Deployment
      name: cert-manager
      namespace: cert-manager
      ready: true
      timeout: 120s

func (*SetupConfig) UnmarshalYAML added in v0.6.0

func (s *SetupConfig) UnmarshalYAML(value *yaml.Node) error

UnmarshalYAML allows setup: to be written as either a plain list of strings (backward-compatible shorthand for setup.apply) or a full struct.

type SetupHelmInstall added in v0.6.0

type SetupHelmInstall struct {
	// Repo is the Helm repository URL.
	Repo string `yaml:"repo"`
	// Chart is the chart name within the repository.
	Chart string `yaml:"chart"`
	// Release is the Helm release name. Defaults to the chart name when empty.
	Release string `yaml:"release,omitempty"`
	// Namespace for the release. Defaults to "default".
	Namespace string `yaml:"namespace,omitempty"`
	// Version pins the chart version. Leave empty for latest.
	Version string `yaml:"version,omitempty"`
	// ValueFiles is an ordered list of values files (local paths or URLs).
	ValueFiles []string `yaml:"valueFiles,omitempty"`
	// Values are inline key-value overrides, equivalent to helm --set.
	Values map[string]interface{} `yaml:"values,omitempty"`
	// CreateNamespace passes --create-namespace to helm.
	CreateNamespace bool `yaml:"createNamespace,omitempty"`
}

SetupHelmInstall installs a Helm chart as a real release into the cluster. Unlike HelmSource (which renders charts to extract Katalog documents), this runs helm upgrade --install for a prerequisite chart.

func (SetupHelmInstall) EffectiveNamespace added in v0.6.0

func (h SetupHelmInstall) EffectiveNamespace() string

EffectiveNamespace returns the effective namespace, defaulting to "default".

func (SetupHelmInstall) ReleaseName added in v0.6.0

func (h SetupHelmInstall) ReleaseName() string

ReleaseName returns the effective Helm release name.

func (SetupHelmInstall) Validate added in v0.6.0

func (h SetupHelmInstall) Validate() error

Validate returns an error when required fields are missing.

type SetupWait added in v0.6.0

type SetupWait struct {
	// Kind is the Kubernetes resource kind (e.g. Deployment, Secret, Namespace).
	Kind string `yaml:"kind"`
	// Name is the exact resource name.
	Name string `yaml:"name"`
	// Namespace to look in. Omit for cluster-scoped resources.
	Namespace string `yaml:"namespace,omitempty"`
	// Ready waits for an available/ready condition, not just existence.
	Ready bool `yaml:"ready,omitempty"`
	// Timeout is a Go duration string. Default: "30s".
	Timeout string `yaml:"timeout,omitempty"`
}

SetupWait describes a single resource to wait for before the operator starts.

type Simulate added in v0.7.2

type Simulate struct {
	APIVersion string        `yaml:"apiVersion"`
	Kind       string        `yaml:"kind"`
	Metadata   SimulateMeta  `yaml:"metadata"`
	Imports    []string      `yaml:"imports,omitempty"`
	Spec       *SimulateSpec `yaml:"spec,omitempty"`
}

Simulate is the schema for simulate.yaml.

Without expect: it runs in op-print mode. With expect: it asserts that the reconciler produces the declared ops and reaches the declared steady state — the run passes or fails like a test.

Aggregator form (imports + no spec) runs each imported simulate.yaml as an independent test, reporting pass/fail for each.

type SimulateExpect added in v0.7.2

type SimulateExpect struct {
	Steady   *bool                      `yaml:"steady,omitempty"`
	SteadyAt *int                       `yaml:"steadyAt,omitempty"` // result.SteadyAt must be ≤ this
	NoErrors bool                       `yaml:"noErrors,omitempty"`
	Ops      []SimulateOpRule           `yaml:"ops,omitempty"`
	Absent   []SimulateOpRule           `yaml:"absent,omitempty"` // ops that must NOT appear
	CRDs     map[string]*SimulateExpect `yaml:"crds,omitempty"`
}

SimulateExpect declares what the reconciler must produce. Top-level fields apply to all CRDs; crds overrides per named CRD.

type SimulateMeta added in v0.7.2

type SimulateMeta struct {
	Name        string `yaml:"name"`
	Description string `yaml:"description,omitempty"`
}

type SimulateOpRule added in v0.7.2

type SimulateOpRule struct {
	Cycle    int    `yaml:"cycle"`
	Verb     string `yaml:"verb"`            // create | update | delete | patch
	Resource string `yaml:"resource"`        // deployments | statefulsets | etc.
	Name     string `yaml:"name,omitempty"`  // optional: match a specific resource name
	Count    int    `yaml:"count,omitempty"` // 0 = at least 1
}

SimulateOpRule asserts that at least one recorded op in the given cycle matches all non-empty fields. count overrides the minimum (default ≥1).

type SimulateSpec added in v0.7.2

type SimulateSpec struct {
	Katalog      string          `yaml:"katalog"`
	CR           string          `yaml:"cr"`
	Cycles       int             `yaml:"cycles,omitempty"` // default 10 when unset
	SkipExternal bool            `yaml:"skipExternal,omitempty"`
	Expect       *SimulateExpect `yaml:"expect,omitempty"` // nil = op-print only
}

type SleepEntry added in v0.4.2

type SleepEntry struct {
	Phase        string // "onCreate", "onReconcile", "onDelete"
	Resource     string // e.g., "Deployment", "Service", "Job"
	ResourceName string // template name field if available (may be empty)
	Duration     string // raw duration string as written in the katalog
}

SleepEntry describes a single sleep declaration found in a HookTemplates resource. It includes the phase (onCreate/onReconcile/onDelete), the resource type (for human diagnostics), an optional resource name (if present in the template), and the raw duration string.

type StatefulSetTemplateSource added in v0.1.9

type StatefulSetTemplateSource struct {
	Version string `yaml:"version,omitempty" json:"version,omitempty"`

	// Name — StatefulSet name. Default: "{{ .metadata.name }}".
	Name string `yaml:"name,omitempty" json:"name,omitempty"`

	// Namespace — target namespace. Default: CR namespace.
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`

	// Image — container image. Required.
	Image string `yaml:"image" json:"image" validate:"omitempty"`

	// ImagePullSecrets is an optional list of references to secrets in the same namespace to use
	// for pulling any of the images used by this PodSpec.
	// If specified, these secrets will be passed to individual puller implementations for them to use.
	ImagePullSecrets []string `yaml:"imagePullSecrets,omitempty" json:"imagePullSecrets,omitempty" validate:"omitempty"`

	// Tag — image tag. Default: "latest".
	Tag string `yaml:"tag,omitempty" json:"tag,omitempty"`

	// Replicas — number of pod replicas. Default: "1".
	Replicas string `yaml:"replicas,omitempty" json:"replicas,omitempty"`

	// Port — container port. "0" or empty means no port exposed.
	Port string `yaml:"port,omitempty" json:"port,omitempty"`

	// Protocol — network protocol for the container port.
	// Accepted values: TCP (default), UDP, SCTP. Omit to use TCP.
	Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty"`

	// ServiceName — name of the headless Service governing the StatefulSet.
	// Default: same as Name.
	ServiceName string `yaml:"serviceName,omitempty" json:"serviceName,omitempty"`

	// VolumeClaimTemplates — one or more PVC templates; each pod gets its own volume per entry.
	VolumeClaimTemplates []VolumeClaimTemplateSource `yaml:"volumeClaimTemplates,omitempty" json:"volumeClaimTemplates,omitempty"`

	// NodeSelector is a selector which must be true for the pod to fit on a node.
	// Selector which must match a node's labels for the pod to be scheduled on that node.
	// More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
	// +optional
	// +mapType=atomic
	NodeSelector map[string]string `yaml:"nodeSelector,omitempty" json:"nodeSelector,omitempty"`

	// ServiceAccountName is the name of the ServiceAccount to use to run this pod.
	// More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
	// +optional
	ServiceAccountName string `yaml:"serviceAccountName,omitempty" json:"serviceAccountName,omitempty"`

	Labels      []ResourceLabel `yaml:"labels,omitempty" json:"labels,omitempty"`
	Annotations []ResourceLabel `yaml:"annotations,omitempty" json:"annotations,omitempty"`
	Env         EnvVarList      `yaml:"env,omitempty" json:"env,omitempty"`
	EnvFrom     *EnvFrom        `yaml:"envFrom,omitempty" json:"envFrom,omitempty"`

	// Resources — CPU and memory requests/limits for the primary container.
	// Set resources.profile for a named preset, or resources.requests/limits for
	// explicit values. Profile and explicit values are mutually exclusive.
	Resources *ResourceRequirements `yaml:"resources,omitempty" json:"resources,omitempty" validate:"omitempty"`

	Reconcile  bool         `yaml:"reconcile,omitempty" json:"reconcile,omitempty"`
	Conditions []Condition  `yaml:"when,omitempty" json:"when,omitempty"`
	AnyOf      []Condition  `yaml:"anyOf,omitempty" json:"anyOf,omitempty"`
	ForEach    *ForEachSpec `yaml:"forEach,omitempty" json:"forEach,omitempty"`

	// Probes — startup, liveness, and readiness probe configuration.
	Probes *ProbesConfig `yaml:"probes,omitempty" json:"probes,omitempty"`

	// SecurityContext — container-level security settings.
	// Set securityContext.profile for a named preset (baseline, restricted, hardened)
	// or declare individual fields. Profile and explicit fields are mutually exclusive.
	SecurityContext *ContainerSecurityContext `yaml:"securityContext,omitempty" json:"securityContext,omitempty"`

	// PodSecurity — pod-level security settings applied to the pod spec.
	// Set podSecurity.profile for a named preset or declare individual fields.
	PodSecurity *PodSecurityContext `yaml:"podSecurity,omitempty" json:"podSecurity,omitempty"`

	// RollingUpdate — rolling update strategy for this StatefulSet.
	// Set rollingUpdate.profile for a named preset (safe, fast, blue-green),
	// or declare maxSurge/maxUnavailable explicitly.
	RollingUpdate *RollingUpdateBehavior `yaml:"rollingUpdate,omitempty" json:"rollingUpdate,omitempty"`

	// Volumes — pod volumes available for mounting into the container.
	Volumes []VolumeSource `yaml:"volumes,omitempty" json:"volumes,omitempty"`

	// VolumeMounts — mounts for the primary container.
	VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"`

	// Sleep injects an artificial delay into the reconcile of this resource.
	// Useful for autoscale testing, latency simulation, and chaos engineering.
	// Accepts extended duration units (s, m, h, d, w, mo, y).
	Sleep string `json:"sleep,omitempty" yaml:"sleep,omitempty"`
}

func (StatefulSetTemplateSource) GetName added in v0.4.2

func (t StatefulSetTemplateSource) GetName() string

func (StatefulSetTemplateSource) GetPodSecurity added in v0.5.4

func (t StatefulSetTemplateSource) GetPodSecurity() *PodSecurityContext

func (StatefulSetTemplateSource) GetProbes added in v0.4.2

func (t StatefulSetTemplateSource) GetProbes() *ProbesConfig

func (StatefulSetTemplateSource) GetProtocol added in v0.6.2

func (t StatefulSetTemplateSource) GetProtocol() string

func (StatefulSetTemplateSource) GetResources added in v0.4.2

func (StatefulSetTemplateSource) GetRollingUpdate added in v0.5.4

func (t StatefulSetTemplateSource) GetRollingUpdate() *RollingUpdateBehavior

func (StatefulSetTemplateSource) GetSecurityContext added in v0.5.4

func (t StatefulSetTemplateSource) GetSecurityContext() *ContainerSecurityContext

func (StatefulSetTemplateSource) GetSleep added in v0.4.2

func (t StatefulSetTemplateSource) GetSleep() string

type StatusConfig

type StatusConfig struct {
	// Fields — list of status fields to write after every successful reconcile.
	// Resolved in declaration order. Later fields win on path conflict.
	Fields []StatusFieldSpec `yaml:"fields,omitempty" json:"fields,omitempty"`

	// Conditions — whether to write the standard Ready condition automatically.
	// Default: true. Set to false to opt out of automatic condition management.
	// When true, Orkestra writes:
	//   status.conditions[type=Ready]:
	//     status: "True" | "False"
	//     reason: ReconcileSucceeded | ReconcileError
	//     message: "" | "<error message>"
	//     lastTransitionTime: <now>
	//   status.observedGeneration: <metadata.generation>
	//
	// Setting false is rarely needed. Do it only when your CRD's status
	// schema explicitly forbids a conditions field, or when you manage
	// conditions entirely via Go hooks.
	Conditions *bool `yaml:"conditions,omitempty" json:"conditions,omitempty"`
}

StatusConfig declares the declarative status behavior for a CRD. Declared under spec.crds[].reconciler.status in the Katalog.

func (*StatusConfig) ConditionsEnabled

func (s *StatusConfig) ConditionsEnabled() bool

ConditionsEnabled reports whether automatic standard condition management is on. Defaults to true when Conditions is nil.

func (*StatusConfig) HasFields

func (s *StatusConfig) HasFields() bool

HasFields reports whether any declarative status fields are declared.

type StatusFieldSpec

type StatusFieldSpec struct {
	// Path — dot-notation path relative to status.
	// "phase"            → status.phase
	// "database.host"    → status.database.host
	// "ready"            → status.ready
	Path string `yaml:"path" json:"path" validate:"required"`

	// Value — the value to write. Supports template expressions.
	// Resolved against the full CR object map at reconcile time.
	// Empty string is written as-is — declare a static empty string to clear a field.
	Value string `yaml:"value" json:"value"`

	// Type — optional explicit type for the resolved value.
	// If omitted, the value is written as a string.
	//
	// Supported values:
	//   "string", "str, "" (default)
	//   "int", "integer"
	//   "float"
	//   "bool", "boolean"
	//   "auto" — infer type from the resolved value
	Type string `yaml:"type,omitempty" json:"type,omitempty"`

	// When is an optional list of conditions that must all pass before
	// this field is written. If absent or empty, the field is always written.
	//
	// All conditions are AND-ed together.
	// To express OR logic, declare multiple StatusField entries for the same path.
	//
	// Conditions are evaluated against the full CR object map — the same
	// map available to template expressions. This means .status.phase,
	// .spec.image, .children.job.status.succeeded are all accessible.
	When []Condition `yaml:"when,omitempty"`

	// AnyOf — optional OR-conditions. If any condition passes, the field is written.
	// Useful for multi-branch declarative state machines.
	AnyOf []Condition `yaml:"anyOf,omitempty"`

	// ClearOnFalse — when true and the when:/anyOf: condition evaluates to false,
	// the field is explicitly written as "" rather than left untouched.
	// Use this for transient fields (e.g. crashReason) that should disappear
	// once the condition that produced them is no longer true.
	// Has no effect when no when:/anyOf: conditions are declared.
	ClearOnFalse bool `yaml:"clearOnFalse,omitempty" json:"clearOnFalse,omitempty"`
}

StatusFieldSpec declares one field to write into the CR's status.

Path is relative to the status subobject. "phase" writes to status.phase. "database.host" writes to status.database.host.

Value supports Go text/template expressions evaluated against the CR:

  • "{{ .spec.replicas }}" — from the CR's spec
  • "{{ .metadata.name }}" — CR name
  • "Running" — static string (fast path, no template parsing)

Type controls how the resolved value is written into the status patch. By default, all values are written as strings. When Type is set, the resolver will cast the resolved value into the requested type:

type: int       → writes an integer (e.g., 3)
type: float     → writes a float64 (e.g., 3.14)
type: bool      → writes a boolean (e.g., true)
type: string    → writes a string (default behavior)
type: auto      → attempts to infer the type from the resolved value

Example:

  • path: replicas type: int value: "{{ toInt .spec.replicas }}"

This ensures status.replicas is written as an integer, not a string.

type SubjectSpec added in v0.3.9

type SubjectSpec struct {
	Kind      string `yaml:"kind,omitempty" json:"kind,omitempty"`
	Name      string `yaml:"name,omitempty" json:"name,omitempty"`
	Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"`
}

SubjectSpec declares one RBAC subject for a RoleBinding. Name and Namespace support template expressions.

type TLSSpec

type TLSSpec struct {
	// CommonName is the certificate's CN field.
	//   commonName: "{{ .metadata.name }}.{{ .metadata.namespace }}.svc"
	CommonName string `yaml:"commonName" json:"commonName"`

	// DNSNames are the Subject Alternative Names.
	// Template expressions supported per entry.
	DNSNames []string `yaml:"dnsNames,omitempty" json:"dnsNames,omitempty"`

	// ValidFor is the certificate validity period.
	// Default: same as rotateAfter, or 1y if rotateAfter is not set.
	// Must be >= rotateAfter to avoid immediate expiry on rotation.
	ValidFor string `yaml:"validFor,omitempty" json:"validFor,omitempty"`

	// Organization is the cert's O field. Default: "orkestra"
	Organization string `yaml:"organization,omitempty" json:"organization,omitempty"`
}

TLSSpec declares TLS certificate generation for a secret. When set, the secret is created as type kubernetes.io/tls with tls.crt, tls.key, and ca.crt fields.

type TemplateEvaluator added in v0.6.0

type TemplateEvaluator func(tmpl string) (string, bool)

TemplateEvaluator evaluates a Go template expression against the current reconcile data map, including all note functions and enriched children. Returns (result, true) on success; ("", false) on any error. Implemented by the resolver package and injected at call sites. nil disables template evaluation — all existing callers are backward-compatible.

type TimeWindow

type TimeWindow struct {
	// After — active after this time (format: "HH:MM" in 24h).
	After string `yaml:"after,omitempty" json:"after,omitempty"`

	// Before — active before this time (format: "HH:MM" in 24h).
	Before string `yaml:"before,omitempty" json:"before,omitempty"`
}

TimeWindow declares a clock-based active window.

type ValidationAction

type ValidationAction string

ValidationAction declares what happens when a validation rule fails.

deny  (default) — at admission: synchronous rejection, kubectl sees the error
                  at reconcile: reconciliation halted until CR is corrected

warn            — at admission: Kubernetes Warning header, CR is still stored
                  at reconcile: recorded as active warning on health API

Default is deny when action is omitted. Warn must be declared explicitly. This is intentional — new rules block by default.

const (
	ValidationActionDeny ValidationAction = "deny"
	ValidationActionWarn ValidationAction = "warn"
)

func EffectiveAction

func EffectiveAction(a ValidationAction) ValidationAction

EffectiveAction returns the effective action, defaulting to deny.

func (ValidationAction) IsDeny

func (a ValidationAction) IsDeny() bool

func (ValidationAction) IsWarn

func (a ValidationAction) IsWarn() bool

type ValidationConfig

type ValidationConfig struct {
	// Rules — evaluated in declaration order.
	// All rules are evaluated before returning — all violations are reported
	// together so the user can fix everything in one cycle.
	Rules []ValidationRule `yaml:"rules,omitempty" json:"rules,omitempty"`
}

ValidationConfig holds all validation rules for a CRD.

func (*ValidationConfig) HasDenyRules

func (c *ValidationConfig) HasDenyRules() bool

HasDenyRules reports whether any rules use action: deny (or the default). Used to decide whether to register a ValidatingWebhookConfiguration.

func (*ValidationConfig) HasWarnRules

func (c *ValidationConfig) HasWarnRules() bool

HasWarnRules reports whether any rules use action: warn.

type ValidationRule

type ValidationRule struct {
	// Field — dot-notation path to the CR field being validated.
	// e.g. "spec.image", "metadata.labels.tier", "spec.db.engine"
	Field string `yaml:"field" json:"field" validate:"required"`

	// Message — shown in the Kubernetes event, webhook response, and operator
	// log when this rule is violated. Make it actionable.
	Message string `yaml:"message" json:"message" validate:"required"`

	// Action — what happens when this rule fails.
	// deny (default): block at admission, halt at reconcile.
	// warn: warning at admission, advisory at reconcile.
	Action ValidationAction `yaml:"action,omitempty" json:"action,omitempty"`

	// Shorthands — use these for the common cases.
	Equals      string `yaml:"equals,omitempty" json:"equals,omitempty"`
	NotEquals   string `yaml:"notEquals,omitempty" json:"notEquals,omitempty"`
	Prefix      string `yaml:"prefix,omitempty" json:"prefix,omitempty"`
	Suffix      string `yaml:"suffix,omitempty" json:"suffix,omitempty"`
	Contains    string `yaml:"contains,omitempty" json:"contains,omitempty"`
	Min         string `yaml:"min,omitempty" json:"min,omitempty"` // numeric, inclusive
	Max         string `yaml:"max,omitempty" json:"max,omitempty"` // numeric, inclusive
	GreaterThan string `yaml:"greaterThan,omitempty" json:"greaterThan,omitempty"`
	LessThan    string `yaml:"lessThan,omitempty" json:"lessThan,omitempty"`

	// Explicit operator form — use when no shorthand covers the comparison.
	Operator  ConditionOperator `yaml:"operator,omitempty" json:"operator,omitempty"`
	Value     string            `yaml:"value,omitempty" json:"value,omitempty"`
	ValueType string            `yaml:"valueType,omitempty"` // "string", "int" or "integer", "float" or "number", "bool" or "boolean"
}

ValidationRule declares one constraint on a CR field.

Shorthands (prefix, suffix, equals, etc.) exist so common rules read without boilerplate. Exactly one shorthand or an explicit operator+value pair should be set per rule.

Example — deny:

  • field: spec.image prefix: "myorg/" message: "image must be from myorg registry" action: deny

Example — warn, advisory only:

  • field: metadata.labels.team operator: exists message: "all resources should declare a team owner" action: warn

Example — numeric bound:

  • field: spec.replicas max: "10" message: "replicas cannot exceed 10"

type ValueFrom added in v0.4.7

type ValueFrom struct {
	SecretKeyRef    *SecretKeyRef    `yaml:"secretKeyRef,omitempty" json:"secretKeyRef,omitempty"`
	ConfigMapKeyRef *ConfigMapKeyRef `yaml:"configMapKeyRef,omitempty" json:"configMapKeyRef,omitempty"`
}

ValueFrom holds the source of an environment variable value. At most one field should be set.

type VolumeClaimTemplateSource added in v0.4.2

type VolumeClaimTemplateSource struct {
	// Name — PVC template name. Default: "data".
	Name string `yaml:"name,omitempty" json:"name,omitempty"`

	// StorageClass — storage class to provision from. Required.
	StorageClass string `yaml:"storageClass" json:"storageClass"`

	// StorageSize — requested storage size (e.g. "10Gi"). Required.
	StorageSize string `yaml:"storageSize" json:"storageSize"`

	// MountPath — path inside the container to mount this volume. Default: "/data".
	MountPath string `yaml:"mountPath,omitempty" json:"mountPath,omitempty"`

	// AccessModes — defaults to ["ReadWriteOnce"].
	AccessModes []string `yaml:"accessModes,omitempty" json:"accessModes,omitempty"`
}

StatefulSetTemplateSource declares one StatefulSet to be managed by Orkestra. VolumeClaimTemplateSource declares one PersistentVolumeClaim template for a StatefulSet. Each StatefulSet pod receives its own PVC created from this template.

type VolumeMount added in v0.6.2

type VolumeMount struct {
	// Name — matches a volume name declared in volumes:. Supports template expressions.
	Name string `yaml:"name" json:"name"`

	// MountPath — path inside the container where the volume is mounted.
	MountPath string `yaml:"mountPath" json:"mountPath"`

	// SubPath — path within the volume to mount. Defaults to "" (volume root).
	// Useful for mounting individual files from a ConfigMap or Secret.
	SubPath string `yaml:"subPath,omitempty" json:"subPath,omitempty"`

	// ReadOnly — mount the volume read-only. Default: false.
	ReadOnly bool `yaml:"readOnly,omitempty" json:"readOnly,omitempty"`
}

VolumeMount declares how a volume is mounted into the container.

type VolumeSource added in v0.6.2

type VolumeSource struct {
	// Name — volume name, referenced by volumeMounts. Supports template expressions.
	Name string `yaml:"name" json:"name"`

	// ConfigMap — mount a ConfigMap as a volume.
	ConfigMap *ConfigMapVolumeSource `yaml:"configMap,omitempty" json:"configMap,omitempty"`

	// Secret — mount a Secret as a volume.
	Secret *SecretVolumeSource `yaml:"secret,omitempty" json:"secret,omitempty"`

	// EmptyDir — an ephemeral empty directory. Exists for the lifetime of the pod.
	// Set to `{}` to use default settings.
	EmptyDir *EmptyDirVolumeSource `yaml:"emptyDir,omitempty" json:"emptyDir,omitempty"`

	// PersistentVolumeClaim — mount an existing PVC by claim name.
	PersistentVolumeClaim *PVCVolumeSource `yaml:"persistentVolumeClaim,omitempty" json:"persistentVolumeClaim,omitempty"`

	// HostPath — mount a file or directory from the host node's filesystem.
	// Use with care — host mounts are a security risk in multi-tenant clusters.
	HostPath *HostPathVolumeSource `yaml:"hostPath,omitempty" json:"hostPath,omitempty"`
}

VolumeSource declares one volume to attach to the pod. Exactly one of the source fields should be set.

type Warnings added in v0.5.3

type Warnings []string

Warnings holds non‑fatal validation messages for this CRD. Populated during Katalog validation (e.g., enrichment, deletion protection overrides).

func (*Warnings) AddWarning added in v0.5.3

func (w *Warnings) AddWarning(msg string)

AddWarning appends a warning message.

func (*Warnings) HasWarnings added in v0.5.3

func (w *Warnings) HasWarnings() bool

HasWarnings returns true if there are any warnings for this CRD.

func (*Warnings) MergeWarnings added in v0.5.3

func (w *Warnings) MergeWarnings(other Warnings)

MergeWarnings adds all warnings from another slice.

type WebhooksConfig

type WebhooksConfig struct {
	// Admission controls the ValidatingWebhookConfiguration and MutatingWebhookConfiguration.
	Admission *AdmissionWebhookToggle `yaml:"admission,omitempty" json:"admission,omitempty"`

	// FailurePolicy controls what the API server does when Orkestra is unreachable
	// for admission calls. "Fail" or "Ignore".
	// Default: WEBHOOKS_FAILURE_POLICY env / "Ignore".
	FailurePolicy string `yaml:"failurePolicy,omitempty" json:"failurePolicy,omitempty"`

	// ServiceName is the Kubernetes Service fronting Orkestra's HTTPS server.
	// Shared with deletion protection when both are enabled.
	// Default: ORK_SERVICE_NAME env / "orkestra".
	ServiceName string `yaml:"serviceName,omitempty" json:"serviceName,omitempty"`

	// CleanupOnShutdown controls whether Admission webhook is deleted on graceful shutdown.
	// Default: false — Admission webhook persists across restarts.
	CleanupOnShutdown bool `yaml:"cleanupOnShutdown,omitempty" json:"cleanupOnShutdown,omitempty"`
}

WebhooksConfig controls global admission webhook settings. Conversion is declared separately under security.conversion.

Jump to

Keyboard shortcuts

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