Skip to content

Commit 8409bdd

Browse files
committedDec 21, 2018
✨ clean up builder package and UX
- Rename Builder functions - Encourage providing the manager to the Builder factory - Deprecate discouraged functions - Add alias.go with short cuts for common functions to reduce import line bloat - Fix issue with GetConfigOrDie not exiting - Update examples - Add example at package root
1 parent b497fd5 commit 8409bdd

File tree

9 files changed

+513
-165
lines changed

9 files changed

+513
-165
lines changed
 

‎alias.go

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package controllerruntime alias' common functions and types to improve discoverability and reduce
18+
// the number of imports for simple Controllers.
19+
package controllerruntime
20+
21+
import (
22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
"k8s.io/apimachinery/pkg/runtime/schema"
24+
"sigs.k8s.io/controller-runtime/pkg/builder"
25+
"sigs.k8s.io/controller-runtime/pkg/client/config"
26+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
27+
"sigs.k8s.io/controller-runtime/pkg/manager"
28+
"sigs.k8s.io/controller-runtime/pkg/reconcile"
29+
"sigs.k8s.io/controller-runtime/pkg/runtime/log"
30+
"sigs.k8s.io/controller-runtime/pkg/runtime/scheme"
31+
"sigs.k8s.io/controller-runtime/pkg/runtime/signals"
32+
)
33+
34+
// Builder builds an Application ControllerManagedBy (e.g. Operator) and returns a manager.Manager to start it.
35+
type Builder = builder.Builder
36+
37+
// Request contains the information necessary to reconcile a Kubernetes object. This includes the
38+
// information to uniquely identify the object - its Name and Namespace. It does NOT contain information about
39+
// any specific Event or the object contents itself.
40+
type Request = reconcile.Request
41+
42+
// Result contains the result of a Reconciler invocation.
43+
type Result = reconcile.Result
44+
45+
// Manager initializes shared dependencies such as Caches and Clients, and provides them to Runnables.
46+
// A Manager is required to create Controllers.
47+
type Manager = manager.Manager
48+
49+
// Options are the arguments for creating a new Manager
50+
type Options = manager.Options
51+
52+
// Builder builds a new Scheme for mapping go types to Kubernetes GroupVersionKinds.
53+
type SchemeBuilder = scheme.Builder
54+
55+
// GroupVersion contains the "group" and the "version", which uniquely identifies the API.
56+
type GroupVersion = schema.GroupVersion
57+
58+
// GroupResource specifies a Group and a Resource, but does not force a version. This is useful for identifying
59+
// concepts during lookup stages without having partially valid types
60+
type GroupResource = schema.GroupResource
61+
62+
// TypeMeta describes an individual object in an API response or request
63+
// with strings representing the type of the object and its API schema version.
64+
// Structures that are versioned or persisted should inline TypeMeta.
65+
//
66+
// +k8s:deepcopy-gen=false
67+
type TypeMeta = metav1.TypeMeta
68+
69+
// ObjectMeta is metadata that all persisted resources must have, which includes all objects
70+
// users must create.
71+
type ObjectMeta = metav1.ObjectMeta
72+
73+
var (
74+
// GetConfigOrDie creates a *rest.Config for talking to a Kubernetes apiserver.
75+
// If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running
76+
// in cluster and use the cluster provided kubeconfig.
77+
//
78+
// Will log an error and exit if there is an error creating the rest.Config.
79+
GetConfigOrDie = config.GetConfigOrDie
80+
81+
// GetConfig creates a *rest.Config for talking to a Kubernetes apiserver.
82+
// If --kubeconfig is set, will use the kubeconfig file at that location. Otherwise will assume running
83+
// in cluster and use the cluster provided kubeconfig.
84+
//
85+
// Config precedence
86+
//
87+
// * --kubeconfig flag pointing at a file
88+
//
89+
// * KUBECONFIG environment variable pointing at a file
90+
//
91+
// * In-cluster config if running in cluster
92+
//
93+
// * $HOME/.kube/config if exists
94+
GetConfig = config.GetConfig
95+
96+
// NewControllerManagedBy returns a new controller builder that will be started by the provided Manager
97+
NewControllerManagedBy = builder.ControllerManagedBy
98+
99+
// NewManager returns a new Manager for creating Controllers.
100+
NewManager = manager.New
101+
102+
// CreateOrUpdate creates or updates the given object obj in the Kubernetes
103+
// cluster. The object's desired state should be reconciled with the existing
104+
// state using the passed in ReconcileFn. obj must be a struct pointer so that
105+
// obj can be updated with the content returned by the Server.
106+
//
107+
// It returns the executed operation and an error.
108+
CreateOrUpdate = controllerutil.CreateOrUpdate
109+
110+
// SetControllerReference sets owner as a Controller OwnerReference on owned.
111+
// This is used for garbage collection of the owned object and for
112+
// reconciling the owner object on changes to owned (with a Watch + EnqueueRequestForOwner).
113+
// Since only one OwnerReference can be a controller, it returns an error if
114+
// there is another OwnerReference with Controller flag set.
115+
SetControllerReference = controllerutil.SetControllerReference
116+
117+
// SetupSignalHandler registered for SIGTERM and SIGINT. A stop channel is returned
118+
// which is closed on one of these signals. If a second signal is caught, the program
119+
// is terminated with exit code 1.
120+
SetupSignalHandler = signals.SetupSignalHandler
121+
122+
// Log is the base logger used by controller-runtime. It delegates
123+
// to another logr.Logger. You *must* call SetLogger to
124+
// get any actual logging.
125+
Log = log.Log
126+
127+
// SetLogger sets a concrete logging implementation for all deferred Loggers.
128+
SetLogger = log.SetLogger
129+
130+
// ZapLogger is a Logger implementation.
131+
// If development is true, a Zap development config will be used
132+
// (stacktraces on warnings, no sampling), otherwise a Zap production
133+
// config will be used (stacktraces on errors, sampling).
134+
ZapLogger = log.ZapLogger
135+
)

