Documentation
¶
Overview ¶
Package component provides the core framework for managing Kubernetes resources as logical components.
Index ¶
- Constants
- type Alive
- type Builder
- func (b *Builder) Build() (*Component, error)
- func (b *Builder) WithConditionType(conditionType ConditionType) *Builder
- func (b *Builder) WithGracePeriod(gracePeriod time.Duration) *Builder
- func (b *Builder) WithName(name string) *Builder
- func (b *Builder) WithResource(resource Resource, shouldDelete bool, readOnly bool) *Builder
- type Component
- type Condition
- type ConditionType
- type ConvergingOperation
- type ConvergingStatus
- type ConvergingStatusWithReason
- type DataExtractable
- type GraceStatus
- type GraceStatusWithReason
- type OperatorCRD
- type ReconcileContext
- type Recorder
- type Resource
- type Status
- type Suspendable
- type SuspensionStatus
- type SuspensionStatusWithReason
Constants ¶
const ( // Unknown indicates that the component has not been reconciled yet. Unknown Status = "Unknown" // Ready indicates that the component is fully provisioned // and operating as expected. Ready = Status(ConvergingStatusReady) // Creating indicates that the resource are being created. Creating = Status(ConvergingStatusCreating) // Scaling indicates that the resources are being scaled. Scaling = Status(ConvergingStatusScaling) // Updating indicates that the resources are being updated. Updating = Status(ConvergingStatusUpdating) // PendingSuspension indicates that the component is aware of the suspension request but has yet to begin suspension. PendingSuspension = Status(SuspensionStatusPending) // Suspending indicates that the component is converging towards a suspended state but is not yet fully suspended. Suspending = Status(SuspensionStatusSuspending) // Suspended indicates that the component is suspended. Suspended = Status(SuspensionStatusSuspended) // Degraded indicates that the component is degraded but operational. Degraded = Status(GraceStatusDegraded) // Down indicates that component is down and not operational. Down = Status(GraceStatusDown) // Error indicates that resource errors happened during reconciliation. Error Status = "Error" )
Variables ¶
This section is empty.
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) (ConvergingStatusWithReason, error)
// 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
// (Ready, Degraded, or Down) without internal timing logic.
GraceStatus() (GraceStatusWithReason, 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 Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder implements the fluent API for constructing and validating a Component. It ensures that a component is configured with consistent rules before it is used in a reconciliation loop.
func NewComponentBuilder ¶
NewComponentBuilder initializes a new Builder for creating a Component.
A Component manages a single condition on an owning object (the OperatorCRD) and aggregates the lifecycle, readiness, and suspension state of all registered resources.
Parameters:
- suspended: If true, the component starts in suspended mode, performing suspension logic instead of create/update operations during reconciliation until resumed.
The returned Builder allows for a fluent configuration of resources and grace periods. Validation of the name and condition type is performed immediately.
func (*Builder) Build ¶
Build finalizes the component configuration and validates all settings and resources added.
If any validation errors occurred during the fluent configuration (e.g., duplicate resources or invalid grace periods), Build returns a single aggregated error containing all failures using errors.Join.
Returns:
- *Component: The fully configured and validated component instance on success.
- error: An aggregated error containing all validation failures, or nil if successful.
func (*Builder) WithConditionType ¶
func (b *Builder) WithConditionType(conditionType ConditionType) *Builder
WithConditionType sets the Kubernetes condition type associated with this component.
This condition type will be updated on the owning object's status to reflect the aggregate state of all resources managed by this component.
Parameters:
- conditionType: The condition name (e.g., "WebInterfaceReady").
If the condition type is empty, a validation error is recorded and will be returned by Build().
func (*Builder) WithGracePeriod ¶
WithGracePeriod configures a grace duration for the component's convergence to a Ready state.
When a component is not Ready, it is considered to be in a progressing state (e.g., Creating, Updating, Scaling). The grace period defines how long the component is allowed to remain in these progressing states before it is considered Degraded or Down.
Once the grace period expires:
- If the aggregate resource state is Down or Degraded, the component condition transitions to that state.
- Resources that implement the Alive interface provide their specific grace status used for this aggregation.
Parameters:
- gracePeriod: The duration to allow for convergence. Must be non-negative.
func (*Builder) WithName ¶
WithName sets the name of the component for logging and status identification.
The name is used as the field name in the aggregation of status conditions and must be unique within the owning reconciler.
Parameters:
- name: A non-empty string identifying the component.
If the name is empty, a validation error is recorded and will be returned by Build().
func (*Builder) WithResource ¶
WithResource registers a Kubernetes resource to be managed by this component.
A resource can be in one of three categories:
- Creation/Update (default): The component ensures the resource exists and matches the desired state. Its health contributes to the component's Ready condition.
- Read-only: The component only reads the resource's state and uses it for status aggregation. It never modifies the resource in the cluster.
- Deletion: The component ensures the resource is deleted from the cluster.
Parameters:
- resource: The resource implementation to manage.
- shouldDelete: If true, the resource is marked for deletion.
- readOnly: If true, the resource is read-only (ignored if 'shouldDelete' is true).
If a resource with the same Identity() is already registered, a validation error is recorded and will be returned by Build().
type Component ¶
type Component struct {
// contains filtered or unexported fields
}
Component represents a logical grouping of Kubernetes resources that are reconciled together and reported as a single condition on an owning object.
A component is responsible for:
- Creating, updating, or reading its registered resources
- Aggregating resource-level readiness into a single converging status
- Managing optional grace-period behavior for degraded or down states
- Handling suspension, including mutation-based suspension and optional deletion
Each Component manages exactly one condition type on the owner and is reconciled independently of other components. Resources are registered during construction using WithResource and the configuration is finalized by calling Build().
func (*Component) GetCondition ¶
func (c *Component) GetCondition(owner OperatorCRD) Condition
GetCondition returns the current component condition from the owner object. It returns a synthetic "Unknown" condition if the condition is not yet present on the owner.
Note: Always reconcile before retrieving this condition to ensure it reflects the latest cluster state; otherwise, it may be stale.
func (*Component) GetName ¶
GetName returns the name of the component, which is used for logging and identification.
func (*Component) Reconcile ¶
func (c *Component) Reconcile(ctx context.Context, rec ReconcileContext) error
Reconcile converges the component to the desired state.
A component manages its own condition on the parent and updates it accordingly to represent currently observable facts about the component status.
Reconciliation follows these steps:
Suspension check: If the component is marked as suspended, it performs suspension of all registered creation resources, updates the status to reflect the suspension progress (PendingSuspension, Suspending, or Suspended), and finally processes any deletion resources.
Resource Creation/Update: If not suspended, it creates or updates all registered creation resources. If any resource creation fails, the component condition is set to Error and reconciliation stops.
Read-only Resources: Fetches the current state of all registered read-only resources from the cluster.
Status Aggregation: Collects converging status from all creation and read-only resources that implement the Alive interface.
Condition Update: Derives a new component condition using a stateful progression model that considers the aggregate resource status, the previous condition, and the configured grace period to avoid churn.
Resource Deletion: Finally, it deletes any resources registered for deletion.
type Condition ¶
Condition is a type alias for metav1.Condition. It represents a single condition for a component.
func (Condition) ComponentStatus ¶
ComponentStatus returns the component's internal status (Reason) from the condition.
func (Condition) ConditionType ¶
func (c Condition) ConditionType() ConditionType
ConditionType returns the component-specific type for the condition.
type ConditionType ¶
type ConditionType string
ConditionType represents the type of condition in the Kubernetes status. It is used to identify the specific component's condition on the owner CRD.
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" )
type ConvergingStatus ¶
type ConvergingStatus string
ConvergingStatus represents the transitional state of a resource as it moves towards "Ready".
const ( // ConvergingStatusReady indicates the resource has reached its desired state and is fully operational. ConvergingStatusReady ConvergingStatus = "Ready" // ConvergingStatusCreating indicates the resource is being created for the first time. ConvergingStatusCreating ConvergingStatus = "Creating" // ConvergingStatusUpdating indicates an existing resource is being updated with new configuration. ConvergingStatusUpdating ConvergingStatus = "Updating" // ConvergingStatusScaling indicates the resource is scaling its capacity (e.g., adding/removing replicas). ConvergingStatusScaling ConvergingStatus = "Scaling" )
type ConvergingStatusWithReason ¶
type ConvergingStatusWithReason struct {
// Status is the status of the resource while converging towards Ready (can also be Ready).
Status ConvergingStatus
// Reason explains why the resource is currently Ready, Creating, Updating or Scaling.
// Examples:
// - With Status=ConvergingStatusReady: Deployment is ready.
// - With Status=ConvergingStatusCreated (ConvergingOperationCreated): Deployment has 2/3 ready replicas.
// - With Status=ConvergingStatusUpdated (ConvergingOperationUpdated): Deployment has 2/3 ready replicas.
// - With Status=ConvergingStatusScaling (ConvergingOperationNone): Deployment has 0/3 ready replicas.
Reason string
}
ConvergingStatusWithReason is the explanation of why the resource is or is not Ready at converge time.
type DataExtractable ¶
type DataExtractable interface {
// ExtractData performs the data extraction from the resource's underlying Kubernetes object.
// The implementation should store the extracted data in its own fields or shared state
// where it can be accessed by the caller.
ExtractData() error
}
DataExtractable defines the contract for resources that need to expose internal data after they have been created, updated, or fetched from the cluster.
Implement this interface when a resource contains information (like generated credentials, endpoint URLs, or status fields) that needs to be pulled back into the operator's memory for use by other components or for updating the parent CRD's status.
Data extraction is intended to be an observational/read-only operation on the resource. It is triggered automatically during reconciliation after all resources have been synchronized with the cluster but before the final component condition is calculated.
type GraceStatus ¶
type GraceStatus string
GraceStatus represents the health of a resource after the allowed grace period has expired.
const ( // GraceStatusReady indicates the resource is fully healthy after the grace period. GraceStatusReady GraceStatus = "Ready" // 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" )
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 Ready, Down or Degraded at grace expiry.
// Examples:
// - With Status=Ready: Deployment is ready.
// - With Status=Degraded: Deployment has 2/3 ready replicas.
// - With Status=Down: Deployment has 0/3 ready replicas.
Reason string
}
GraceStatusWithReason is the explanation of why the resource did or did not converge to Ready on grace expiry.
type OperatorCRD ¶
type OperatorCRD interface {
client.Object
// GetStatusConditions returns a pointer to the slice of status conditions.
// This is used to read and update the component's status condition on the owner.
GetStatusConditions() *[]metav1.Condition
// GetKind returns the string representation of the CRD's Kind.
GetKind() string
}
OperatorCRD defines the interface for the custom resource that owns the component. It must support status conditions and provide its kind for recording purposes.
type ReconcileContext ¶
type ReconcileContext struct {
// Client is the Kubernetes client for resource operations.
Client client.Client
// Scheme is the runtime scheme for the operator.
Scheme *runtime.Scheme
// Recorder is the event recorder for publishing Kubernetes events.
Recorder record.EventRecorder
// Metrics is the recorder for status condition metrics.
Metrics Recorder
// Owner is the custom resource that owns and is updated by the components.
Owner OperatorCRD
}
ReconcileContext carries the dependencies and target object for a reconciliation loop.
type Recorder ¶
type Recorder interface {
// RecordConditionFor records a condition change for a specific object and kind.
RecordConditionFor(
kind string, object ocm.ObjectLike,
conditionType, conditionStatus, conditionReason string, lastTransitionTime time.Time,
extraLabelValues ...string,
)
}
Recorder is an interface for recording status condition changes as metrics.
type Resource ¶
type Resource interface {
// Mutate applies all applicable mutations on the resource retrieved from the kubernetes api.
//
// If the object exists: `current` is the object fetched from the API server.
// If it does not exist: `current` is the same base object returned by Object() and passed into CreateOrUpdate,
// not a fetched server object.
//
// The Resource implementation is responsible for applying all desired fields from its
// internal core state to the current resource before proceeding with feature mutations.
// Only fields that are defined as mutable by the k8s api server should be applied.
//
// The mutations are applied every time the component is reconciled.
Mutate(current client.Object) error
// Object returns a copy of the managed Kubernetes resource.
//
// The returned object's state depends on the reconciliation phase:
// - Before reconciliation: Represents the baseline state before any mutations or side effects.
// - After reconciliation: Represents the state as applied to the Kubernetes API, including all mutations.
//
// This method is primarily intended for use by the Component reconciler. Implementers should
// avoid calling this directly to retrieve data; instead, use provided patterns like DataExtractable.
Object() (client.Object, error)
// Identity returns a unique identifier for the resource in the format <apiVersion>/<kind>/<name>.
Identity() string
}
Resource is a generic interface for handling Kubernetes resources within a Component. Implementations of this interface wrap a specific Kubernetes object and define how its immutable and mutable fields are applied during reconciliation.
type Status ¶
type Status string
Status represents the internal state of a component. It is used as the Reason in a Kubernetes condition and provides a standardized way to reflect the health and progress of a component.
func (Status) Level ¶
Level returns the aggregation priority of a component Status.
The returned value is used when multiple component statuses must be collapsed into a single overall status (for example by a parent component or system-level status aggregator). The status with the highest Level() should be selected as the representative state.
The ordering reflects the most meaningful explanation of the system's current state:
- Error, Down and Degraded represent failure states and therefore have the highest priority.
- Suspension-related states (PendingSuspension, Suspending, Suspended) represent an intentional lifecycle mode and take precedence over normal convergence states.
- Convergence states (Creating, Updating, Scaling) represent normal reconciliation progress toward Ready.
- Ready represents the steady-state healthy condition.
Unknown or unrecognized statuses return 0 and therefore do not influence aggregation.
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" )
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.