reconcilers

package
v0.20.0 Latest Latest
Warning

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

Go to latest
Published: Mar 13, 2024 License: Apache-2.0 Imports: 48 Imported by: 5

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrQuiet are not logged or recorded as events within reconciler.io/runtime.
	// They are propagated as errors unless otherwise defined.
	//
	// Test for ErrQuiet with errors.Is(err, ErrQuiet)
	ErrQuiet = fmt.Errorf("quiet errors are returned as errors, but not logged or recorded")

	// ErrHaltSubReconcilers is an error that instructs SubReconcilers to stop processing the request,
	// while the root reconciler proceeds as if there was no error. ErrHaltSubReconcilers may be
	// wrapped by other errors.
	//
	// ErrHaltSubReconcilers wraps ErrQuiet to suppress spurious logs.
	//
	// See documentation for the specific SubReconciler caller to see how they handle this case.
	ErrHaltSubReconcilers = fmt.Errorf("stop processing SubReconcilers, without returning an error: %w", ErrQuiet)

	// Deprecated HaltSubReconcilers use ErrHaltSubReconcilers instead
	HaltSubReconcilers = ErrHaltSubReconcilers
)
View Source
var IgnoreAllUnexported = cmp.FilterPath(func(p cmp.Path) bool {

	sf, ok := p.Index(-1).(cmp.StructField)
	if !ok {
		return false
	}
	r, _ := utf8.DecodeRuneInString(sf.Name())
	return !unicode.IsUpper(r)
}, cmp.Ignore())

IgnoreAllUnexported is a cmp.Option that ignores unexported fields in all structs

View Source
var (
	OnlyReconcileChildStatus = errors.New("skip reconciler create/update/delete behavior for the child resource, while still reflecting the existing child's status on the reconciled resource")
)
View Source
var PatchGenerationMismatch = errors.New("patch generation did not match target")

Functions

func AddFinalizer

func AddFinalizer(ctx context.Context, resource client.Object, finalizer string) error

AddFinalizer ensures the desired finalizer exists on the reconciled resource. The client that loaded the reconciled resource is used to patch it with the finalizer if not already set.

func ClearFinalizer

func ClearFinalizer(ctx context.Context, resource client.Object, finalizer string) error

ClearFinalizer ensures the desired finalizer does not exist on the reconciled resource. The client that loaded the reconciled resource is used to patch it with the finalizer if set.

func ClearValue

func ClearValue(ctx context.Context, key StashKey) interface{}

func EnqueueTracked

func EnqueueTracked(ctx context.Context) handler.EventHandler

func MergeMaps

func MergeMaps(maps ...map[string]string) map[string]string

MergeMaps flattens a sequence of maps into a single map. Keys in latter maps overwrite previous keys. None of the arguments are mutated.

func RetrieveAdditionalConfigs

func RetrieveAdditionalConfigs(ctx context.Context) map[string]Config

RetrieveAdditionalConfigs returns the additional configs defined for this request. Uncommon outside of the context of a test. An empty map is returned when no value is stashed.

func RetrieveAdmissionRequest

func RetrieveAdmissionRequest(ctx context.Context) admission.Request

RetrieveAdmissionRequest returns the admission Request from the context, or empty if not found.

func RetrieveAdmissionResponse

func RetrieveAdmissionResponse(ctx context.Context) *admission.Response

RetrieveAdmissionResponse returns the admission Response from the context, or nil if not found.

func RetrieveHTTPRequest

func RetrieveHTTPRequest(ctx context.Context) *http.Request

RetrieveHTTPRequest returns the http Request from the context, or nil if not found.

func RetrieveIteration

func RetrieveIteration(ctx context.Context) int

RetrieveIteration returns the iteration index. If nested loops are executing only the inner most iteration index is returned.

-1 indicates the call is not within a loop.

func RetrieveKnownChildren

func RetrieveKnownChildren[T client.Object](ctx context.Context) []T

RetrieveKnownChildren returns the children managed by current ChildSetReconciler. The known children can be returned from the DesiredChildren method to preserve existing children, or to mutate/delete an existing child.

For example, a child stamper could be implemented by returning existing children from DesiredChildren and appending an addition child when a new resource should be created. Likewise existing children can be garbage collected by omitting a known child.

func RetrieveOriginalResourceType

func RetrieveOriginalResourceType(ctx context.Context) client.Object

RetrieveOriginalResourceType returns the reconciled resource type object, or nil if not found.

func RetrieveResourceType

func RetrieveResourceType(ctx context.Context) client.Object

RetrieveResourceType returns the reconciled resource type object, or nil if not found.

func RetrieveValue

func RetrieveValue(ctx context.Context, key StashKey) interface{}

func StashAdditionalConfigs

func StashAdditionalConfigs(ctx context.Context, additionalConfigs map[string]Config) context.Context

func StashAdmissionRequest

func StashAdmissionRequest(ctx context.Context, req admission.Request) context.Context

func StashAdmissionResponse

func StashAdmissionResponse(ctx context.Context, resp *admission.Response) context.Context

func StashConfig

func StashConfig(ctx context.Context, config Config) context.Context

