concepts

package
v0.18.1 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package concepts defines the core concepts for the operator component framework.

Index

Constants

This section is empty.

Variables

View Source
var ErrDataNotExtracted = errors.New("data not extracted")

ErrDataNotExtracted is returned (wrapped) by Data.Require when the cell has not been set during the current reconcile. Callers can match it with errors.Is to distinguish "not extracted yet" from other failures.

Functions

This section is empty.

Types

type Alive

type Alive interface {
	// ConvergingStatus returns the resource's current progress towards "Ready".
	// The provided ConvergingOperation helps the resource decide if it's currently Creating or Updating.
	ConvergingStatus(op ConvergingOperation) (AliveStatusWithReason, error)
}

Alive defines the contract for resources that have observable health and readiness. Resources implementing this interface contribute to the component's aggregate status. If a resource does NOT implement Alive, it is considered "Ready" as long as it exists.

type AliveConvergingStatus

type AliveConvergingStatus string

AliveConvergingStatus represents the transitional state of an alive resource as it moves towards "healthy".

const (
	// AliveConvergingStatusHealthy indicates the resource has reached its desired state and is fully operational.
	AliveConvergingStatusHealthy AliveConvergingStatus = "Healthy"
	// AliveConvergingStatusCreating indicates the resource is being created for the first time.
	AliveConvergingStatusCreating AliveConvergingStatus = "Creating"
	// AliveConvergingStatusUpdating indicates an existing resource is being updated with new configuration.
	AliveConvergingStatusUpdating AliveConvergingStatus = "Updating"
	// AliveConvergingStatusScaling indicates the resource is scaling its capacity (e.g., adding/removing replicas).
	AliveConvergingStatusScaling AliveConvergingStatus = "Scaling"
	// AliveConvergingStatusFailing indicates the resource is failing to converge to healthy.
	AliveConvergingStatusFailing AliveConvergingStatus = "Failing"
)

type AliveStatusWithReason

type AliveStatusWithReason struct {
	// Status is the status of the resource while converging towards healthy (can also be healthy).
	Status AliveConvergingStatus
	// Reason explains why the resource is currently healthy, Creating, Updating or Scaling.
	// Examples:
	//  - With Status=healthy: Deployment is healthy.
	//  - With Status=Created (ConvergingOperationCreated): Deployment has 2/3 healthy replicas.
	//  - With Status=Updated (ConvergingOperationUpdated): Deployment has 2/3 healthy replicas.
	//  - With Status=Scaling (ConvergingOperationNone): Deployment has 0/3 healthy replicas.
	//  - With Status=failing: failing to pull image
	Reason string
}

AliveStatusWithReason is the explanation of why the resource is or is not healthy at health checking time.

func StaleGenerationStatus

func StaleGenerationStatus(
	op ConvergingOperation, observedGeneration, generation int64, resourceKind string,
) *AliveStatusWithReason

StaleGenerationStatus checks whether a resource's controller has observed the latest spec by comparing ObservedGeneration against the object's Generation. If the controller is behind, it returns a non-nil AliveStatusWithReason with an appropriate Creating or Updating status. If the generation is current, it returns nil.

This should be called at the top of a DefaultConvergingStatusHandler before evaluating readiness fields, which may be stale when the controller has not yet reconciled the latest generation.

if status := concepts.StaleGenerationStatus(op, obj.Status.ObservedGeneration, obj.Generation, "deployment"); status != nil {
    return *status, nil
}

type Completable

type Completable interface {
	// ConvergingStatus returns the resource's current completion state.
	// The provided ConvergingOperation helps the resource decide its current status.
	ConvergingStatus(op ConvergingOperation) (CompletionStatusWithReason, error)
}

Completable defines the contract for resources that run to completion rather than being long-running. Resources implementing this interface contribute to the component's aggregate completion status.

type CompletionStatus

type CompletionStatus string

CompletionStatus represents the execution state of a resource that runs to completion (e.g., Jobs, Tasks).