‎example_test.go

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
Copyright 2018 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package controllerruntime_test
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"os"
23+
24+
appsv1 "k8s.io/api/apps/v1"
25+
corev1 "k8s.io/api/core/v1"
26+
controllers "sigs.k8s.io/controller-runtime"
27+
"sigs.k8s.io/controller-runtime/pkg/client"
28+
)
29+
30+
// This example creates a simple application Controller that is configured for ReplicaSets and Pods.
31+
//
32+
// * Create a new application for ReplicaSets that manages Pods owned by the ReplicaSet and calls into
33+
// ReplicaSetReconciler.
34+
//
35+
// * Start the application.
36+
// TODO(pwittrock): Update this example when we have better dependency injection support
37+
func Example() {
38+
var log = controllers.Log.WithName("builder-examples")
39+
40+
manager, err := controllers.NewManager(controllers.GetConfigOrDie(), controllers.Options{})
41+
if err != nil {
42+
log.Error(err, "could not create manager")
43+
os.Exit(1)
44+
}
45+
46+
err = controllers.
47+
NewControllerManagedBy(manager). // Create the Controller
48+
For(&appsv1.ReplicaSet{}). // ReplicaSet is the Application API
49+
Owns(&corev1.Pod{}). // ReplicaSet owns Pods created by it
50+
Complete(&ReplicaSetReconciler{Client: manager.GetClient()})
51+
if err != nil {
52+
log.Error(err, "could not create controller")
53+
os.Exit(1)
54+
}
55+
56+
if err := manager.Start(controllers.SetupSignalHandler()); err != nil {
57+
log.Error(err, "could not start manager")
58+
os.Exit(1)
59+
}
60+
}
61+
62+
// ReplicaSetReconciler is a simple Controller example implementation.
63+
type ReplicaSetReconciler struct {
64+
client.Client
65+
}
66+
67+
// Implement the business logic:
68+
// This function will be called when there is a change to a ReplicaSet or a Pod with an OwnerReference
69+
// to a ReplicaSet.
70+
//
71+
// * Read the ReplicaSet
72+
// * Read the Pods
73+
// * Set a Label on the ReplicaSet with the Pod count
74+
func (a *ReplicaSetReconciler) Reconcile(req controllers.Request) (controllers.Result, error) {
75+
// Read the ReplicaSet
76+
rs := &appsv1.ReplicaSet{}
77+
err := a.Get(context.TODO(), req.NamespacedName, rs)
78+
if err != nil {
79+
return controllers.Result{}, err
80+
}
81+
82+
// List the Pods matching the PodTemplate Labels
83+
pods := &corev1.PodList{}
84+
err = a.List(context.TODO(), client.InNamespace(req.Namespace).MatchingLabels(rs.Spec.Template.Labels), pods)
85+
if err != nil {
86+
return controllers.Result{}, err
87+
}
88+
89+
// Update the ReplicaSet
90+
rs.Labels["pod-count"] = fmt.Sprintf("%v", len(pods.Items))
91+
err = a.Update(context.TODO(), rs)
92+
if err != nil {
93+
return controllers.Result{}, err
94+
}
95+
96+
return controllers.Result{}, nil
97+
}

0 commit comments

Comments
 (0)