@@ -6,11 +6,15 @@ package cilium
6
6
import (
7
7
"context"
8
8
"fmt"
9
+ "time"
9
10
11
+ "github.com/go-logr/logr"
10
12
"github.com/spf13/pflag"
13
+ appsv1 "k8s.io/api/apps/v1"
11
14
corev1 "k8s.io/api/core/v1"
12
15
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13
16
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
17
+ "sigs.k8s.io/cluster-api/controllers/remote"
14
18
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
15
19
ctrl "sigs.k8s.io/controller-runtime"
16
20
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
@@ -19,10 +23,12 @@ import (
19
23
commonhandlers "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers"
20
24
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/handlers/lifecycle"
21
25
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/clustertopology/variables"
26
+ capiutils "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/common/pkg/capi/utils"
22
27
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/lifecycle/addons"
23
28
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/generic/lifecycle/config"
24
29
"github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/options"
25
30
handlersutils "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/handlers/utils"
31
+ "github.com/nutanix-cloud-native/cluster-api-runtime-extensions-nutanix/pkg/wait"
26
32
)
27
33
28
34
type CNIConfig struct {
@@ -222,7 +228,8 @@ func (c *CiliumCNI) apply(
222
228
c .client ,
223
229
helmChart ,
224
230
).
225
- WithValueTemplater (templateValues )
231
+ WithValueTemplater (templateValues ).
232
+ WithDefaultWaiter ()
226
233
case "" :
227
234
resp .SetStatus (runtimehooksv1 .ResponseStatusFailure )
228
235
resp .SetMessage ("strategy not specified for Cilium CNI addon" )
@@ -232,11 +239,129 @@ func (c *CiliumCNI) apply(
232
239
return
233
240
}
234
241
235
- if err := strategy . Apply (ctx , cluster , targetNamespace , log ); err != nil {
242
+ if err := runApply (ctx , c . client , cluster , strategy , targetNamespace , log ); err != nil {
236
243
resp .SetStatus (runtimehooksv1 .ResponseStatusFailure )
237
244
resp .SetMessage (err .Error ())
238
245
return
239
246
}
240
247
241
248
resp .SetStatus (runtimehooksv1 .ResponseStatusSuccess )
242
249
}
250
+
251
+ func runApply (
252
+ ctx context.Context ,
253
+ client ctrlclient.Client ,
254
+ cluster * clusterv1.Cluster ,
255
+ strategy addons.Applier ,
256
+ targetNamespace string ,
257
+ log logr.Logger ,
258
+ ) error {
259
+ if err := strategy .Apply (ctx , cluster , targetNamespace , log ); err != nil {
260
+ return err
261
+ }
262
+
263
+ // If skip kube-proxy is not set, return early.
264
+ // Otherwise, wait for Cilium to be rolled out and then cleanup kube-proxy if installed.
265
+ if ! capiutils .SkipKubeProxy (cluster ) {
266
+ return nil
267
+ }
268
+
269
+ log .Info (
270
+ fmt .Sprintf ("Waiting for Cilium to be ready for cluster %s" , ctrlclient .ObjectKeyFromObject (cluster )),
271
+ )
272
+ if err := waitForCiliumToBeReady (ctx , client , cluster ); err != nil {
273
+ return fmt .Errorf ("failed to wait for Cilium to be ready: %w" , err )
274
+ }
275
+
276
+ log .Info (
277
+ fmt .Sprintf ("Cleaning up kube-proxy for cluster %s" , ctrlclient .ObjectKeyFromObject (cluster )),
278
+ )
279
+ if err := cleanupKubeProxy (ctx , client , cluster ); err != nil {
280
+ return fmt .Errorf ("failed to cleanup kube-proxy: %w" , err )
281
+ }
282
+
283
+ return nil
284
+ }
285
+
286
+ const (
287
+ kubeProxyName = "kube-proxy"
288
+ kubeProxyNamespace = "kube-system"
289
+ )
290
+
291
+ func waitForCiliumToBeReady (
292
+ ctx context.Context ,
293
+ c ctrlclient.Client ,
294
+ cluster * clusterv1.Cluster ,
295
+ ) error {
296
+ remoteClient , err := remote .NewClusterClient (
297
+ ctx ,
298
+ "" ,
299
+ c ,
300
+ ctrlclient .ObjectKeyFromObject (cluster ),
301
+ )
302
+ if err != nil {
303
+ return fmt .Errorf ("error creating remote cluster client: %w" , err )
304
+ }
305
+
306
+ ds := & appsv1.DaemonSet {
307
+ ObjectMeta : metav1.ObjectMeta {
308
+ Name : defaultCiliumReleaseName ,
309
+ Namespace : defaultCiliumNamespace ,
310
+ },
311
+ }
312
+ if err := wait .ForObject (
313
+ ctx ,
314
+ wait.ForObjectInput [* appsv1.DaemonSet ]{
315
+ Reader : remoteClient ,
316
+ Target : ds .DeepCopy (),
317
+ Check : func (_ context.Context , obj * appsv1.DaemonSet ) (bool , error ) {
318
+ return obj .Status .NumberAvailable == obj .Status .DesiredNumberScheduled && obj .Status .NumberUnavailable == 0 , nil
319
+ },
320
+ Interval : 1 * time .Second ,
321
+ Timeout : 30 * time .Second ,
322
+ },
323
+ ); err != nil {
324
+ return fmt .Errorf (
325
+ "failed to wait for DaemonSet %s to be Ready: %w" ,
326
+ ctrlclient .ObjectKeyFromObject (ds ),
327
+ err ,
328
+ )
329
+ }
330
+
331
+ return nil
332
+ }
333
+
334
+ // cleanupKubeProxy cleans up kube-proxy DaemonSet and ConfigMap on the remote cluster when kube-proxy is disabled.
335
+ func cleanupKubeProxy (ctx context.Context , c ctrlclient.Client , cluster * clusterv1.Cluster ) error {
336
+ remoteClient , err := remote .NewClusterClient (
337
+ ctx ,
338
+ "" ,
339
+ c ,
340
+ ctrlclient .ObjectKeyFromObject (cluster ),
341
+ )
342
+ if err != nil {
343
+ return fmt .Errorf ("error creating remote cluster client: %w" , err )
344
+ }
345
+
346
+ objs := []ctrlclient.Object {
347
+ & appsv1.DaemonSet {
348
+ ObjectMeta : metav1.ObjectMeta {
349
+ Name : kubeProxyName ,
350
+ Namespace : kubeProxyNamespace ,
351
+ },
352
+ },
353
+ & corev1.ConfigMap {
354
+ ObjectMeta : metav1.ObjectMeta {
355
+ Name : kubeProxyName ,
356
+ Namespace : kubeProxyNamespace ,
357
+ },
358
+ },
359
+ }
360
+ for _ , obj := range objs {
361
+ if err := ctrlclient .IgnoreNotFound (remoteClient .Delete (ctx , obj )); err != nil {
362
+ return fmt .Errorf ("failed to delete %s/%s: %w" , obj .GetNamespace (), obj .GetName (), err )
363
+ }
364
+ }
365
+
366
+ return nil
367
+ }
0 commit comments