const (
	// CompletionStatusCompleted indicates the resource has finished its execution successfully.
	CompletionStatusCompleted CompletionStatus = "Completed"
	// CompletionStatusRunning indicates the resource is currently running.
	CompletionStatusRunning CompletionStatus = "TaskRunning"
	// CompletionStatusPending indicates the resource is waiting to start.
	CompletionStatusPending CompletionStatus = "TaskPending"
	// CompletionStatusFailing indicates the resource has finished its execution with an error.
	CompletionStatusFailing CompletionStatus = "TaskFailing"
)

type CompletionStatusWithReason

type CompletionStatusWithReason struct {
	// Status is the current execution state of the resource.
	Status CompletionStatus
	// Reason explains why the resource is in the current status.
	// Examples:
	//  - With Status=Completed: Job has finished successfully.
	//  - With Status=TaskRunning: Job has 1/1 active pods.
	//  - With Status=TaskPending: Job is waiting for pods to be scheduled.
	//  - With Status=TaskFailing: Job failed with exit code 1.
	Reason string
}

CompletionStatusWithReason is the explanation of why the resource is in its current execution state.

type ConvergingOperation

type ConvergingOperation string

ConvergingOperation represents the result of a CreateOrUpdate operation on a resource. It provides context to the Alive interface to help determine the ConvergingStatus.

const (
	// ConvergingOperationCreated indicates that the resource was newly created.
	ConvergingOperationCreated ConvergingOperation = "Created"
	// ConvergingOperationUpdated indicates that an existing resource was updated.
	ConvergingOperationUpdated ConvergingOperation = "Updated"
	// ConvergingOperationNone indicates that no changes were made to the resource.
	ConvergingOperationNone ConvergingOperation = "None"
)

func ConvergingOperationFromOperationResult

func ConvergingOperationFromOperationResult(result controllerutil.OperationResult) ConvergingOperation

ConvergingOperationFromOperationResult maps a controllerutil.OperationResult to a ConvergingStatus.

type Data added in v0.18.0

type Data[T any] struct {
	// contains filtered or unexported fields
}

Data is a named, typed, presence-aware cell for intra-component data flow. A cell is written by a declared extraction (ExtractInto on a builder) and read by later resources' guards and mutations within the same reconcile.

Create cells inside the component assembly function so they stay scoped to a single reconcile. As a hardening, the owning component clears every declared cell at the start of each reconcile, so accidental reuse of a long-lived cell cannot leak state between reconciles. Sharing a cell across components is unsupported: validation and reset are per component.

The presence flag separates "not extracted" from "extracted as the zero value". There is deliberately no panicking accessor: reconciler code must degrade to conditions and requeues, never crash the manager.

func NewData added in v0.18.0

func NewData[T any](name string) *Data[T]

NewData creates a new, unset data cell with the given diagnostic name. Within one component, no two distinct cells may share a name; the component builder rejects the collision at Build time.

func (*Data[T]) Clear added in v0.18.0

func (d *Data[T]) Clear()

Clear resets the cell to unset and the zero value of T. Clear is called by the owning component at the start of each reconcile.

func (*Data[T]) Get added in v0.18.0

func (d *Data[T]) Get() (T, bool)

Get returns the cell's value and whether it has been set. When the cell is unset, the value is the zero value of T.

func (*Data[T]) IsSet added in v0.18.0

func (d *Data[T]) IsSet() bool

IsSet reports whether the cell currently holds an extracted value.

func (*Data[T]) Name added in v0.18.0

func (d *Data[T]) Name() string

Name returns the diagnostic name of the cell.

func (*Data[T]) Require added in v0.18.0

func (d *Data[T]) Require() (T, error)

Require returns the cell's value, or the zero value of T and an error wrapping ErrDataNotExtracted (naming the cell) when the cell is unset. Mutations propagate the error through their normal error path.

func (*Data[T]) Set added in v0.18.0

func (d *Data[T]) Set(value T)

Set stores a value in the cell and marks it present. Set is called by declared extractions (ExtractInto). The one supported manual use is a test seeding a cell before rendering a cluster-free preview; any other manual call bypasses topology validation and is unsupported.

type DataCell added in v0.18.0

type DataCell interface {
	// Name returns the diagnostic name of the cell. Cell identity is the
	// pointer; the name exists for validation messages and introspection.
	Name() string
	// IsSet reports whether the cell currently holds an extracted value.
	IsSet() bool
	// Clear resets the cell's value and presence. It is called by the owning
	// component at the start of each reconcile; calling it from user code is
	// unsupported.
	Clear()
}

