Documentation ¶
Overview ¶
Package builder wraps other controller-runtime libraries and exposes simple patterns for building common Controllers.
Projects built with the builder package can trivially be rebased on top of the underlying packages if the project requires more customized behavior in the future.
Index ¶
- Variables
- type Builder
- func (blder *Builder) Build(r reconcile.Reconciler) (controller.Controller, error)
- func (blder *Builder) Complete(r reconcile.Reconciler) error
- func (blder *Builder) For(object client.Object, opts ...ForOption) *Builder
- func (blder *Builder) Named(name string) *Builder
- func (blder *Builder) Owns(object client.Object, opts ...OwnsOption) *Builder
- func (blder *Builder) Watches(src source.Source, eventhandler handler.EventHandler, opts ...WatchesOption) *Builder
- func (blder *Builder) WithEventFilter(p predicate.Predicate) *Builder
- func (blder *Builder) WithLogConstructor(logConstructor func(*reconcile.Request) logr.Logger) *Builder
- func (blder *Builder) WithOptions(options controller.Options) *Builder
- type ForInput
- type ForOption
- type OwnsInput
- type OwnsOption
- type Predicates
- type WatchesInput
- type WatchesOption
- type WebhookBuilder
- func (blder *WebhookBuilder) Complete() error
- func (blder *WebhookBuilder) For(apiType runtime.Object) *WebhookBuilder
- func (blder *WebhookBuilder) RecoverPanic() *WebhookBuilder
- func (blder *WebhookBuilder) WithDefaulter(defaulter admission.CustomDefaulter) *WebhookBuilder
- func (blder *WebhookBuilder) WithValidator(validator admission.CustomValidator) *WebhookBuilder
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // OnlyMetadata tells the controller to *only* cache metadata, and to watch // the API server in metadata-only form. This is useful when watching // lots of objects, really big objects, or objects for which you only know // the GVK, but not the structure. You'll need to pass // metav1.PartialObjectMetadata to the client when fetching objects in your // reconciler, otherwise you'll end up with a duplicate structured or // unstructured cache. // // When watching a resource with OnlyMetadata, for example the v1.Pod, you // should not Get and List using the v1.Pod type. Instead, you should use // the special metav1.PartialObjectMetadata type. // // ❌ Incorrect: // // pod := &v1.Pod{} // mgr.GetClient().Get(ctx, nsAndName, pod) // // ✅ Correct: // // pod := &metav1.PartialObjectMetadata{} // pod.SetGroupVersionKind(schema.GroupVersionKind{ // Group: "", // Version: "v1", // Kind: "Pod", // }) // mgr.GetClient().Get(ctx, nsAndName, pod) // // In the first case, controller-runtime will create another cache for the // concrete type on top of the metadata cache; this increases memory // consumption and leads to race conditions as caches are not in sync. OnlyMetadata = projectAs(projectAsMetadata) )
Functions ¶
This section is empty.
Types ¶
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder builds a Controller.
Example ¶
This example creates a simple application ControllerManagedBy that is configured for ReplicaSets and Pods.
* Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into ReplicaSetReconciler.
* Start the application.
package main import ( "context" "fmt" "os" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" "github.com/samuelkuklis/controller-runtime/pkg/builder" "github.com/samuelkuklis/controller-runtime/pkg/client" "github.com/samuelkuklis/controller-runtime/pkg/client/config" logf "github.com/samuelkuklis/controller-runtime/pkg/log" "github.com/samuelkuklis/controller-runtime/pkg/log/zap" "github.com/samuelkuklis/controller-runtime/pkg/manager" "github.com/samuelkuklis/controller-runtime/pkg/manager/signals" "github.com/samuelkuklis/controller-runtime/pkg/reconcile" ) func main() { logf.SetLogger(zap.New()) var log = logf.Log.WithName("builder-examples") mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{}) if err != nil { log.Error(err, "could not create manager") os.Exit(1) } err = builder. ControllerManagedBy(mgr). // Create the ControllerManagedBy For(&appsv1.ReplicaSet{}). // ReplicaSet is the Application API Owns(&corev1.Pod{}). // ReplicaSet owns Pods created by it Complete(&ReplicaSetReconciler{}) if err != nil { log.Error(err, "could not create controller") os.Exit(1) } if err := mgr.Start(signals.SetupSignalHandler()); err != nil { log.Error(err, "could not start manager") os.Exit(1) } } // ReplicaSetReconciler is a simple ControllerManagedBy example implementation. type ReplicaSetReconciler struct { client.Client } // Implement the business logic: // This function will be called when there is a change to a ReplicaSet or a Pod with an OwnerReference // to a ReplicaSet. // // * Read the ReplicaSet // * Read the Pods // * Set a Label on the ReplicaSet with the Pod count. func (a *ReplicaSetReconciler) Reconcile(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { rs := &appsv1.ReplicaSet{} err := a.Get(ctx, req.NamespacedName, rs) if err != nil { return reconcile.Result{}, err } pods := &corev1.PodList{} err = a.List(ctx, pods, client.InNamespace(req.Namespace), client.MatchingLabels(rs.Spec.Template.Labels)) if err != nil { return reconcile.Result{}, err } rs.Labels["pod-count"] = fmt.Sprintf("%v", len(pods.Items)) err = a.Update(ctx, rs) if err != nil { return reconcile.Result{}, err } return reconcile.Result{}, nil } func (a *ReplicaSetReconciler) InjectClient(c client.Client) error { a.Client = c return nil }
Output:
Example (Metadata_only) ¶
package main import ( "context" "fmt" "os" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/samuelkuklis/controller-runtime/pkg/builder" "github.com/samuelkuklis/controller-runtime/pkg/client" "github.com/samuelkuklis/controller-runtime/pkg/client/config" logf "github.com/samuelkuklis/controller-runtime/pkg/log" "github.com/samuelkuklis/controller-runtime/pkg/log/zap" "github.com/samuelkuklis/controller-runtime/pkg/manager" "github.com/samuelkuklis/controller-runtime/pkg/manager/signals" "github.com/samuelkuklis/controller-runtime/pkg/reconcile" ) func main() { logf.SetLogger(zap.New()) var log = logf.Log.WithName("builder-examples") mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{}) if err != nil { log.Error(err, "could not create manager") os.Exit(1) } cl := mgr.GetClient() err = builder. ControllerManagedBy(mgr). // Create the ControllerManagedBy For(&appsv1.ReplicaSet{}). // ReplicaSet is the Application API Owns(&corev1.Pod{}, builder.OnlyMetadata). // ReplicaSet owns Pods created by it, and caches them as metadata only Complete(reconcile.Func(func(ctx context.Context, req reconcile.Request) (reconcile.Result, error) { // Read the ReplicaSet rs := &appsv1.ReplicaSet{} err := cl.Get(ctx, req.NamespacedName, rs) if err != nil { return reconcile.Result{}, client.IgnoreNotFound(err) } // List the Pods matching the PodTemplate Labels, but only their metadata var podsMeta metav1.PartialObjectMetadataList err = cl.List(ctx, &podsMeta, client.InNamespace(req.Namespace), client.MatchingLabels(rs.Spec.Template.Labels)) if err != nil { return reconcile.Result{}, client.IgnoreNotFound(err) } // Update the ReplicaSet rs.Labels["pod-count"] = fmt.Sprintf("%v", len(podsMeta.Items)) err = cl.Update(ctx, rs) if err != nil { return reconcile.Result{}, err } return reconcile.Result{}, nil })) if err != nil { log.Error(err, "could not create controller") os.Exit(1) } if err := mgr.Start(signals.SetupSignalHandler()); err != nil { log.Error(err, "could not start manager") os.Exit(1) } }
Output:
func ControllerManagedBy ¶ added in v0.1.10
ControllerManagedBy returns a new controller builder that will be started by the provided Manager.
func (*Builder) Build ¶
func (blder *Builder) Build(r reconcile.Reconciler) (controller.Controller, error)
Build builds the Application Controller and returns the Controller it created.
func (*Builder) Complete ¶ added in v0.1.10
func (blder *Builder) Complete(r reconcile.Reconciler) error
Complete builds the Application Controller.
func (*Builder) For ¶ added in v0.1.10
For defines the type of Object being *reconciled*, and configures the ControllerManagedBy to respond to create / delete / update events by *reconciling the object*. This is the equivalent of calling Watches(&source.Kind{Type: apiType}, &handler.EnqueueRequestForObject{}).
func (*Builder) Named ¶ added in v1.0.1
Named sets the name of the controller to the given name. The name shows up in metrics, among other things, and thus should be a prometheus compatible name (underscores and alphanumeric characters only).
By default, controllers are named using the lowercase version of their kind.
func (*Builder) Owns ¶
func (blder *Builder) Owns(object client.Object, opts ...OwnsOption) *Builder
Owns defines types of Objects being *generated* by the ControllerManagedBy, and configures the ControllerManagedBy to respond to create / delete / update events by *reconciling the owner object*. This is the equivalent of calling Watches(&source.Kind{Type: <ForType-forInput>}, &handler.EnqueueRequestForOwner{OwnerType: apiType, IsController: true}).
func (*Builder) Watches ¶ added in v0.1.10
func (blder *Builder) Watches(src source.Source, eventhandler handler.EventHandler, opts ...WatchesOption) *Builder
Watches exposes the lower-level ControllerManagedBy Watches functions through the builder. Consider using Owns or For instead of Watches directly. Specified predicates are registered only for given source.
func (*Builder) WithEventFilter ¶
WithEventFilter sets the event filters, to filter which create/update/delete/generic events eventually trigger reconciliations. For example, filtering on whether the resource version has changed. Given predicate is added for all watched objects. Defaults to the empty list.
func (*Builder) WithLogConstructor ¶ added in v1.0.1
func (blder *Builder) WithLogConstructor(logConstructor func(*reconcile.Request) logr.Logger) *Builder
WithLogConstructor overrides the controller options's LogConstructor.
func (*Builder) WithOptions ¶ added in v1.0.1
func (blder *Builder) WithOptions(options controller.Options) *Builder
WithOptions overrides the controller options use in doController. Defaults to empty.
type ForInput ¶ added in v1.0.1
type ForInput struct {
// contains filtered or unexported fields
}
ForInput represents the information set by For method.
type ForOption ¶ added in v1.0.1
type ForOption interface { // ApplyToFor applies this configuration to the given for input. ApplyToFor(*ForInput) }
ForOption is some configuration that modifies options for a For request.
type OwnsInput ¶ added in v1.0.1
type OwnsInput struct {
// contains filtered or unexported fields
}
OwnsInput represents the information set by Owns method.
type OwnsOption ¶ added in v1.0.1
type OwnsOption interface { // ApplyToOwns applies this configuration to the given owns input. ApplyToOwns(*OwnsInput) }
OwnsOption is some configuration that modifies options for a owns request.
type Predicates ¶ added in v1.0.1
type Predicates struct {
// contains filtered or unexported fields
}
Predicates filters events before enqueuing the keys.
func WithPredicates ¶ added in v1.0.1
func WithPredicates(predicates ...predicate.Predicate) Predicates
WithPredicates sets the given predicates list.
func (Predicates) ApplyToFor ¶ added in v1.0.1
func (w Predicates) ApplyToFor(opts *ForInput)
ApplyToFor applies this configuration to the given ForInput options.
func (Predicates) ApplyToOwns ¶ added in v1.0.1
func (w Predicates) ApplyToOwns(opts *OwnsInput)
ApplyToOwns applies this configuration to the given OwnsInput options.
func (Predicates) ApplyToWatches ¶ added in v1.0.1
func (w Predicates) ApplyToWatches(opts *WatchesInput)
ApplyToWatches applies this configuration to the given WatchesInput options.
type WatchesInput ¶ added in v1.0.1
type WatchesInput struct {
// contains filtered or unexported fields
}
WatchesInput represents the information set by Watches method.
type WatchesOption ¶ added in v1.0.1
type WatchesOption interface { // ApplyToWatches applies this configuration to the given watches options. ApplyToWatches(*WatchesInput) }
WatchesOption is some configuration that modifies options for a watches request.
type WebhookBuilder ¶ added in v1.0.1
type WebhookBuilder struct {
// contains filtered or unexported fields
}
WebhookBuilder builds a Webhook.
Example ¶
This example use webhook builder to create a simple webhook that is managed by a manager for CRD ChaosPod. And then start the manager.
package main import ( "os" "github.com/samuelkuklis/controller-runtime/pkg/builder" "github.com/samuelkuklis/controller-runtime/pkg/client/config" logf "github.com/samuelkuklis/controller-runtime/pkg/log" "github.com/samuelkuklis/controller-runtime/pkg/manager" "github.com/samuelkuklis/controller-runtime/pkg/manager/signals" "github.com/samuelkuklis/controller-runtime/pkg/webhook/admission" examplegroup "github.com/samuelkuklis/controller-runtime/examples/crd/pkg" ) // examplegroup.ChaosPod has implemented both admission.Defaulter and // admission.Validator interfaces. var _ admission.Defaulter = &examplegroup.ChaosPod{} var _ admission.Validator = &examplegroup.ChaosPod{} // This example use webhook builder to create a simple webhook that is managed // by a manager for CRD ChaosPod. And then start the manager. func main() { var log = logf.Log.WithName("webhookbuilder-example") mgr, err := manager.New(config.GetConfigOrDie(), manager.Options{}) if err != nil { log.Error(err, "could not create manager") os.Exit(1) } err = builder. WebhookManagedBy(mgr). // Create the WebhookManagedBy For(&examplegroup.ChaosPod{}). // ChaosPod is a CRD. Complete() if err != nil { log.Error(err, "could not create webhook") os.Exit(1) } if err := mgr.Start(signals.SetupSignalHandler()); err != nil { log.Error(err, "could not start manager") os.Exit(1) } }
Output:
func WebhookManagedBy ¶ added in v1.0.1
func WebhookManagedBy(m manager.Manager) *WebhookBuilder
WebhookManagedBy allows inform its manager.Manager.
func (*WebhookBuilder) Complete ¶ added in v1.0.1
func (blder *WebhookBuilder) Complete() error
Complete builds the webhook.
func (*WebhookBuilder) For ¶ added in v1.0.1
func (blder *WebhookBuilder) For(apiType runtime.Object) *WebhookBuilder
For takes a runtime.Object which should be a CR. If the given object implements the admission.Defaulter interface, a MutatingWebhook will be wired for this type. If the given object implements the admission.Validator interface, a ValidatingWebhook will be wired for this type.
func (*WebhookBuilder) RecoverPanic ¶ added in v1.0.1
func (blder *WebhookBuilder) RecoverPanic() *WebhookBuilder
RecoverPanic indicates whether the panic caused by webhook should be recovered.
func (*WebhookBuilder) WithDefaulter ¶ added in v1.0.1
func (blder *WebhookBuilder) WithDefaulter(defaulter admission.CustomDefaulter) *WebhookBuilder
WithDefaulter takes a admission.WithDefaulter interface, a MutatingWebhook will be wired for this type.
func (*WebhookBuilder) WithValidator ¶ added in v1.0.1
func (blder *WebhookBuilder) WithValidator(validator admission.CustomValidator) *WebhookBuilder
WithValidator takes a admission.WithValidator interface, a ValidatingWebhook will be wired for this type.