@@ -25,11 +25,13 @@ import (
25
25
"k8s.io/apimachinery/pkg/runtime"
26
26
"k8s.io/client-go/kubernetes/scheme"
27
27
"k8s.io/client-go/rest"
28
+ "k8s.io/client-go/tools/leaderelection/resourcelock"
28
29
"k8s.io/client-go/tools/record"
29
30
"sigs.k8s.io/controller-runtime/pkg/cache"
30
31
"sigs.k8s.io/controller-runtime/pkg/client"
31
32
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
32
33
internalrecorder "sigs.k8s.io/controller-runtime/pkg/internal/recorder"
34
+ "sigs.k8s.io/controller-runtime/pkg/leaderelection"
33
35
"sigs.k8s.io/controller-runtime/pkg/recorder"
34
36
)
35
37
@@ -83,10 +85,23 @@ type Options struct {
83
85
// value only if you know what you are doing. Defaults to 10 hours if unset.
84
86
SyncPeriod * time.Duration
85
87
88
+ // LeaderElection determines whether or not to use leader election when
89
+ // starting the manager.
90
+ LeaderElection bool
91
+
92
+ // LeaderElectionNamespace determines the namespace in which the leader
93
+ // election configmap will be created.
94
+ LeaderElectionNamespace string
95
+
96
+ // LeaderElectionID determines the name of the configmap that leader election
97
+ // will use for holding the leader lock.
98
+ LeaderElectionID string
99
+
86
100
// Dependency injection for testing
87
101
newCache func (config * rest.Config , opts cache.Options ) (cache.Cache , error )
88
102
newClient func (config * rest.Config , options client.Options ) (client.Client , error )
89
103
newRecorderProvider func (config * rest.Config , scheme * runtime.Scheme , logger logr.Logger ) (recorder.Provider , error )
104
+ newResourceLock func (config * rest.Config , recorderProvider recorder.Provider , options leaderelection.Options ) (resourcelock.Interface , error )
90
105
}
91
106
92
107
// Runnable allows a component to be started.
@@ -140,6 +155,16 @@ func New(config *rest.Config, options Options) (Manager, error) {
140
155
return nil , err
141
156
}
142
157
158
+ // Create the resource lock to enable leader election)
159
+ resourceLock , err := options .newResourceLock (config , recorderProvider , leaderelection.Options {
160
+ LeaderElection : options .LeaderElection ,
161
+ LeaderElectionID : options .LeaderElectionID ,
162
+ LeaderElectionNamespace : options .LeaderElectionNamespace ,
163
+ })
164
+ if err != nil {
165
+ return nil , err
166
+ }
167
+
143
168
return & controllerManager {
144
169
config : config ,
145
170
scheme : options .Scheme ,
@@ -148,6 +173,7 @@ func New(config *rest.Config, options Options) (Manager, error) {
148
173
fieldIndexes : cache ,
149
174
client : client.DelegatingClient {Reader : cache , Writer : writeObj , StatusClient : writeObj },
150
175
recorderProvider : recorderProvider ,
176
+ resourceLock : resourceLock ,
151
177
}, nil
152
178
}
153
179
@@ -177,5 +203,10 @@ func setOptionsDefaults(options Options) Options {
177
203
options .newRecorderProvider = internalrecorder .NewProvider
178
204
}
179
205
206
+ // Allow newResourceLock to be mocked
207
+ if options .newResourceLock == nil {
208
+ options .newResourceLock = leaderelection .NewResourceLock
209
+ }
210
+
180
211
return options
181
212
}
0 commit comments