DataCell is the non-generic view of a *Data[T] cell. It lets untyped code (builders, the component, introspection) hold heterogeneous cells without knowing their value type. Every *Data[T] satisfies it.

type DataConsumer added in v0.18.0

type DataConsumer interface {
	// ConsumedData returns the declared reads in declaration order.
	ConsumedData() []DataConsumption
}

DataConsumer is implemented by resources that declare data reads, either blocking (WithDataGuard) or optional (WithOptionalData).

type DataConsumption added in v0.18.0

type DataConsumption struct {
	// Cell is the cell being read.
	Cell DataCell
	// Optional reports the read mode: false means the resource blocks until
	// the cell is set (WithDataGuard); true means the resource proceeds and
	// reads opportunistically (WithOptionalData).
	Optional bool
}

DataConsumption records one declared read of a data cell by a resource.

type DataEdge added in v0.18.0

type DataEdge struct {
	// Data is the cell name.
	Data string
	// Producers lists the resource identities declaring a write, in
	// registration order.
	Producers []string
	// Guarded lists the resource identities blocking on the cell, in
	// registration order.
	Guarded []string
	// Optional lists the resource identities optionally reading the cell, in
	// registration order.
	Optional []string
}

DataEdge describes the declared flow of one data cell through a component: which resources write it and which resources read it.

type DataExtractable

type DataExtractable interface {
	// ExtractData runs the resource's declared data extractions against its
	// reconciled Kubernetes object, storing each computed value in its cell.
	ExtractData() error
}

DataExtractable is the runtime hook through which the component triggers a resource's declared data extractions (see ExtractInto on the builders). Extraction runs immediately after each resource is applied or fetched during reconciliation, so data extracted from one resource is available to subsequent resources' guards and mutations within the same cycle, and always before the final component condition is calculated.

All built-in primitives satisfy this through generic.BaseResource. User code does not call ExtractData; declare extractions on the builder instead.

type DataInspector added in v0.18.0

type DataInspector interface {
	// DataTopology returns one edge per declared cell, in first-producer
	// registration order.
	DataTopology() []DataEdge
}

DataInspector surfaces, read-only, the declared data topology of a built component. It is the data-flow counterpart of MutationInspector: an inert capability that nothing in the reconcile path calls, so importing it costs nothing at runtime.

type DataProducer added in v0.18.0

type DataProducer interface {
	// ProducedData returns the cells this resource extracts into, deduplicated,
	// in declaration order.
	ProducedData() []DataCell
}

DataProducer is implemented by resources that declare data extractions. The component builder uses it to validate that every consumed cell has a producer registered strictly earlier, and the component uses it to know which cells to clear at the start of each reconcile.

type GraceStatus

type GraceStatus string

GraceStatus represents the health of a resource after the allowed grace period has expired.

const (
	// GraceStatusHealthy indicates the resource is fully healthy after the grace period.
	GraceStatusHealthy = GraceStatus(AliveConvergingStatusHealthy)
	// GraceStatusDegraded indicates the resource is partially functional or in an intermediate state
	// after the grace period has expired.
	GraceStatusDegraded GraceStatus = "Degraded"
	// GraceStatusDown indicates the resource is completely non-functional after the grace period.
	GraceStatusDown GraceStatus = "Down"
)

func (GraceStatus) Priority

func (s GraceStatus) Priority() int

Priority returns the priority of the grace status. Higher values indicate more severe health issues. This is used for status aggregation: "Down" takes precedence over "Degraded", which takes precedence over "Healthy".

type GraceStatusWithReason

type GraceStatusWithReason struct {
	// Status is the status of the resource when the grace period expired.
	Status GraceStatus
	// Reason explains the reason why the resource is healthy, Down or Degraded at grace expiry.
	// Examples:
	//  - With Status=healthy: Deployment is healthy.
	//  - With Status=Degraded: Deployment has 2/3 healthy replicas.
	//  - With Status=Down: Deployment has 0/3 healthy replicas.
	Reason string
}

