Skip to content

Commit 37c8aa1

Browse files
committed
Return controller from builder.Build
Return controller from builder.Build to allow developers to use it after it's been created by the builder; e.g., to add watches dynamically from a reconciler. Remove deprecated SimpleController() and Builder.WithManager(). Signed-off-by: Andy Goldstein <[email protected]>
1 parent 59b131b commit 37c8aa1

File tree

5 files changed

+37
-131
lines changed

5 files changed

+37
-131
lines changed

pkg/builder/controller.go

Lines changed: 10 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"k8s.io/apimachinery/pkg/runtime"
2424
"k8s.io/client-go/rest"
2525
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
26-
"sigs.k8s.io/controller-runtime/pkg/client/config"
2726
"sigs.k8s.io/controller-runtime/pkg/controller"
2827
"sigs.k8s.io/controller-runtime/pkg/handler"
2928
"sigs.k8s.io/controller-runtime/pkg/manager"
@@ -33,9 +32,7 @@ import (
3332
)
3433

3534
// Supporting mocking out functions for testing
36-
var getConfig = config.GetConfig
3735
var newController = controller.New
38-
var newManager = manager.New
3936
var getGvk = apiutil.GVKForObject
4037

4138
// Builder builds a Controller.
@@ -50,16 +47,9 @@ type Builder struct {
5047
name string
5148
}
5249

53-
// SimpleController returns a new Builder.
54-
//
55-
// Deprecated: Use ControllerManagedBy(Manager) instead.
56-
func SimpleController() *Builder {
57-
return &Builder{}
58-
}
59-
6050
// ControllerManagedBy returns a new controller builder that will be started by the provided Manager
6151
func ControllerManagedBy(m manager.Manager) *Builder {
62-
return SimpleController().WithManager(m)
52+
return &Builder{mgr: m}
6353
}
6454

6555
// ForType defines the type of Object being *reconciled*, and configures the ControllerManagedBy to respond to create / delete /
@@ -109,14 +99,6 @@ func (blder *Builder) WithConfig(config *rest.Config) *Builder {
10999
return blder
110100
}
111101

112-
// WithManager sets the Manager to use for registering the ControllerManagedBy. Defaults to a new manager.Manager.
113-
//
114-
// Deprecated: Use ControllerManagedBy(Manager) and this isn't needed.
115-
func (blder *Builder) WithManager(m manager.Manager) *Builder {
116-
blder.mgr = m
117-
return blder
118-
}
119-
120102
// WithEventFilter sets the event filters, to filter which create/update/delete/generic events eventually
121103
// trigger reconciliations. For example, filtering on whether the resource version has changed.
122104
// Defaults to the empty list.
@@ -141,23 +123,17 @@ func (blder *Builder) Complete(r reconcile.Reconciler) error {
141123
return err
142124
}
143125

