adopt

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: May 1, 2024 License: Apache-2.0 Imports: 12 Imported by: 2

Documentation

Overview

Package adopt implements a generic adoption handler for use in controllers.

Adoption is used when the controller needs to make use of some existing resource in a cluster, generally when a reference to an object is placed in an owned object's spec (i.e. a reference to a secret or a configmap).

Adoption happens in two phases:

  1. Labelling - the resource is labelled as managed by the controller. This is primarily so that the controller an open a label-filtered watch against the cluster instead of watching all objects, which keeps the cache small and avoids unwanted data (i.e. watching all secrets).
  2. Owner Annotation - the resource is annotated as owned by one or more objects. The annotation is done using a unique field manager per owner, which allows server-side-apply to reconcile the owner annotations without providing the full list of owners every time.

There are additional utilities for cleaning up old ownership labels and annotations and for constructing or consuming index and cache keys for adopted objects.

Index

Constants

View Source
const Owned = "owned"

Owned is used in object annotations to indicate an object is managed.

Variables

This section is empty.

Functions

func OwnerKeysFromMeta

func OwnerKeysFromMeta(annotationPrefix string) func(in any) ([]string, error)

OwnerKeysFromMeta returns a set of namespace/name keys for the owners of adopted objects with `annotationPrefix`. The namespace is always set to the namespace of the object passed in.

Types

type Adoptable

type Adoptable[T any] interface {
	Annotator[T]
	Labeler[T]
}

Adoptable is any type that can be labelled and annotated. Labels are used for including in a watch stream, and annotations are used to indicated ownership by a specific object.

type AdoptionHandler

type AdoptionHandler[K Object, A Adoptable[A]] struct {
	// OperationsContext allows the adoption handler to control the sync loop
	// it's called from to deal with transient errors.
	queue.OperationsContext

	// ControllerFieldManager is the value to use when adopting the object
	// for visibility by the controller
	// If adoption is the only thing the controller needs to do with this object,
	// then it's fine to set this value to the fieldmanager used for "owned"
	// types. But a new value should be used if the controller needs to modify
	// the adopted objects in other ways, so that server-side-apply doesn't
	// revert the changes performed elsewhere in the controller.
	ControllerFieldManager string

	// AdopteeCtx tells the handler how to fetch the adoptee from context
	AdopteeCtx typedctx.MustValueContext[types.NamespacedName]

	// OwnerCtx tells the handler how to fetch the owner from context
	OwnerCtx typedctx.MustValueContext[types.NamespacedName]

	// AdoptedCtx will store the object after it has been adopted
	AdoptedCtx typedctx.SettableContext[K]

	// ObjectAdoptedFunc is called when an adoption was performed
	ObjectAdoptedFunc func(ctx context.Context, obj K)

	// ObjectMissingFunc is called when the object cannot be found
	ObjectMissingFunc func(ctx context.Context, err error)

	// GetFromCache is where we expect to find the object if it is being watched
	// This will usually be a wrapper around an informer cache `Get`.
	GetFromCache func(ctx context.Context) (K, error)

	// Indexer is the index we expect to find adopted objects
	// The absence of the object from this indexer triggers adoption.
	Indexer *typed.Indexer[K]

	// IndexName is the name of the index to look for owned objects
	IndexName string

	// Labels to add if the object is not found in the index
	// Note that this must include a label that matches the index, otherwise
	// the controller will never stop attempting to add labels.
	Labels map[string]string

	// NewPatch returns an empty object satisfying Adoptable
	// This is typically an apply configuration, like `applycorev1.Secret(name, namespace)`
	NewPatch func(types.NamespacedName) A

	// OwnerAnnotationPrefix is a common prefix for all owner annotations
	OwnerAnnotationPrefix string

	// OwnerAnnotationKeyFunc generates an ownership annotation key for a given owner
	OwnerAnnotationKeyFunc func(owner types.NamespacedName) string

	// OwnerFieldManagerFunc generates a field manager name for a given owner
	OwnerFieldManagerFunc func(owner types.NamespacedName) string

	// ApplyFunc applies adoption-related changes to the object to the cluster
	ApplyFunc ApplyFunc[K, A]

	// ExistsFunc checks if the object to be adopted exists in the cluster
	ExistsFunc ExistsFunc

	// Next is the next handler in the chain (use NoopHandler if not chaining)
	Next handler.ContextHandler
}

AdoptionHandler implements handler.Handler to "adopt" an existing resource under the controller's management. See the package description for more info.

func (*AdoptionHandler[K, A]) Handle

func (s *AdoptionHandler[K, A]) Handle(ctx context.Context)

type Annotator

type Annotator[T any] interface {
	WithAnnotations(entries map[string]string) T
}

Annotator is any type that can have annotations added to it. All standard applyconfiguration packages from client-go implement this type. Custom types should implement it themselves.

type ApplyFunc

type ApplyFunc[K Object, A Adoptable[A]] func(ctx context.Context, object A, opts metav1.ApplyOptions) (result K, err error)

ApplyFunc should apply a patch defined by the object A with server-side apply and should return the base type. For example a SecretApplyConfiguration would be applied with a client-go Patch call, and return a Secret.

type ExistsFunc added in v0.4.0

type ExistsFunc func(ctx context.Context, nn types.NamespacedName) error

ExistsFunc should return nil if the object exists in the cluster, and an error otherwise.

var (
	// AlwaysExistsFunc is an ExistsFunc that always returns nil
	AlwaysExistsFunc ExistsFunc = func(_ context.Context, _ types.NamespacedName) error {
		return nil
	}
	// NoopObjectMissingFunc is an ObjectMissing func that does nothing
	NoopObjectMissingFunc = func(_ context.Context, _ error) {}
)

type IndexKeyFunc

type IndexKeyFunc func(ctx context.Context) (indexName string, indexValue string)

IndexKeyFunc returns the name of an index to use and the value to query it for.

type Labeler

type Labeler[T any] interface {
	WithLabels(entries map[string]string) T
}

Labeler is any type that can have labels added to it. All standard applyconfiguration packages from client-go implement this type. Custom types should implement it themselves.

type Object

type Object interface {
	comparable
	runtime.Object
	metav1.Object
}

Object is satisfied by any standard kube object.

Jump to

Keyboard shortcuts

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