kubebuilderx

package
v1.1.0-alpha.1 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2025 License: AGPL-3.0 Imports: 22 Imported by: 0

Documentation

Overview

Package kubebuilderx is a new framework builds upon the original DAG framework, which abstracts the reconciliation process into two stages. The first stage is the pure computation phase, where the goal is to generate an execution plan. The second stage is the plan execution phase, responsible for applying the changes computed in the first stage to the K8s API server.

The design choice of making the first stage purely computational serves two purposes.

  • it allows leveraging the experience and patterns from functional programming to make the code more robust.
  • it enables breaking down complex business logic into smaller units, facilitating testing.

The new framework retains this concept while attempting to address the following issues of the original approach:

  • The low-level exposure of the DAG data structure, which should be abstracted away.
  • The execution of business logic code being deferred, making step-by-step tracing and debugging challenging.

Additionally, the new framework further abstracts the concept of object snapshots into an ObjectTree, making it easier to apply the experience of editing a group of related objects using kubectl.

KubeBuilderX is in its very early stage.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ConditionSatisfied means the corresponding Reconcile() should be invoked
	ConditionSatisfied = &CheckResult{Satisfied: true}

	// ConditionUnsatisfied means the corresponding Reconcile() should be skipped
	ConditionUnsatisfied = &CheckResult{}

	// ConditionUnsatisfiedWithError means the corresponding and all the following
	// Reconcile() should be skipped
	ConditionUnsatisfiedWithError = func(err error) *CheckResult {
		return &CheckResult{Satisfied: false, Err: err}
	}
)
View Source
var (
	// Continue tells the control flow to continue
	Continue = Result{Next: cntn}

	// Commit tells the control flow to stop and jump to the commit phase
	Commit = Result{Next: cmmt}

	// RetryAfter tells the control flow to stop, jump to the commit phase
	// and retry from the beginning with a delay specified by `after`.
	RetryAfter = func(after time.Duration) Result {
		return Result{Next: rtry, RetryAfter: after}
	}
)
View Source
var ErrDeepCopyFailed = errors.New("DeepCopyFailed")

Functions

func NewPlanBuilder

func NewPlanBuilder(ctx context.Context, cli client.Client, currentTree, desiredTree *ObjectTree, recorder record.EventRecorder, logger logr.Logger) graph.PlanBuilder

NewPlanBuilder returns a PlanBuilder

Types

type CheckResult

type CheckResult struct {
	Satisfied bool
	Err       error
}

type Controller

type Controller interface {
	// Prepare loads the object tree from Kubernetes.
	Prepare(TreeLoader) Controller

	// Do is the computation phase. It contains the business logic and modifies the object tree.
	Do(...Reconciler) Controller

	// Commit is the plan execution phase. It computes the difference between
	// the old and new object trees, and applies the difference to Kubernetes.
	Commit() (ctrl.Result, error)
}

Controller interface should be implemented by a controller using kubebuilderx. Typically these methods are chained like:

kubebuilderx.NewController(ctx, client, req, recorder, logger).
	Prepare(treeloader).
	Do(reconciler).
	Do(moreReconciler).
	Commit()

func NewController

func NewController(ctx context.Context, cli client.Client, req ctrl.Request, recorder record.EventRecorder, logger logr.Logger) Controller

type ObjectOption added in v0.9.5

type ObjectOption interface {
	ApplyToObject(*ObjectOptions)
}

type ObjectOptions added in v0.9.5

type ObjectOptions struct {
	// if not empty, action should be done on the specified subresource
	SubResource string

	// if true, the object should not be reconciled
	SkipToReconcile bool
}

type ObjectTree

type ObjectTree struct {
	// TODO(free6om): should find a better place to hold these two params?
	context.Context
	record.EventRecorder
	logr.Logger
	// contains filtered or unexported fields
}

func NewObjectTree

func NewObjectTree() *ObjectTree

func ReadObjectTree

func ReadObjectTree[T client.Object](ctx context.Context, reader client.Reader, req ctrl.Request, ml client.MatchingLabels, kinds ...client.ObjectList) (*ObjectTree, error)

ReadObjectTree reads all objects owned by the root object which is type of 'T' with key in 'req'.

func (*ObjectTree) Add

func (t *ObjectTree) Add(objects ...client.Object) error

func (*ObjectTree) AddWithOption

func (t *ObjectTree) AddWithOption(object client.Object, options ...ObjectOption) error

func (*ObjectTree) DeepCopy

func (t *ObjectTree) DeepCopy() (*ObjectTree, error)

func (*ObjectTree) Delete

func (t *ObjectTree) Delete(objects ...client.Object) error

func (*ObjectTree) DeleteRoot

func (t *ObjectTree) DeleteRoot()

func (*ObjectTree) DeleteSecondaryObjects

func (t *ObjectTree) DeleteSecondaryObjects()

func (*ObjectTree) Get

func (t *ObjectTree) Get(object client.Object) (client.Object, error)

func (*ObjectTree) GetFinalizer

func (t *ObjectTree) GetFinalizer() string

func (*ObjectTree) GetRoot

func (t *ObjectTree) GetRoot() client.Object

func (*ObjectTree) GetSecondaryObjects

func (t *ObjectTree) GetSecondaryObjects() model.ObjectSnapshot

func (*ObjectTree) GetWithOption added in v0.9.5

func (t *ObjectTree) GetWithOption(object client.Object) (client.Object, ObjectOptions, error)

func (*ObjectTree) List

func (t *ObjectTree) List(obj client.Object) []client.Object

func (*ObjectTree) SetFinalizer

func (t *ObjectTree) SetFinalizer(finalizer string)

func (*ObjectTree) SetRoot

func (t *ObjectTree) SetRoot(root client.Object)

func (*ObjectTree) Update

func (t *ObjectTree) Update(object client.Object, options ...ObjectOption) error

type Plan

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

func (*Plan) Execute

func (p *Plan) Execute() error

type PlanBuilder

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

func (*PlanBuilder) AddTransformer

func (b *PlanBuilder) AddTransformer(_ ...graph.Transformer) graph.PlanBuilder

func (*PlanBuilder) Build

func (b *PlanBuilder) Build() (graph.Plan, error)

func (*PlanBuilder) Init

func (b *PlanBuilder) Init() error

type Reconciler

type Reconciler interface {
	// PreCondition should return ConditionSatisfied if Reconcile() should be invoked,
	// otherwise return ConditionUnsatisfied.
	PreCondition(*ObjectTree) *CheckResult

	// Reconcile contains the business logic and modifies the object tree.
	Reconcile(tree *ObjectTree) (Result, error)
}

type Result added in v0.9.1

type Result struct {
	Next       controlMethod
	RetryAfter time.Duration
}

type SkipToReconcile

type SkipToReconcile bool

func (SkipToReconcile) ApplyToObject

func (o SkipToReconcile) ApplyToObject(opts *ObjectOptions)

type TreeLoader

type TreeLoader interface {
	Load(context.Context, client.Reader, ctrl.Request, record.EventRecorder, logr.Logger) (*ObjectTree, error)
}

type WithSubResource added in v0.9.5

type WithSubResource string

func (WithSubResource) ApplyToObject added in v0.9.5

func (w WithSubResource) ApplyToObject(opts *ObjectOptions)

Jump to

Keyboard shortcuts

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