func StashHTTPRequest

func StashHTTPRequest(ctx context.Context, req *http.Request) context.Context

func StashOriginalConfig

func StashOriginalConfig(ctx context.Context, resourceConfig Config) context.Context

func StashOriginalResourceType

func StashOriginalResourceType(ctx context.Context, resourceType client.Object) context.Context

func StashRequest

func StashRequest(ctx context.Context, req Request) context.Context

func StashResourceType

func StashResourceType(ctx context.Context, currentType client.Object) context.Context

func StashValue

func StashValue(ctx context.Context, key StashKey, value interface{})

func WithStash

func WithStash(ctx context.Context) context.Context

Types

type AdmissionWebhookAdapter

type AdmissionWebhookAdapter[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `{Type}AdmissionWebhookAdapter`.  Ideally
	// unique, but not required to be so.
	//
	// +optional
	Name string

	// Type of resource to reconcile. Required when the generic type is not a struct.
	//
	// +optional
	Type Type

	// Reconciler is called for each reconciler request with the resource being reconciled.
	// Typically, Reconciler is a Sequence of multiple SubReconcilers.
	Reconciler SubReconciler[Type]

	Config Config
	// contains filtered or unexported fields
}

AdmissionWebhookAdapter allows using sub reconcilers to process admission webhooks. The full suite of sub reconcilers are available, however, behavior that is generally not accepted within a webhook is discouraged. For example, new requests against the API server are discouraged (reading from an informer is ok), mutation requests against the API Server can cause a loop with the webhook processing its own requests.

All requests are allowed by default unless the response.Allowed field is explicitly unset, or the reconciler returns an error. The raw admission request and response can be retrieved from the context via the RetrieveAdmissionRequest and RetrieveAdmissionResponse methods, respectively. The Result typically returned by a reconciler is unused.

The request object is unmarshaled from the request object for most operations, and the old object for delete operations. If the webhhook handles multiple resources or versions of the same resource with different shapes, use of an unstructured type is recommended.

If the resource being reconciled is mutated and the response does not already define a patch, a json patch is computed for the mutation and set on the response.

If the webhook can handle multiple types, use *unstructured.Unstructured as the generic type.

func (*AdmissionWebhookAdapter[T]) Build

func (r *AdmissionWebhookAdapter[T]) Build() *admission.Webhook

func (*AdmissionWebhookAdapter[T]) Handle

Handle implements admission.Handler

type AggregateReconciler

type AggregateReconciler[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `{Type}ResourceReconciler`.  Ideally
	// unique, but not required to be so.
	//
	// +optional
	Name string

	// Setup performs initialization on the manager and builder this reconciler
	// will run with. It's common to setup field indexes and watch resources.
	//
	// +optional
	Setup func(ctx context.Context, mgr Manager, bldr *Builder) error

	// Type of resource to reconcile. Required when the generic type is not a
	// struct, or is unstructured.
	//
	// +optional
	Type Type

	// Request of resource to reconcile. Only the specific resource matching the namespace and name
	// is reconciled. The namespace may be empty for cluster scoped resources.
	Request Request

	// Reconciler is called for each reconciler request with the resource being reconciled.
	// Typically, Reconciler is a Sequence of multiple SubReconcilers.
	//
	// When ErrHaltSubReconcilers is returned as an error, execution continues as if no error was
	// returned.
	//
	// +optional
	Reconciler SubReconciler[Type]

	// DesiredResource returns the desired resource to create/update, or nil if
	// the resource should not exist.
	//
	// +optional
	DesiredResource func(ctx context.Context, resource Type) (Type, error)

	// HarmonizeImmutableFields allows fields that are immutable on the current
	// object to be copied to the desired object in order to avoid creating
	// updates which are guaranteed to fail.
	//
	// +optional
	HarmonizeImmutableFields func(current, desired Type)

	// MergeBeforeUpdate copies desired fields on to the current object before
	// calling update. Typically fields to copy are the Spec, Labels and
	// Annotations.
	MergeBeforeUpdate func(current, desired Type)

	// Sanitize is called with an object before logging the value. Any value may
	// be returned. A meaningful subset of the resource is typically returned,
	// like the Spec.
	//
	// +optional
	Sanitize func(resource Type) interface{}

	Config Config
	// contains filtered or unexported fields
}

AggregateReconciler is a controller-runtime reconciler that reconciles a specific resource. The Type resource is fetched for the reconciler request and passed in turn to each SubReconciler. Finally, the reconciled resource's status is compared with the original status, updating the API server if needed.

func (*AggregateReconciler[T]) Reconcile

func (r *AggregateReconciler[T]) Reconcile(ctx context.Context, req Request) (Result, error)

func (*AggregateReconciler[T]) SetupWithManager

func (r *AggregateReconciler[T]) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error

func (*AggregateReconciler[T]) SetupWithManagerYieldingController

func (r *AggregateReconciler[T]) SetupWithManagerYieldingController(ctx context.Context, mgr ctrl.Manager) (controller.Controller, error)

type Builder

type Builder = builder.Builder

type CastResource