144-
// Build builds the Application ControllerManagedBy and returns the Manager used to start it.
145-
//
146-
// Deprecated: Use Complete
147-
func (blder *Builder) Build(r reconcile.Reconciler) (manager.Manager, error) {
126+
// Build builds the Application ControllerManagedBy and returns the Controller it created.
127+
func (blder *Builder) Build(r reconcile.Reconciler) (controller.Controller, error) {
148128
if r == nil {
149129
return nil, fmt.Errorf("must provide a non-nil Reconciler")
150130
}
151-
152-
// Set the Config
153-
if err := blder.loadRestConfig(); err != nil {
154-
return nil, err
131+
if blder.mgr == nil {
132+
return nil, fmt.Errorf("must provide a non-nil Manager")
155133
}
156134

157-
// Set the Manager
158-
if err := blder.doManager(); err != nil {
159-
return nil, err
160-
}
135+
// Set the Config
136+
blder.loadRestConfig()
161137

162138
// Set the ControllerManagedBy
163139
if err := blder.doController(r); err != nil {
@@ -169,7 +145,7 @@ func (blder *Builder) Build(r reconcile.Reconciler) (manager.Manager, error) {
169145
return nil, err
170146
}
171147

172-
return blder.mgr, nil
148+
return blder.ctrl, nil
173149
}
174150

175151
func (blder *Builder) doWatch() error {
@@ -203,26 +179,10 @@ func (blder *Builder) doWatch() error {
203179
return nil
204180
}
205181

206-
func (blder *Builder) loadRestConfig() error {
207-
if blder.config != nil {
208-
return nil
209-
}
210-
if blder.mgr != nil {
182+
func (blder *Builder) loadRestConfig() {
183+
if blder.config == nil {
211184
blder.config = blder.mgr.GetConfig()
212-
return nil
213185
}
214-
var err error
215-
blder.config, err = getConfig()
216-
return err
217-
}
218-
219-
func (blder *Builder) doManager() error {
220-
if blder.mgr != nil {
221-
return nil
222-
}
223-
var err error
224-
blder.mgr, err = newManager(blder.config, manager.Options{})
225-
return err
226186
}
227187

228188
func (blder *Builder) getControllerName() (string, error) {

pkg/builder/controller_test.go

Lines changed: 23 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030
"k8s.io/apimachinery/pkg/runtime"
3131
"k8s.io/apimachinery/pkg/runtime/schema"
3232
"k8s.io/apimachinery/pkg/types"
33-
"k8s.io/client-go/rest"
3433
"sigs.k8s.io/controller-runtime/pkg/controller"
3534
"sigs.k8s.io/controller-runtime/pkg/handler"
3635
"sigs.k8s.io/controller-runtime/pkg/manager"
@@ -44,9 +43,7 @@ var _ = Describe("application", func() {
4443

4544
BeforeEach(func() {
4645
stop = make(chan struct{})
47-
getConfig = func() (*rest.Config, error) { return cfg, nil }
4846
newController = controller.New
49-
newManager = manager.New
5047
})
5148

5249
AfterEach(func() {
@@ -57,35 +54,32 @@ var _ = Describe("application", func() {
5754

5855
Describe("New", func() {
5956
It("should return success if given valid objects", func() {
60-
instance, err := SimpleController().
61-
For(&appsv1.ReplicaSet{}).
62-
Owns(&appsv1.ReplicaSet{}).
63-
Build(noop)
57+
By("creating a controller manager")
58+
m, err := manager.New(cfg, manager.Options{})
6459
Expect(err).NotTo(HaveOccurred())
65-
Expect(instance).NotTo(BeNil())
66-
})
6760

68-
It("should return an error if the Config is invalid", func() {
69-
getConfig = func() (*rest.Config, error) { return cfg, fmt.Errorf("expected error") }
70-
instance, err := SimpleController().
61+
instance, err := ControllerManagedBy(m).
7162
For(&appsv1.ReplicaSet{}).
7263
Owns(&appsv1.ReplicaSet{}).
7364
Build(noop)
74-
Expect(err).To(HaveOccurred())
75-
Expect(err.Error()).To(ContainSubstring("expected error"))
76-
Expect(instance).To(BeNil())
65+
Expect(err).NotTo(HaveOccurred())
66+
Expect(instance).NotTo(BeNil())
7767
})
7868

7969
It("should return an error if there is no GVK for an object", func() {
80-
instance, err := SimpleController().
70+
By("creating a controller manager")
71+
m, err := manager.New(cfg, manager.Options{})
72+
Expect(err).NotTo(HaveOccurred())
73+
74+
instance, err := ControllerManagedBy(m).
8175
For(&fakeType{}).
8276
Owns(&appsv1.ReplicaSet{}).
8377
Build(noop)
8478
Expect(err).To(HaveOccurred())
8579
Expect(err.Error()).To(ContainSubstring("no kind is registered for the type builder.fakeType"))
8680
Expect(instance).To(BeNil())
8781

88-
instance, err = SimpleController().
82+
instance, err = ControllerManagedBy(m).
8983
For(&appsv1.ReplicaSet{}).
9084
Owns(&fakeType{}).
9185
Build(noop)
@@ -94,25 +88,17 @@ var _ = Describe("application", func() {
9488
Expect(instance).To(BeNil())
9589
})
9690

97-
It("should return an error if it cannot create the manager", func() {
98-
newManager = func(config *rest.Config, options manager.Options) (manager.Manager, error) {
99-
return nil, fmt.Errorf("expected error")
100-
}
101-
instance, err := SimpleController().
102-
For(&appsv1.ReplicaSet{}).
103-
Owns(&appsv1.ReplicaSet{}).
104-
Build(noop)
105-
Expect(err).To(HaveOccurred())
106-
Expect(err.Error()).To(ContainSubstring("expected error"))
107-
Expect(instance).To(BeNil())
108-
})
109-
11091
It("should return an error if it cannot create the controller", func() {
11192
newController = func(name string, mgr manager.Manager, options controller.Options) (
11293
controller.Controller, error) {
11394
return nil, fmt.Errorf("expected error")
11495
}
115-
instance, err := SimpleController().
96+
97+
By("creating a controller manager")
98+
m, err := manager.New(cfg, manager.Options{})
99+
Expect(err).NotTo(HaveOccurred())
100+
101+
instance, err := ControllerManagedBy(m).
116102
For(&appsv1.ReplicaSet{}).
117103
Owns(&appsv1.ReplicaSet{}).
118104
Build(noop)
@@ -150,30 +136,6 @@ var _ = Describe("application", func() {
150136
})
151137
})
152138

153-
Describe("Start with SimpleController", func() {
154-
It("should Reconcile Owns objects", func(done Done) {
155-
bldr := SimpleController().
156-
ForType(&appsv1.Deployment{}).
157-
WithConfig(cfg).
158-
Owns(&appsv1.ReplicaSet{})
159-
doReconcileTest("1", stop, bldr, nil, false)
160-
161-
close(done)
162-
}, 10)
163-
164-
It("should Reconcile Owns objects with a Manager", func(done Done) {
165-
m, err := manager.New(cfg, manager.Options{})
166-
Expect(err).NotTo(HaveOccurred())
167-
168-
bldr := SimpleController().
169-
WithManager(m).
170-
For(&appsv1.Deployment{}).
171-
Owns(&appsv1.ReplicaSet{})
172-
doReconcileTest("2", stop, bldr, m, false)
173-
close(done)
174-
}, 10)
175-
})
176-
177139
Describe("Start with ControllerManagedBy", func() {
178140
It("should Reconcile Owns objects", func(done Done) {
179141
m, err := manager.New(cfg, manager.Options{})
@@ -217,25 +179,21 @@ func doReconcileTest(nameSuffix string, stop chan struct{}, blder *Builder, mgr
217179
return reconcile.Result{}, nil
218180
})
219181

220-
instance := mgr
221182
if complete {
222183
err := blder.Complete(fn)
223184
Expect(err).NotTo(HaveOccurred())
224185
} else {
225186
var err error
226-
instance, err = blder.Build(fn)
187+
var c controller.Controller
188+
c, err = blder.Build(fn)
227189
Expect(err).NotTo(HaveOccurred())
228-
}
229-
230-
// Manager should match
231-
if mgr != nil {
232-
Expect(instance).To(Equal(mgr))
190+
Expect(c).NotTo(BeNil())
233191
}
234192

235193
By("Starting the application")
236194
go func() {
237195
defer GinkgoRecover()
238-
Expect(instance.Start(stop)).NotTo(HaveOccurred())
196+
Expect(mgr.Start(stop)).NotTo(HaveOccurred())
239197
By("Stopping the application")
240198
}()
241199

@@ -263,7 +221,7 @@ func doReconcileTest(nameSuffix string, stop chan struct{}, blder *Builder, mgr
263221
},
264222
},
265223
}
266-
err := instance.GetClient().Create(context.TODO(), dep)
224+
err := mgr.GetClient().Create(context.TODO(), dep)
267225
Expect(err).NotTo(HaveOccurred())
268226

269227
By("Waiting for the Deployment Reconcile")
@@ -293,7 +251,7 @@ func doReconcileTest(nameSuffix string, stop chan struct{}, blder *Builder, mgr
293251
Template: dep.Spec.Template,
294252
},
295253
}
296-
err = instance.GetClient().Create(context.TODO(), rs)
254+
err = mgr.GetClient().Create(context.TODO(), rs)
297255
Expect(err).NotTo(HaveOccurred())
298256

299257
By("Waiting for the ReplicaSet Reconcile")

pkg/builder/webhook.go

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,16 @@ func (blder *WebhookBuilder) For(apiType runtime.Object) *WebhookBuilder {
5555
// Complete builds the webhook.
5656
func (blder *WebhookBuilder) Complete() error {
5757
// Set the Config
58-
if err := blder.loadRestConfig(); err != nil {
59-
return err
60-
}
58+
blder.loadRestConfig()
6159

6260
// Set the Webhook if needed
6361
return blder.registerWebhooks()
6462
}
6563

66-
func (blder *WebhookBuilder) loadRestConfig() error {
67-
if blder.config != nil {
68-
return nil
69-
}
70-
if blder.mgr != nil {
64+
func (blder *WebhookBuilder) loadRestConfig() {
65+
if blder.config == nil {
7166
blder.config = blder.mgr.GetConfig()
72-
return nil
7367
}
74-
var err error
75-
blder.config, err = getConfig()
76-
return err
7768
}
7869

7970
func (blder *WebhookBuilder) registerWebhooks() error {

pkg/builder/webhook_test.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828
. "github.com/onsi/gomega"
2929
"k8s.io/apimachinery/pkg/runtime"
3030
"k8s.io/apimachinery/pkg/runtime/schema"
31-
"k8s.io/client-go/rest"
3231
"sigs.k8s.io/controller-runtime/pkg/controller"
3332
"sigs.k8s.io/controller-runtime/pkg/manager"
3433
"sigs.k8s.io/controller-runtime/pkg/scheme"
@@ -40,9 +39,7 @@ var _ = Describe("application", func() {
4039

4140
BeforeEach(func() {
4241
stop = make(chan struct{})
43-
getConfig = func() (*rest.Config, error) { return cfg, nil }
4442
newController = controller.New
45-
newManager = manager.New
4643
})
4744

4845
AfterEach(func() {

pkg/patterns/application/doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ limitations under the License.
2020
// An application is a Controller and Resource that together implement the operational logic for an application.
2121
// They are often used to take off-the-shelf OSS applications, and make them Kubernetes native.
2222
//
23-
// A typical application Controller may use a new builder.SimpleController() to create a Controller
23+
// A typical application Controller may use builder.ControllerManagedBy() to create a Controller
2424
// for a single API type that manages other objects it creates.
2525
//
2626
// Application Controllers are most useful for stateful applications such as Cassandra, Etcd and MySQL

0 commit comments

Comments
 (0)