runners

package
v0.7.9 Latest Latest
Warning

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

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

README

pkg/runners

Resource runners — one file per Kubernetes resource type.

Each runner takes a resolved list of template sources and applies them to the cluster: creating, updating, or deleting the corresponding Kubernetes objects according to the CR's declared state.

What lives here

File Resource
secrets.go Secret (includes once:, rotateAfter:, tls:, toNamespaces:)
configmaps.go ConfigMap (includes toNamespaces:, fromConfigMap:)
serviceaccounts.go ServiceAccount
roles.go Role
rolebindings.go RoleBinding
deployments.go Deployment
statefulsets.go StatefulSet
replicasets.go ReplicaSet
services.go Service
ingresses.go Ingress
jobs.go Job
cronjobs.go CronJob
pods.go Pod
pvcs.go PersistentVolumeClaim
pvs.go PersistentVolume
hpas.go HorizontalPodAutoscaler
pdbs.go PodDisruptionBudget
namespaces.go Namespace (create-only; no drift correction)
secrets_once.go Helper: once: guard, IsNotFoundErr
secret_tls.go Helper: TLS secret rotation

What does NOT live here

Runners that are specific to the reconciler's dispatch logic stay in pkg/reconciler/:

  • run_template_reconcile.go — the dispatcher that calls each runner in sequence
  • run_admission.go, run_validations.go, run_mutations.go — admission/validation/mutation pipeline
  • run_status.go — status field writing
  • run_namespace_guard.go — namespace allow/restrict enforcement
  • run_delete_ordered.go — sequential staged deletion
  • run_external.go, run_git.go, run_docker.go — external integration runners
  • run_providers.go, run_cross.go, run_customresource.go — provider and cross-CRD runners

Adding a new resource type

See docs/01-runner-contract.md for the canonical shape every runner must follow.

For the full end-to-end walkthrough (types → resource package → resolver → runner → dispatcher), see pkg/reconciler/docs/07-adding-a-resource.md.

Documentation

Overview

pkg/runners/clusterrolebindings.go

pkg/runners/clusterroles.go

pkg/runners/configmaps.go

pkg/runners/cronjobs.go

pkg/runners/deployments.go

pkg/runners/hpas.go

pkg/runners/ingresses.go

pkg/runners/jobs.go

pkg/runners/limitranges.go

pkg/runners/namespaces.go

pkg/runners/networkpolicies.go

pkg/runners/pdbs.go

pkg/runners/pods.go

pkg/runners/pvcs.go

pkg/runners/pvs.go

pkg/runners/replicasets.go

pkg/runners/resourcequotas.go

pkg/runners/rolebindings.go

pkg/runners/roles.go

pkg/runners/secret_tls.go

TLS certificate generation and secret rotation for Orkestra secrets.

Extends the once: true pattern with:

  • rotateAfter: <duration> — time-based rotation using a generated-at annotation
  • tls: {...} — self-signed CA + signed certificate generation

The generated Secret is annotated with:

orkestra.orkspace.io/generated-at: "2026-04-06T08:00:00Z"
orkestra.orkspace.io/rotate-after: "90d"

On each reconcile, secretNeedsRotation reads these annotations and returns true when the threshold is crossed. The caller deletes and recreates.

TLS generation produces a Secret of type kubernetes.io/tls with:

tls.crt — PEM-encoded signed certificate
tls.key — PEM-encoded private key (for the server)
ca.crt  — PEM-encoded self-signed CA certificate

The CA is unique per Secret — appropriate for self-signed operator webhooks. For shared CAs across multiple services, store the CA in a separate Secret and reference it (planned: ca.secretRef field).

pkg/runners/secrets.go

Adds to the previous version:

  • orktypes.EvaluateWhen instead of evaluateConditions (fixes anyOf: being ignored)
  • rotateAfter: <duration> support — time-based credential rotation
  • tls: {...} support — self-signed CA + signed certificate generation

Execution order per secret declaration:

  1. EvaluateWhen(when:, anyOf:) — skip if conditions fail
  2. Once/rotation check a. once: true, rotateAfter set — check annotation, delete if expired b. once: true, no rotateAfter — skip if exists c. once: false — standard create/update
  3. Resolve template expressions — randomAlphanumeric evaluated here
  4. TLS generation (if tls: is set) — generate CA + cert, skip data resolution
  5. Create/Update/CopyToNamespaces
  6. Annotate with generated-at — only when rotateAfter is set

pkg/runners/secrets_once.go

once: true on secrets — idempotent random secret generation.

The Kubernetes reconcile loop is called on every resync. A secret with random data (password, API key) would change every 30 seconds without the once: guard. once: true makes the create step check for existence first — if the Secret already exists, skip template evaluation entirely.