GraceStatusWithReason is the explanation of why the resource did or did not converge to healthy on grace expiry.

type Graceful

type Graceful interface {
	// GraceStatus returns the final health assessment after the component's grace period has expired.
	// The implementation should assume the grace period HAS expired and return its current state
	// (healthy, Degraded, or Down) without internal timing logic.
	GraceStatus() (GraceStatusWithReason, error)
}

Graceful defines the contract for resources which have time constrained convergence.

type GuardStatus added in v0.4.0

type GuardStatus string

GuardStatus represents whether a resource's guard precondition has been met.

const (
	// GuardStatusBlocked indicates that the resource's precondition is not yet satisfied.
	// The resource will not be applied and all resources registered after it are also skipped.
	GuardStatusBlocked GuardStatus = "Blocked"
	// GuardStatusUnblocked indicates that the resource's precondition is satisfied
	// and the resource can be applied normally.
	GuardStatusUnblocked GuardStatus = "Unblocked"
)

type GuardStatusWithReason added in v0.4.0

type GuardStatusWithReason struct {
	// Status is the guard evaluation result.
	Status GuardStatus
	// Reason provides a human-readable explanation of why the guard is in this state.
	Reason string
}

GuardStatusWithReason pairs a guard evaluation result with a human-readable explanation.

type Guardable added in v0.4.0

type Guardable interface {
	// GuardStatus evaluates the resource's precondition and returns whether
	// the resource is ready to be applied.
	GuardStatus() (GuardStatusWithReason, error)
}

Guardable defines the contract for resources that have preconditions which must be satisfied before the resource can be applied to the cluster.

When a guard evaluates to Blocked, the resource is not applied and all resources registered after it in the component are also skipped. The blocked reason is surfaced in the component's status condition.

Guards are not evaluated during suspension. Suspension proceeds regardless of guard state to ensure the component can always be fully deactivated.

type MutationInspector added in v0.14.0

type MutationInspector interface {
	// RegisteredMutations returns the Names of every mutation registered on the
	// unit, independent of the version it was built at. Names are unique within a
	// resource (the resource builder rejects a duplicate at build time), and the
	// returned list is deduplicated across a component's resources, so it is always
	// a set.
	RegisteredMutations() []string

	// FiringSet returns the Names of registered mutations whose gate is enabled
	// for the version the unit was built at. A mutation with a nil gate fires
	// unconditionally and is always included. It returns an error if any gate's
	// Enabled evaluation fails, since a swallowed gate error would silently
	// misclassify a version regime.
	FiringSet() ([]string, error)
}

MutationInspector surfaces, read-only, the mutations registered on a built resource or component and which of them fire at the version it was built at.

All built-in primitives satisfy this through generic.BaseResource, and the component aggregates its managed resources. It is an inert capability: nothing in the reconcile path calls it, so importing it costs nothing at runtime.

type ObservationRecorder added in v0.9.0

type ObservationRecorder interface {
	// RecordObservation stores the supplied object as the resource's most recently
	// observed cluster state. Subsequent calls to capabilities that inspect the
	// resource's state (such as ExtractData) operate against this object.
	RecordObservation(observed client.Object) error
}

ObservationRecorder defines the contract for resources whose internal state must be updated with what was just fetched from the cluster, before any subsequent inspection (most notably data extraction) takes place.

Read-only resources are constructed with a base object that typically carries only enough identifying metadata for the framework to fetch the live object. The fetched object must then be recorded back onto the resource so that capabilities such as DataExtractable observe the cluster state rather than the inert base.

Implementations should accept any object compatible with the resource's underlying type and return an error when the supplied object is not assignable to that type.

type Operational

type Operational interface {
	ConvergingStatus(op ConvergingOperation) (OperationalStatusWithReason, error)
}

Operational describes resources who are not necessarily alive but depend on assignments or other external dependencies to be considered operational. This can be services, ingresses, cronjob schedules, or any other resource who may be perceived as static but also depend on cluster-external factors.

type OperationalStatus

type OperationalStatus string

OperationalStatus represents the operational state of a resource.

