@@ -412,3 +412,85 @@ var _ = Describe("ImpNetwork Controller: CiliumConfigMissing", func() {
412412 }, 200 * time .Millisecond , 50 * time .Millisecond ).ShouldNot (ContainSubstring (EventReasonCiliumConfigMissing ))
413413 })
414414})
415+
416+ var _ = Describe ("ImpNetwork Controller: group CIDR allocation" , func () {
417+ ctx := context .Background ()
418+
419+ It ("populates status.groupCIDRs from spec.groups on reconcile" , func () {
420+ net := & impdevv1alpha1.ImpNetwork {
421+ ObjectMeta : metav1.ObjectMeta {Name : "group-net-1" , Namespace : "default" },
422+ Spec : impdevv1alpha1.ImpNetworkSpec {
423+ Subnet : "10.55.0.0/24" ,
424+ Groups : []impdevv1alpha1.NetworkGroupSpec {
425+ {Name : "workers" , ExpectedSize : 14 },
426+ {Name : "controllers" , ExpectedSize : 4 },
427+ },
428+ },
429+ }
430+ Expect (k8sClient .Create (ctx , net )).To (Succeed ())
431+ DeferCleanup (func () { k8sClient .Delete (ctx , net ) }) //nolint:errcheck
432+
433+ r , _ := newNetworkReconciler (unknownStore ())
434+ // First reconcile: adds finalizer.
435+ _ , err := r .Reconcile (ctx , reconcile.Request {
436+ NamespacedName : types.NamespacedName {Name : "group-net-1" , Namespace : "default" },
437+ })
438+ Expect (err ).NotTo (HaveOccurred ())
439+ // Second reconcile: runs sync, populates groupCIDRs.
440+ _ , err = r .Reconcile (ctx , reconcile.Request {
441+ NamespacedName : types.NamespacedName {Name : "group-net-1" , Namespace : "default" },
442+ })
443+ Expect (err ).NotTo (HaveOccurred ())
444+
445+ updated := & impdevv1alpha1.ImpNetwork {}
446+ Expect (k8sClient .Get (ctx , types.NamespacedName {Name : "group-net-1" , Namespace : "default" }, updated )).To (Succeed ())
447+ Expect (updated .Status .GroupCIDRs ).To (HaveLen (2 ))
448+
449+ byName := make (map [string ]string )
450+ for _ , gc := range updated .Status .GroupCIDRs {
451+ byName [gc .Name ] = gc .CIDR
452+ }
453+ // "controllers" sorted first: /29 at 10.55.0.0
454+ Expect (byName ["controllers" ]).To (Equal ("10.55.0.0/29" ))
455+ // "workers": /28 aligned after /29 block → 10.55.0.16
456+ Expect (byName ["workers" ]).To (Equal ("10.55.0.16/28" ))
457+ })
458+
459+ It ("clears status.groupCIDRs when spec.groups is removed" , func () {
460+ net := & impdevv1alpha1.ImpNetwork {
461+ ObjectMeta : metav1.ObjectMeta {Name : "group-net-2" , Namespace : "default" },
462+ Spec : impdevv1alpha1.ImpNetworkSpec {
463+ Subnet : "10.56.0.0/24" ,
464+ Groups : []impdevv1alpha1.NetworkGroupSpec {
465+ {Name : "a" , ExpectedSize : 4 },
466+ },
467+ },
468+ }
469+ Expect (k8sClient .Create (ctx , net )).To (Succeed ())
470+ DeferCleanup (func () { k8sClient .Delete (ctx , net ) }) //nolint:errcheck
471+
472+ r , _ := newNetworkReconciler (unknownStore ())
473+ for i := 0 ; i < 2 ; i ++ {
474+ _ , err := r .Reconcile (ctx , reconcile.Request {
475+ NamespacedName : types.NamespacedName {Name : "group-net-2" , Namespace : "default" },
476+ })
477+ Expect (err ).NotTo (HaveOccurred ())
478+ }
479+
480+ // Remove groups from spec.
481+ updated := & impdevv1alpha1.ImpNetwork {}
482+ Expect (k8sClient .Get (ctx , types.NamespacedName {Name : "group-net-2" , Namespace : "default" }, updated )).To (Succeed ())
483+ updated .Spec .Groups = nil
484+ Expect (k8sClient .Update (ctx , updated )).To (Succeed ())
485+
486+ // Reconcile again.
487+ _ , err := r .Reconcile (ctx , reconcile.Request {
488+ NamespacedName : types.NamespacedName {Name : "group-net-2" , Namespace : "default" },
489+ })
490+ Expect (err ).NotTo (HaveOccurred ())
491+
492+ final := & impdevv1alpha1.ImpNetwork {}
493+ Expect (k8sClient .Get (ctx , types.NamespacedName {Name : "group-net-2" , Namespace : "default" }, final )).To (Succeed ())
494+ Expect (final .Status .GroupCIDRs ).To (BeEmpty ())
495+ })
496+ })
0 commit comments