This is the check-before-generate pattern used by cert-manager and every other tool that generates credentials idempotently.

YAML:

secrets:
  - name: "{{ .metadata.name }}-credentials"
    once: true
    data:
      password: "{{ randomAlphanumeric 32 }}"
      apiKey:   "{{ randomHex 16 }}"
      jwtSecret: "{{ randomBase64 32 }}"

Behaviour:

  • First reconcile: Secret does not exist → evaluate templates → create
  • Every subsequent reconcile: Secret exists → skip completely (no-op)
  • CR deleted: Secret deleted via owner reference (garbage collection)

once: true is IGNORED when update=true (onReconcile with reconcile: true). A secret in onReconcile should use static or deterministic template values. Combining once: true with reconcile: true logs a warning and skips the once: guard — the caller opted into continuous reconciliation.

once: false (default): standard create/update behavior, unchanged.

pkg/runners/serviceaccounts.go

pkg/runners/services.go

pkg/runners/statefulsets.go

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsNotFoundErr

func IsNotFoundErr(err error) bool

IsNotFoundErr returns true when err is a Kubernetes 404 Not Found error.

func RunClusterRoleBindings added in v0.7.8

func RunClusterRoleBindings(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.ClusterRoleBindingTemplateSource,
	update bool,
) error

RunClusterRoleBindings resolves and applies ClusterRoleBinding template declarations.

ClusterRoleBindings are cluster-scoped — the namespace guard is not applied. Ownership is tracked via the orkestra.io/owner label; auto-GC via OwnerReferences is not possible for cluster-scoped resources.

func RunClusterRoles added in v0.7.8

func RunClusterRoles(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.ClusterRoleTemplateSource,
	update bool,
) error

RunClusterRoles resolves and applies ClusterRole template declarations.

ClusterRoles are cluster-scoped — the namespace guard is not applied. Ownership is tracked via the orkestra.io/owner label; auto-GC via OwnerReferences is not possible for cluster-scoped resources.

func RunConfigMaps