const (
	// OperationalStatusOperational indicates the resource is fully operational.
	OperationalStatusOperational OperationalStatus = "Operational"
	// OperationalStatusPending indicates the resource is waiting to become operational.
	OperationalStatusPending OperationalStatus = "OperationPending"
	// OperationalStatusFailing indicates the resource is not operational.
	OperationalStatusFailing OperationalStatus = "OperationFailing"
)

type OperationalStatusWithReason

type OperationalStatusWithReason struct {
	// Status is the status of the resource while converging towards operational (can also be operational).
	Status OperationalStatus
	// Reason explains why the resource is currently 'Operational', 'Pending' or 'Failing'.
	// Examples:
	//  - With Status=Operational: Service load balancer IP address assigned.
	//  - With Status=Pending: Awaiting load balancer IP assignment.
	//  - With Status=Failing: Missing cloud provider annotation for load balancer assignment.
	Reason string
}

OperationalStatusWithReason is the explanation of why the resource is or is not operational at checking time.

type Previewable added in v0.11.0

type Previewable interface {
	// Preview renders the resource's desired state with all feature mutations
	// applied, leaving the resource's internal state untouched. Suspension
	// mutations are not applied; the preview reflects content state only.
	Preview() (client.Object, error)
}

Previewable is implemented by resources that can render their post-mutation desired state as a client.Object without contacting the cluster.

All built-in primitives satisfy this through generic.BaseResource. The component uses it to assemble a cluster-free preview of every managed resource it would apply (see the component package's Component.Preview).

type Suspendable

type Suspendable interface {
	// DeleteOnSuspend returns true if the resource should be deleted after suspension is complete.
	// Note: Suspend() and SuspensionStatus() are still called even if this returns true.
	// The resource must reach SuspensionStatusSuspended before it is actually deleted.
	// This allows for necessary cleanup or state persistence (e.g., ensuring disks are retained)
	// before the Kubernetes object is removed.
	DeleteOnSuspend() bool
	// Suspend applies suspension mutations to the resource's desired state.
	// The suspension intent MUST be stored in the wrapper's internal state and applied
	// during a subsequent Mutate() call.
	// Suspend MUST NOT mutate the Kubernetes cluster state directly.
	Suspend() error
	// SuspensionStatus returns the current progress of the suspension.
	// It is called after Suspend() to track when the resource has reached the desired state.
	SuspensionStatus() (SuspensionStatusWithReason, error)
}

Suspendable defines the contract for resources that support controlled suspension. Suspension can be achieved through deletion, mutations (like scaling to zero), or both. Any resource not implementing this interface is considered non-suspendable and remains active.

type SuspensionStatus

type SuspensionStatus string

SuspensionStatus is the status determined for the resource at suspension time. It represents the progress of a resource towards a fully suspended state.

const (
	// SuspensionStatusPending indicates that the suspension is waiting for a precondition to be met.
	SuspensionStatusPending SuspensionStatus = "PendingSuspension"
	// SuspensionStatusSuspending indicates that suspension is in progress but not yet completed.
	// For example, a Deployment might be scaling down its replicas.
	SuspensionStatusSuspending SuspensionStatus = "Suspending"
	// SuspensionStatusSuspended indicates that the suspension has successfully completed.
	SuspensionStatusSuspended SuspensionStatus = "Suspended"
)

func (SuspensionStatus) Priority

func (s SuspensionStatus) Priority() int

Priority returns the priority of the suspension status. Higher values indicate a state that is further from the desired "Suspended" state. This is used for status aggregation when multiple resources are being suspended.

type SuspensionStatusWithReason

type SuspensionStatusWithReason struct {
	// Status is the status of the resource while converging towards Suspended (can also be Suspended)
	Status SuspensionStatus
	// Reason explains the reason why the Status is currently PendingSuspension, Suspending or Suspended.
	// Examples:
	//  - With Status=PendingSuspension (SuspensionStatusPending): Waiting for statefulset observed generation to match generation.
	//  - With Status=Suspending (SuspensionStatusSuspending): Replicas scaling down. 1/3 replicas running.
	//  - With Status=Suspended (SuspensionStatusSuspended): Replicas scaled down to 0.
	Reason string
}

SuspensionStatusWithReason is the explanation of why the resource is or is not Suspended at suspension checking time.

Jump to

Keyboard shortcuts

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