2
2
using System . Text ;
3
3
4
4
using k8s ;
5
+ using k8s . LeaderElection ;
6
+ using k8s . LeaderElection . ResourceLock ;
5
7
using k8s . Models ;
6
8
7
9
using KubeOps . Abstractions . Builder ;
@@ -22,13 +24,13 @@ namespace KubeOps.Operator.Builder;
22
24
23
25
internal class OperatorBuilder : IOperatorBuilder
24
26
{
27
+ private readonly OperatorSettings _settings ;
28
+
25
29
public OperatorBuilder ( IServiceCollection services , OperatorSettings settings )
26
30
{
31
+ _settings = settings ;
27
32
Services = services ;
28
- Services . AddSingleton ( settings ) ;
29
- Services . AddTransient < IKubernetesClient < Corev1Event > > ( _ => new KubernetesClient < Corev1Event > ( new (
30
- Corev1Event . KubeKind , Corev1Event . KubeApiVersion , Plural : Corev1Event . KubePluralName ) ) ) ;
31
- Services . AddTransient ( CreateEventPublisher ( ) ) ;
33
+ AddOperatorBase ( ) ;
32
34
}
33
35
34
36
public IServiceCollection Services { get ; }
@@ -45,10 +47,18 @@ public IOperatorBuilder AddController<TImplementation, TEntity>()
45
47
where TEntity : IKubernetesObject < V1ObjectMeta >
46
48
{
47
49
Services . AddScoped < IEntityController < TEntity > , TImplementation > ( ) ;
48
- Services . AddHostedService < ResourceWatcher < TEntity > > ( ) ;
49
50
Services . AddSingleton ( new TimedEntityQueue < TEntity > ( ) ) ;
50
51
Services . AddTransient ( CreateEntityRequeue < TEntity > ( ) ) ;
51
52
53
+ if ( _settings . EnableLeaderElection )
54
+ {
55
+ Services . AddHostedService < LeaderAwareResourceWatcher < TEntity > > ( ) ;
56
+ }
57
+ else
58
+ {
59
+ Services . AddHostedService < ResourceWatcher < TEntity > > ( ) ;
60
+ }
61
+
52
62
return this ;
53
63
}
54
64
@@ -99,7 +109,7 @@ private static Func<IServiceProvider, EntityFinalizerAttacher<TImplementation, T
99
109
100
110
private static Func < IServiceProvider , EntityRequeue < TEntity > > CreateEntityRequeue < TEntity > ( )
101
111
where TEntity : IKubernetesObject < V1ObjectMeta >
102
- => services => ( entity , timespan ) =>
112
+ => services => ( entity , timeSpan ) =>
103
113
{
104
114
var logger = services . GetService < ILogger < EntityRequeue < TEntity > > > ( ) ;
105
115
var queue = services . GetRequiredService < TimedEntityQueue < TEntity > > ( ) ;
@@ -108,9 +118,9 @@ private static Func<IServiceProvider, EntityRequeue<TEntity>> CreateEntityRequeu
108
118
"""Requeue entity "{kind}/{name}" in {milliseconds}ms.""" ,
109
119
entity . Kind ,
110
120
entity . Name ( ) ,
111
- timespan . TotalMilliseconds ) ;
121
+ timeSpan . TotalMilliseconds ) ;
112
122
113
- queue . Enqueue ( entity , timespan ) ;
123
+ queue . Enqueue ( entity , timeSpan ) ;
114
124
} ;
115
125
116
126
private static Func < IServiceProvider , EventPublisher > CreateEventPublisher ( )
@@ -192,4 +202,33 @@ private static Func<IServiceProvider, EventPublisher> CreateEventPublisher()
192
202
entity . Name ( ) ) ;
193
203
}
194
204
} ;
205
+
206
+ private void AddOperatorBase ( )
207
+ {
208
+ Services . AddSingleton ( _settings ) ;
209
+ Services . AddTransient < IKubernetesClient < Corev1Event > > ( _ => new KubernetesClient < Corev1Event > ( new (
210
+ Corev1Event . KubeKind , Corev1Event . KubeApiVersion , Plural : Corev1Event . KubePluralName ) ) ) ;
211
+ Services . AddTransient ( CreateEventPublisher ( ) ) ;
212
+
213
+ if ( _settings . EnableLeaderElection )
214
+ {
215
+ using var client = new KubernetesClient < Corev1Event > ( new (
216
+ Corev1Event . KubeKind , Corev1Event . KubeApiVersion , Plural : Corev1Event . KubePluralName ) ) ;
217
+
218
+ var elector = new LeaderElector (
219
+ new LeaderElectionConfig (
220
+ new LeaseLock (
221
+ new Kubernetes ( KubernetesClientConfiguration . BuildDefaultConfig ( ) ) ,
222
+ client . GetCurrentNamespace ( ) ,
223
+ $ "{ _settings . Name } -leader",
224
+ Environment . MachineName ) )
225
+ {
226
+ LeaseDuration = _settings . LeaderElectionLeaseDuration ,
227
+ RenewDeadline = _settings . LeaderElectionRenewDeadline ,
228
+ RetryPeriod = _settings . LeaderElectionRetryPeriod ,
229
+ } ) ;
230
+ Services . AddSingleton ( elector ) ;
231
+ elector . RunAsync ( ) ;
232
+ }
233
+ }
195
234
}
0 commit comments