type CastResource[Type, CastType client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `{Type}CastResource`.  Ideally unique, but
	// not required to be so.
	//
	// +optional
	Name string

	// Reconciler is called for each reconciler request with the reconciled resource. Typically a
	// Sequence is used to compose multiple SubReconcilers.
	Reconciler SubReconciler[CastType]
	// contains filtered or unexported fields
}

CastResource casts the ResourceReconciler's type by projecting the resource data onto a new struct. Casting the reconciled resource is useful to create cross cutting reconcilers that can operate on common portion of multiple resources, commonly referred to as a duck type.

If the CastType generic is an interface rather than a struct, the resource is passed directly rather than converted.

func (*CastResource[T, CT]) Reconcile

func (r *CastResource[T, CT]) Reconcile(ctx context.Context, resource T) (Result, error)

func (*CastResource[T, CT]) SetupWithManager

func (r *CastResource[T, CT]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

type ChildReconciler

type ChildReconciler[Type, ChildType client.Object, ChildListType client.ObjectList] struct {
	// Name used to identify this reconciler.  Defaults to `{ChildType}ChildReconciler`.  Ideally
	// unique, but not required to be so.
	//
	// +optional
	Name string

	// ChildType is the resource being created/updated/deleted by the reconciler. For example, a
	// reconciled resource Deployment would have a ReplicaSet as a child. Required when the
	// generic type is not a struct, or is unstructured.
	//
	// +optional
	ChildType ChildType
	// ChildListType is the listing type for the child type. For example,
	// PodList is the list type for Pod. Required when the generic type is not
	// a struct, or is unstructured.
	//
	// +optional
	ChildListType ChildListType

	// Finalizer is set on the reconciled resource before a child resource is created, and cleared
	// after a child resource is deleted. The value must be unique to this specific reconciler
	// instance and not shared. Reusing a value may result in orphaned resources when the
	// reconciled resource is deleted.
	//
	// Using a finalizer is encouraged when the Kubernetes garbage collector is unable to delete
	// the child resource automatically, like when the reconciled resource and child are in different
	// namespaces, scopes or clusters.
	//
	// Use of a finalizer implies that SkipOwnerReference is true, and OurChild must be defined.
	//
	// +optional
	Finalizer string

	// SkipOwnerReference when true will not create and find child resources via an owner
	// reference. OurChild must be defined for the reconciler to distinguish the child being
	// reconciled from other resources of the same type.
	//
	// Any child resource created is tracked for changes.
	SkipOwnerReference bool

	// Setup performs initialization on the manager and builder this reconciler
	// will run with. It's common to setup field indexes and watch resources.
	//
	// +optional
	Setup func(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

	// DesiredChild returns the desired child object for the given reconciled resource, or nil if
	// the child should not exist.
	//
	// To skip reconciliation of the child resource while still reflecting an existing child's
	// status on the reconciled resource, return OnlyReconcileChildStatus as an error.
	DesiredChild func(ctx context.Context, resource Type) (ChildType, error)

	// ReflectChildStatusOnParent updates the reconciled resource's status with values from the
	// child. Select types of errors are passed, including:
	//   - apierrs.IsAlreadyExists
	//   - apierrs.IsInvalid
	//
	// Most errors are returned directly, skipping this method. The set of handled error types
	// may grow, implementations should be defensive rather than assuming the error type.
	ReflectChildStatusOnParent func(ctx context.Context, parent Type, child ChildType, err error)

	// HarmonizeImmutableFields allows fields that are immutable on the current
	// object to be copied to the desired object in order to avoid creating
	// updates which are guaranteed to fail.
	//
	// +optional
	HarmonizeImmutableFields func(current, desired ChildType)

	// MergeBeforeUpdate copies desired fields on to the current object before
	// calling update. Typically fields to copy are the Spec, Labels and
	// Annotations.
	MergeBeforeUpdate func(current, desired ChildType)

	// ListOptions allows custom options to be use when listing potential child resources. Each
	// resource retrieved as part of the listing is confirmed via OurChild. There is a performance
	// benefit to limiting the number of resource return for each List operation, however,
	// excluding an actual child will orphan that resource.
	//
	// Defaults to filtering by the reconciled resource's namespace:
	//     []client.ListOption{
	//         client.InNamespace(resource.GetNamespace()),
	//     }
	//
	// ListOptions is required when a Finalizer is defined or SkipOwnerReference is true. An empty
	// list is often sufficient although it may incur a performance penalty, especially when
	// querying the API sever instead of an informer cache.
	//
	// +optional
	ListOptions func(ctx context.Context, resource Type) []client.ListOption

	// OurChild is used when there are multiple ChildReconciler for the same ChildType controlled
	// by the same reconciled resource. The function return true for child resources managed by
	// this ChildReconciler. Objects returned from the DesiredChild function should match this
	// function, otherwise they may be orphaned. If not specified, all children match.
	//
	// OurChild is required when a Finalizer is defined or SkipOwnerReference is true.
	//
	// +optional
	OurChild func(resource Type, child ChildType) bool

	// Sanitize is called with an object before logging the value. Any value may
	// be returned. A meaningful subset of the resource is typically returned,
	// like the Spec.
	//
	// +optional
	Sanitize func(child ChildType) interface{}
	// contains filtered or unexported fields
}

ChildReconciler is a sub reconciler that manages a single child resource for a reconciled resource. The reconciler will ensure that exactly one child will match the desired state by:

  • creating a child if none exists
  • updating an existing child
  • removing an unneeded child
  • removing extra children

The flow for each reconciliation request is:

  • DesiredChild
  • if child is desired, HarmonizeImmutableFields (optional)
  • if child is desired, MergeBeforeUpdate
  • ReflectChildStatusOnParent

During setup, the child resource type is registered to watch for changes.

func (*ChildReconciler[T, CT, CLT]) Reconcile

func (r *ChildReconciler[T, CT, CLT]) Reconcile(ctx context.Context, resource T) (Result, error)

func (*ChildReconciler[T, CT, CLT]) SetResourceManager

func (r *ChildReconciler[T, CT, CLT]) SetResourceManager(rm *ResourceManager[CT])

func (*ChildReconciler[T, CT, CLT]) SetupWithManager

func (r *ChildReconciler[T, CT, CLT]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

type ChildSetPartialResult

type ChildSetPartialResult[T client.Object] struct {
	Id    string
	Child T
	Err   error
}

type ChildSetReconciler

type ChildSetReconciler[Type, ChildType client.Object, ChildListType client.ObjectList] struct {
	// Name used to identify this reconciler.  Defaults to `{ChildType}ChildSetReconciler`.  Ideally
	// unique, but not required to be so.
	//
	// +optional
	Name string

	// ChildType is the resource being created/updated/deleted by the reconciler. For example, a
	// reconciled resource Deployment would have a ReplicaSet as a child. Required when the
	// generic type is not a struct, or is unstructured.
	//
	// +optional
	ChildType ChildType
	// ChildListType is the listing type for the child type. For example,
	// PodList is the list type for Pod. Required when the generic type is not
	// a struct, or is unstructured.
	//
	// +optional
	ChildListType ChildListType

	// Finalizer is set on the reconciled resource before a child resource is created, and cleared
	// after a child resource is deleted. The value must be unique to this specific reconciler
	// instance and not shared. Reusing a value may result in orphaned resources when the
	// reconciled resource is deleted.
	//
	// Using a finalizer is encouraged when the Kubernetes garbage collector is unable to delete
	// the child resource automatically, like when the reconciled resource and child are in different
	// namespaces, scopes or clusters.
	//
	// Use of a finalizer implies that SkipOwnerReference is true.
	//
	// +optional
	Finalizer string

	// SkipOwnerReference when true will not create and find child resources via an owner
	// reference. OurChild must be defined for the reconciler to distinguish the child being
	// reconciled from other resources of the same type.
	//
	// Any child resource created is tracked for changes.
	SkipOwnerReference bool

	// Setup performs initialization on the manager and builder this reconciler
	// will run with. It's common to setup field indexes and watch resources.
	//
	// +optional
	Setup func(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

	// DesiredChildren returns the set of desired child object for the given reconciled resource,
	// or nil if no children should exist. Each resource returned from this method must be claimed
	// by the OurChild method with a stable, unique identifier returned. The identifier is used to
	// correlate desired and actual child resources.
	//
	// Current known children can be obtained via RetrieveKnownChildren[ChildType](ctx). This can
	// be used to keep existing children while stamping out new resources, or for garbage
	// collecting resources based on some criteria. Return the children that should be kept and
	// omit children to delete.
	//
	// To skip reconciliation of the child resources while still reflecting an existing child's
	// status on the reconciled resource, return OnlyReconcileChildStatus as an error.
	DesiredChildren func(ctx context.Context, resource Type) ([]ChildType, error)

	// ReflectChildrenStatusOnParent updates the reconciled resource's status with values from the
	// child reconciliations. Select types of errors are captured, including:
	//   - apierrs.IsAlreadyExists
	//   - apierrs.IsInvalid
	//
	// Most errors are returned directly, skipping this method. The set of handled error types
	// may grow, implementations should be defensive rather than assuming the error type.
	//
	// Results contain the union of desired and actual child resources, in the order they were
	// reconciled, (sorted by identifier).
	ReflectChildrenStatusOnParent func(ctx context.Context, parent Type, result ChildSetResult[ChildType])

	// HarmonizeImmutableFields allows fields that are immutable on the current
	// object to be copied to the desired object in order to avoid creating
	// updates which are guaranteed to fail.
	//
	// +optional
	HarmonizeImmutableFields func(current, desired ChildType)

	// MergeBeforeUpdate copies desired fields on to the current object before
	// calling update. Typically fields to copy are the Spec, Labels and
	// Annotations.
	MergeBeforeUpdate func(current, desired ChildType)

	// ListOptions allows custom options to be use when listing potential child resources. Each
	// resource retrieved as part of the listing is confirmed via OurChild. There is a performance
	// benefit to limiting the number of resource return for each List operation, however,
	// excluding an actual child will orphan that resource.
	//
	// Defaults to filtering by the reconciled resource's namespace:
	//     []client.ListOption{
	//         client.InNamespace(resource.GetNamespace()),
	//     }
	//
	// ListOptions is required when a Finalizer is defined or SkipOwnerReference is true. An empty
	// list is often sufficient although it may incur a performance penalty, especially when
	// querying the API sever instead of an informer cache.
	//
	// +optional
	ListOptions func(ctx context.Context, resource Type) []client.ListOption

	// OurChild is used when there are multiple sources of children of the same ChildType
	// controlled by the same reconciled resource. The function return true for child resources
	// managed by this ChildReconciler. Objects returned from the DesiredChildren function should
	// match this function, otherwise they may be orphaned. If not specified, all children match.
	// Matched child resources must also be uniquely identifiable with the IdentifyChild method.
	//
	// OurChild is required when a Finalizer is defined or SkipOwnerReference is true.
	//
	// +optional
	OurChild func(resource Type, child ChildType) bool

	// IdentifyChild returns a stable identifier for the child resource. The identifier is used to
	// correlate desired child resources with actual child resources. The same value must be returned
	// for an object both before and after it is created on the API server.
	//
	// Non-deterministic IDs will result in the rapid deletion and creation of child resources.
	IdentifyChild func(child ChildType) string

	// Sanitize is called with an object before logging the value. Any value may
	// be returned. A meaningful subset of the resource is typically returned,
	// like the Spec.
	//
	// +optional
	Sanitize func(child ChildType) interface{}
	// contains filtered or unexported fields
}

ChildSetReconciler is a sub reconciler that manages a set of child resources for a reconciled resource. A correlation ID is used to track the desired state of each child resource across reconcile requests. A ChildReconciler is created dynamically and reconciled for each desired and discovered child resource.

During setup, the child resource type is registered to watch for changes.

func (*ChildSetReconciler[T, CT, CLT]) Reconcile

func (r *ChildSetReconciler[T, CT, CLT]) Reconcile(ctx context.Context, resource T) (Result, error)

func (*ChildSetReconciler[T, CT, CLT]) SetupWithManager

func (r *ChildSetReconciler[T, CT, CLT]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

type ChildSetResult

type ChildSetResult[T client.Object] struct {
	Children []ChildSetPartialResult[T]
}

func (*ChildSetResult[T]) AggregateError

func (r *ChildSetResult[T]) AggregateError() error

type Config

type Config struct {
	client.Client
	APIReader client.Reader
	Recorder  record.EventRecorder
	Tracker   tracker.Tracker
}

Config holds common resources for controllers. The configuration may be passed to sub-reconcilers.

func NewConfig

func NewConfig(mgr ctrl.Manager, apiType client.Object, syncPeriod time.Duration) Config

NewConfig creates a Config for a specific API type. Typically passed into a reconciler.

func RetrieveConfig

func RetrieveConfig(ctx context.Context) (Config, error)

RetrieveConfig returns the Config from the context. An error is returned if not found.

func RetrieveConfigOrDie

func RetrieveConfigOrDie(ctx context.Context) Config

RetrieveConfigOrDie returns the Config from the context. Panics if not found.

func RetrieveOriginalConfig

func RetrieveOriginalConfig(ctx context.Context) (Config, error)

RetrieveOriginalConfig returns the Config from the context used to load the reconciled resource. An error is returned if not found.

func RetrieveOriginalConfigOrDie

func RetrieveOriginalConfigOrDie(ctx context.Context) Config

RetrieveOriginalConfigOrDie returns the Config from the context used to load the reconciled resource. Panics if not found.

func (Config) IsEmpty

func (c Config) IsEmpty() bool

func (Config) TrackAndGet

func (c Config) TrackAndGet(ctx context.Context, key types.NamespacedName, obj client.Object, opts ...client.GetOption) error

TrackAndGet tracks the resources for changes and returns the current value. The track is registered even when the resource does not exists so that its creation can be tracked.

Equivalent to calling both `c.Tracker.TrackObject(...)` and `c.Client.Get(...)`

func (Config) TrackAndList

func (c Config) TrackAndList(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error

TrackAndList tracks the resources for changes and returns the current value.

Equivalent to calling both `c.Tracker.TrackReference(...)` and `c.Client.List(...)`

func (Config) WithCluster

func (c Config) WithCluster(cluster cluster.Cluster) Config

WithCluster extends the config to access a new cluster.

type ErrMaxIterations

type ErrMaxIterations struct {
	Iterations int
}

ErrMaxIterations indicates the maximum number of loop iterations was exceeded.

func (*ErrMaxIterations) Error

func (err *ErrMaxIterations) Error() string

type IfThen

type IfThen[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `IfThen`.  Ideally
	// unique, but not required to be so.
	//
	// +optional
	Name string

	// Setup performs initialization on the manager and builder this reconciler
	// will run with. It's common to setup field indexes and watch resources.
	//
	// +optional
	Setup func(ctx context.Context, mgr Manager, bldr *Builder) error

	// If controls the flow of execution calling the Then reconciler when true,
	// and the Else reconciler when false.
	If func(ctx context.Context, resource Type) bool

	// Then is called when If() returns true. Typically, Then is a Sequence of
	// multiple SubReconcilers.
	Then SubReconciler[Type]

	// Else is called when If() returns false. Typically, Else is a Sequence of
	// multiple SubReconcilers.
	//
	// +optional
	Else SubReconciler[Type]
	// contains filtered or unexported fields
}

IfThen conditionally branches the reconcilers called for a request based on a condition. When the If condition is true, Then is invoked; when false, Else is invoked.

func (*IfThen[T]) Reconcile

func (r *IfThen[T]) Reconcile(ctx context.Context, resource T) (Result, error)

func (*IfThen[T]) SetupWithManager

func (r *IfThen[T]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

type Manager

type Manager = manager.Manager

type OverrideSetup

type OverrideSetup[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `SkipSetup`. Ideally
	// unique, but not required to be so.
	//
	// +optional
	Name string

	// Setup allows for custom initialization on the manager and builder this
	// reconciler will run with. Since the SetupWithManager method will not be
	// called on Reconciler, this method can be used to provide an alternative
	// setup. It's common to setup field indexes and watch resources.
	//
	// +optional
	Setup func(ctx context.Context, mgr Manager, bldr *Builder) error

	// Reconciler is called for each reconciler request with the reconciled
	// resource being reconciled. SetupWithManager will not be called on this
	// reconciler. Typically a Sequence is used to compose multiple
	// SubReconcilers.
	//
	// +optional
	Reconciler SubReconciler[Type]
	// contains filtered or unexported fields
}

OverrideSetup suppresses the SetupWithManager on the nested Reconciler in favor of the local Setup method.

func (*OverrideSetup[T]) Reconcile

func (r *OverrideSetup[T]) Reconcile(ctx context.Context, resource T) (Result, error)

func (*OverrideSetup[T]) SetupWithManager

func (r *OverrideSetup[T]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

type Patch

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

func NewPatch

func NewPatch(base, update client.Object) (*Patch, error)

func (*Patch) Apply

func (p *Patch) Apply(rebase client.Object) error

type Request

type Request = reconcile.Request

func RetrieveRequest

func RetrieveRequest(ctx context.Context) Request

RetrieveRequest returns the reconciler Request from the context, or empty if not found.

type ResourceManager

type ResourceManager[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `{Type}ResourceManager`.  Ideally
	// unique, but not required to be so.
	//
	// +optional
	Name string

	// Type is the resource being created/updated/deleted by the reconciler. Required when the
	// generic type is not a struct, or is unstructured.
	//
	// +optional
	Type Type

	// Finalizer is set on the reconciled resource before a managed resource is created, and cleared
	// after a managed resource is deleted. The value must be unique to this specific manager
	// instance and not shared. Reusing a value may result in orphaned resources when the
	// reconciled resource is deleted.
	//
	// Using a finalizer is encouraged when the Kubernetes garbage collector is unable to delete
	// the child resource automatically, like when the reconciled resource and child are in different
	// namespaces, scopes or clusters.
	//
	// +optional
	Finalizer string

	// TrackDesired when true, the desired resource is tracked after creates, before
	// updates, and on delete errors.
	TrackDesired bool

	// HarmonizeImmutableFields allows fields that are immutable on the current
	// object to be copied to the desired object in order to avoid creating
	// updates which are guaranteed to fail.
	//
	// +optional
	HarmonizeImmutableFields func(current, desired Type)

	// MergeBeforeUpdate copies desired fields on to the current object before
	// calling update. Typically fields to copy are the Spec, Labels and
	// Annotations.
	MergeBeforeUpdate func(current, desired Type)

	// Sanitize is called with an object before logging the value. Any value may
	// be returned. A meaningful subset of the resource is typically returned,
	// like the Spec.
	//
	// +optional
	Sanitize func(child Type) interface{}
	// contains filtered or unexported fields
}

ResourceManager compares the actual and desired resources to create/update/delete as desired.

func (*ResourceManager[T]) Manage

func (r *ResourceManager[T]) Manage(ctx context.Context, resource client.Object, actual, desired T) (T, error)

Manage a specific resource to create/update/delete based on the actual and desired state. The resource is the reconciled resource and used to record events for mutations. The actual and desired objects represent the managed resource and must be compatible with the type field.

func (*ResourceManager[T]) Setup

func (r *ResourceManager[T]) Setup(ctx context.Context) error

type ResourceReconciler

type ResourceReconciler[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `{Type}ResourceReconciler`.  Ideally
	// unique, but not required to be so.
	//
	// +optional
	Name string

	// Setup performs initialization on the manager and builder this reconciler
	// will run with. It's common to setup field indexes and watch resources.
	//
	// +optional
	Setup func(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

	// Type of resource to reconcile. Required when the generic type is not a
	// struct, or is unstructured.
	//
	// +optional
	Type Type

	// SkipStatusUpdate when true, the resource's status will not be updated. If this
	// is not the primary reconciler for a resource, skipping status updates can avoid
	// conflicts. Finalizers and events are still actionable.
	SkipStatusUpdate bool

	// Reconciler is called for each reconciler request with the resource being reconciled.
	// Typically, Reconciler is a Sequence of multiple SubReconcilers.
	//
	// When ErrHaltSubReconcilers is returned as an error, execution continues as if no error was
	// returned.
	Reconciler SubReconciler[Type]

	Config Config
	// contains filtered or unexported fields
}

ResourceReconciler is a controller-runtime reconciler that reconciles a given existing resource. The Type resource is fetched for the reconciler request and passed in turn to each SubReconciler. Finally, the reconciled resource's status is compared with the original status, updating the API server if needed.

func (*ResourceReconciler[T]) Reconcile

func (r *ResourceReconciler[T]) Reconcile(ctx context.Context, req Request) (Result, error)

func (*ResourceReconciler[T]) SetupWithManager

func (r *ResourceReconciler[T]) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error

func (*ResourceReconciler[T]) SetupWithManagerYieldingController

func (r *ResourceReconciler[T]) SetupWithManagerYieldingController(ctx context.Context, mgr ctrl.Manager) (controller.Controller, error)

type Result

type Result = reconcile.Result

func AggregateResults

func AggregateResults(results ...Result) Result

AggregateResults combines multiple results into a single result. If any result requests requeue, the aggregate is requeued. The shortest non-zero requeue after is the aggregate value.

type Sequence

type Sequence[Type client.Object] []SubReconciler[Type]

Sequence is a collection of SubReconcilers called in order. If a reconciler errs, further reconcilers are skipped.

func (Sequence[T]) Reconcile

func (r Sequence[T]) Reconcile(ctx context.Context, resource T) (Result, error)

func (Sequence[T]) SetupWithManager

func (r Sequence[T]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

type StashKey

type StashKey string

type SubReconciler

type SubReconciler[Type client.Object] interface {
	SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error
	Reconcile(ctx context.Context, resource Type) (Result, error)
}

SubReconciler are participants in a larger reconciler request. The resource being reconciled is passed directly to the sub reconciler.

type SyncReconciler

type SyncReconciler[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `SyncReconciler`.  Ideally unique, but
	// not required to be so.
	//
	// +optional
	Name string

	// Setup performs initialization on the manager and builder this reconciler
	// will run with. It's common to setup field indexes and watch resources.
	//
	// +optional
	Setup func(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

	// SyncDuringFinalization indicates the Sync method should be called when the resource is pending deletion.
	SyncDuringFinalization bool

	// Sync does whatever work is necessary for the reconciler.
	//
	// If SyncDuringFinalization is true this method is called when the resource is pending
	// deletion. This is useful if the reconciler is managing reference data.
	//
	// Mutually exclusive with SyncWithResult
	Sync func(ctx context.Context, resource Type) error

	// SyncWithResult does whatever work is necessary for the reconciler.
	//
	// If SyncDuringFinalization is true this method is called when the resource is pending
	// deletion. This is useful if the reconciler is managing reference data.
	//
	// Mutually exclusive with Sync
	SyncWithResult func(ctx context.Context, resource Type) (Result, error)

	// Finalize does whatever work is necessary for the reconciler when the resource is pending
	// deletion. If this reconciler sets a finalizer it should do the necessary work to clean up
	// state the finalizer represents and then clear the finalizer.
	//
	// Mutually exclusive with FinalizeWithResult
	//
	// +optional
	Finalize func(ctx context.Context, resource Type) error

	// Finalize does whatever work is necessary for the reconciler when the resource is pending
	// deletion. If this reconciler sets a finalizer it should do the necessary work to clean up
	// state the finalizer represents and then clear the finalizer.
	//
	// Mutually exclusive with Finalize
	//
	// +optional
	FinalizeWithResult func(ctx context.Context, resource Type) (Result, error)
}

SyncReconciler is a sub reconciler for custom reconciliation logic. No behavior is defined directly.

func (*SyncReconciler[T]) Reconcile

func (r *SyncReconciler[T]) Reconcile(ctx context.Context, resource T) (Result, error)

func (*SyncReconciler[T]) SetupWithManager

func (r *SyncReconciler[T]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

type TryCatch

type TryCatch[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `TryCatch`.  Ideally
	// unique, but not required to be so.
	//
	// +optional
	Name string

	// Setup performs initialization on the manager and builder this reconciler
	// will run with. It's common to setup field indexes and watch resources.
	//
	// +optional
	Setup func(ctx context.Context, mgr Manager, bldr *Builder) error

	// Try is a reconciler that may return an error that needs to be handled.
	// Typically, Try is a Sequence of multiple SubReconcilers.
	Try SubReconciler[Type]

	// Catch is called with the results from Try(). New results can be returned
	// suppressing the original results.
	//
	// +optional
	Catch func(ctx context.Context, resource Type, result Result, err error) (Result, error)

	// Finally is always called before returning. An error from Finally will
	// always be returned. If Finally does not return an error, the error state
	// before Finally was called will be returned along with the result
	// aggregated.
	//
	// Typically, Finally is a Sequence of multiple SubReconcilers.
	//
	// +optional
	Finally SubReconciler[Type]
	// contains filtered or unexported fields
}

TryCatch facilitates recovery from errors encountered within the Try reconciler. The results of the Try reconciler are passed to the Catch handler which can suppress, modify or continue the error. The Finally reconciler is always called before returning, but cannot prevent an error from being returned.

The semantics mimic the try-catch-finally behavior from C-style languages:

  • Try, Catch, Finally are called in order for each request.
  • Catch can fully redefine the results from Try.
  • if Catch is not defined, the Try results are implicitly propagated.
  • if the results are in error before Finally is called, the final results will be in error.
  • an error returned from Finally will preempt an existing error.
  • the existing Result is aggregated with the Finally Result.

Use of Finally should be limited to common clean up logic that applies equally to normal and error conditions. Further flow control within Finally is discouraged as new errors can mask errors returned from Catch.

func (*TryCatch[T]) Reconcile

func (r *TryCatch[T]) Reconcile(ctx context.Context, resource T) (Result, error)

func (*TryCatch[T]) SetupWithManager

func (r *TryCatch[T]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

type While

type While[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `While`.  Ideally
	// unique, but not required to be so.
	//
	// +optional
	Name string

	// Setup performs initialization on the manager and builder this reconciler
	// will run with. It's common to setup field indexes and watch resources.
	//
	// +optional
	Setup func(ctx context.Context, mgr Manager, bldr *Builder) error

	// Condition controls the execution flow calling the reconciler so long as
	// the returned value remains true.
	Condition func(ctx context.Context, resource Type) bool

	// Reconciler is called so long as Condition() returns true. Typically,
	// Reconciler is a Sequence of multiple SubReconcilers.
	Reconciler SubReconciler[Type]

	// MaxIterations guards against infinite loops by limiting the number of
	// allowed iterations before returning an error. Defaults to 100, set to 0
	// to disable.
	MaxIterations *int
	// contains filtered or unexported fields
}

While the Condition is true call the Reconciler.

While must not be used to block the reconciler awaiting a remote condition change. Instead watch the remote condition for changes and enqueue a new request to reconcile the resource.

To avoid infinite loops, MaxIterations is defaulted to 100. Set MaxIterations to 0 to disable. ErrMaxIterations is returned when the limit is exceeded. The current iteration for the most local loop is available via RetrieveIteration.

func (*While[T]) Reconcile

func (r *While[T]) Reconcile(ctx context.Context, resource T) (Result, error)

func (*While[T]) SetupWithManager

func (r *While[T]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

type WithConfig

type WithConfig[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `WithConfig`.  Ideally unique, but
	// not required to be so.
	//
	// +optional
	Name string

	// Config to use for this portion of the reconciler hierarchy. This method is called during
	// setup and during reconciliation, if context is needed, it should be available durring both
	// phases.
	Config func(context.Context, Config) (Config, error)

	// Reconciler is called for each reconciler request with the reconciled
	// resource being reconciled. Typically a Sequence is used to compose
	// multiple SubReconcilers.
	Reconciler SubReconciler[Type]
}

Experimental: WithConfig injects the provided config into the reconcilers nested under it. For example, the client can be swapped to use a service account with different permissions, or to target an entirely different cluster.

The specified config can be accessed with `RetrieveConfig(ctx)`, the original config used to load the reconciled resource can be accessed with `RetrieveOriginalConfig(ctx)`.

func (*WithConfig[T]) Reconcile

func (r *WithConfig[T]) Reconcile(ctx context.Context, resource T) (Result, error)

func (*WithConfig[T]) SetupWithManager

func (r *WithConfig[T]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

type WithFinalizer

type WithFinalizer[Type client.Object] struct {
	// Name used to identify this reconciler.  Defaults to `WithFinalizer`.  Ideally unique, but
	// not required to be so.
	//
	// +optional
	Name string

	// Finalizer to set on the reconciled resource. The value must be unique to this specific
	// reconciler instance and not shared. Reusing a value may result in orphaned state when
	// the reconciled resource is deleted.
	//
	// Using a finalizer is encouraged when state needs to be manually cleaned up before a resource
	// is fully deleted. This commonly include state allocated outside of the current cluster.
	Finalizer string

	// Reconciler is called for each reconciler request with the reconciled
	// resource being reconciled. Typically a Sequence is used to compose
	// multiple SubReconcilers.
	Reconciler SubReconciler[Type]
}

WithFinalizer ensures the resource being reconciled has the desired finalizer set so that state can be cleaned up upon the resource being deleted. The finalizer is added to the resource, if not already set, before calling the nested reconciler. When the resource is terminating, the finalizer is cleared after returning from the nested reconciler without error.

func (*WithFinalizer[T]) Reconcile

func (r *WithFinalizer[T]) Reconcile(ctx context.Context, resource T) (Result, error)

func (*WithFinalizer[T]) SetupWithManager

func (r *WithFinalizer[T]) SetupWithManager(ctx context.Context, mgr ctrl.Manager, bldr *builder.Builder) error

Jump to

Keyboard shortcuts

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