func RunConfigMaps(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.ConfigMapTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunConfigMaps resolves and applies ConfigMap template declarations.

ConfigMaps support the same fromConfigMap and toNamespaces patterns as Secrets:

fromConfigMap — copies data from an existing ConfigMap, with declared data entries overriding matching keys from the source. This is the "base config + environment override" pattern.

toNamespaces — creates one copy in each listed namespace.

reconcile: true — re-reads the source ConfigMap on every reconcile and syncs any changes. When logLevel changes in the CR spec, the ConfigMap in every namespace updates automatically.

func RunCronJobs

func RunCronJobs(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.CronJobTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunCronJobs resolves and applies CronJob template declarations.

CronJobs are long-lived scheduled resources — created under onCreate and drift-corrected under onReconcile (or reconcile: true).

Common use cases:

  • Periodic sync jobs (cache warming, data replication)
  • Scheduled backup jobs
  • Recurring cleanup or archival tasks
  • Health check or audit jobs on a schedule

The schedule field supports both static cron expressions and dynamic values from the CR spec:

schedule: "0 * * * *"               static — every hour
schedule: "{{ .spec.syncSchedule }}" dynamic — from CR spec

func RunDeployments

func RunDeployments(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.DeploymentTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunDeployments resolves and applies Deployment template declarations.

update=false onCreate path — idempotent Create update=true onReconcile path — Update for drift correction

reconcile: true on an onCreate entry means also call Update on that same reconcile loop — the shorthand for "create it and keep it in sync" without a separate onReconcile declaration.

func RunHPAs

func RunHPAs(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.HPATemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunHPAs resolves and applies HorizontalPodAutoscaler template declarations.

func RunIngresses

func RunIngresses(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.IngressTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunIngresses resolves and applies Ingress template declarations. When tls.enabled is true on an Ingress, a kubernetes.io/tls Secret is created before the Ingress so the Ingress can reference it immediately.

func RunJobs

func RunJobs(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.JobTemplateSource,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunJobs resolves and applies Job template declarations.

Jobs are fire-and-forget — they run once to completion and are not updated after creation. They are therefore always idempotent creates.

Jobs appear almost exclusively under onDelete for cleanup tasks that must complete before Orkestra removes finalizers:

  • Draining message queues before a consumer CR is deleted
  • Archiving state to external storage
  • Notifying external systems of deletion
  • Running database migrations before removing a schema CR

Jobs can also appear under onCreate for one-time provisioning tasks.

Owner references are NOT set on onDelete Jobs because the owner CR is being deleted — the Job must complete independently after the CR is gone.

func RunLimitRanges added in v0.7.8

func RunLimitRanges(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.LimitRangeTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunLimitRanges resolves and applies LimitRange template declarations.

limitRanges support fromLimitRange to copy an existing LimitRange's limits, and toNamespaces to distribute copies across multiple namespaces.

reconcile: true — re-reads the source LimitRange on every reconcile and syncs changes.

func RunNamespaces

func RunNamespaces(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.NamespaceTemplateSource,
	update bool,
) error

RunNamespaces resolves and applies Namespace template declarations.

Namespaces are create-only — there is nothing meaningful to update on a Namespace after creation (no spec fields that drift). They are therefore always idempotent creates regardless of whether this is called from onCreate or onReconcile.

Owner references ensure cleanup when the CR is deleted.

func RunNetworkPolicies added in v0.7.8

func RunNetworkPolicies(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.NetworkPolicyTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunNetworkPolicies resolves and applies NetworkPolicy template declarations.

networkPolicies support fromNetworkPolicy to copy an existing policy's spec, and toNamespaces to distribute copies across multiple namespaces.

reconcile: true — re-reads the source policy on every reconcile and syncs changes.

func RunPDBs

func RunPDBs(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.PDBTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunPDBs resolves and applies PodDisruptionBudget template declarations.

func RunPVCs

func RunPVCs(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.PVCTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunPVCs resolves and applies PersistentVolumeClaim template declarations.

func RunPVs

func RunPVs(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.PVTemplateSource,
	update bool,
) error

RunPVs resolves and applies PersistentVolume template declarations. PVs are cluster-scoped; the namespace guard is intentionally not applied.

func RunPods

func RunPods(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.PodTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunPods resolves and applies Pod template declarations.

update=false onCreate path — idempotent Create update=true onReconcile path — Update for drift correction (delete + recreate on image drift)

reconcile: true on an onCreate entry means also call Update on that same reconcile loop — the shorthand for "create it and keep it in sync" without a separate onReconcile declaration.

func RunReplicaSets

func RunReplicaSets(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.ReplicaSetTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunReplicaSets resolves and applies ReplicaSet template declarations.

update=false onCreate path — idempotent Create update=true onReconcile path — Update for drift correction

reconcile: true on an onCreate entry means also call Update on that same reconcile loop — the shorthand for "create it and keep it in sync" without a separate onReconcile declaration.

func RunResourceQuotas added in v0.7.8

func RunResourceQuotas(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.ResourceQuotaTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunResourceQuotas resolves and applies ResourceQuota template declarations.

resourceQuotas support fromResourceQuota to copy an existing quota's hard limits, and toNamespaces to distribute copies across multiple namespaces.

reconcile: true — re-reads the source quota on every reconcile and syncs changes.

func RunRoleBindings

func RunRoleBindings(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.RoleBindingTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunRoleBindings resolves and applies RoleBinding template declarations.

On onCreate: idempotent create only. On onReconcile (update=true): creates or updates (or recreates when roleRef changed). Owner references ensure cleanup when the CR is deleted.

func RunRoles

func RunRoles(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.RoleTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunRoles resolves and applies Role template declarations.

On onCreate: idempotent create only. On onReconcile (update=true): creates or updates rules on existing Roles. Owner references ensure cleanup when the CR is deleted.

func RunSecrets

func RunSecrets(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.SecretTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

func RunServiceAccounts

func RunServiceAccounts(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.ServiceAccountTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunServiceAccounts resolves and applies ServiceAccount template declarations.

ServiceAccounts are create-only — there is nothing meaningful to update on a ServiceAccount after creation (no spec fields that drift). They are therefore always idempotent creates regardless of whether this is called from onCreate or onReconcile.

Owner references ensure cleanup when the CR is deleted.

func RunServices

func RunServices(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.ServiceTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunServices resolves and applies Service template declarations. Same update/reconcile: true semantics as RunDeployments.

func RunStatefulSets

func RunStatefulSets(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	srcs []orktypes.StatefulSetTemplateSource,
	update bool,
	guard func(ctx context.Context, obj domain.Object, ns string) bool,
) error

RunStatefulSets resolves and applies StatefulSet template declarations.

func RunTLSSecret

func RunTLSSecret(
	ctx context.Context,
	kube kubeclient.KubeClient,
	resolver *orktmpl.Resolver,
	owner domain.Object,
	src orktypes.SecretTemplateSource,
	name, namespace string,
	update bool,
) error

RunTLSSecret handles the tls: path — generates a self-signed CA and server certificate and creates/updates a kubernetes.io/tls Secret.

Types

This section is empty.

Jump to

Keyboard shortcuts

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