@@ -18,15 +18,16 @@ package controller
1818
1919import (
2020 "context"
21- "fmt"
22- "time"
2321
2422 apierrors "k8s.io/apimachinery/pkg/api/errors"
2523 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2624 "k8s.io/apimachinery/pkg/runtime"
25+ "k8s.io/apimachinery/pkg/types"
2726 ctrl "sigs.k8s.io/controller-runtime"
2827 "sigs.k8s.io/controller-runtime/pkg/client"
28+ "sigs.k8s.io/controller-runtime/pkg/handler"
2929 "sigs.k8s.io/controller-runtime/pkg/log"
30+ "sigs.k8s.io/controller-runtime/pkg/reconcile"
3031
3132 netguardv1alpha1 "sgroups.io/netguard/api/v1alpha1"
3233 providerv1alpha1 "sgroups.io/netguard/deps/apis/sgroups-k8s-provider/v1alpha1"
@@ -85,33 +86,44 @@ func (r *AddressGroupBindingPolicyReconciler) Reconcile(ctx context.Context, req
8586 }
8687
8788 if err := r .Get (ctx , addressGroupKey , addressGroup ); err != nil {
88- // Set condition to indicate that the AddressGroup was not found
89- setAddressGroupBindingPolicyCondition (policy , "AddressGroupFound" , metav1 .ConditionFalse , "AddressGroupNotFound" ,
90- fmt .Sprintf ("AddressGroup %s not found in namespace %s" , addressGroupRef .GetName (), addressGroupNamespace ))
91- if err := UpdateStatusWithRetry (ctx , r .Client , policy , DefaultMaxRetries ); err != nil {
92- logger .Error (err , "Failed to update AddressGroupBindingPolicy status" )
89+ if apierrors .IsNotFound (err ) {
90+ logger .Info ("AddressGroup not found, deleting policy" ,
91+ "addressGroup" , addressGroupKey .String ())
92+ // AddressGroup deleted, delete the policy with retry
93+ if err := DeleteWithRetry (ctx , r .Client , policy , DefaultMaxRetries ); err != nil {
94+ logger .Error (err , "Failed to delete policy after AddressGroup deletion" )
95+ return ctrl.Result {}, err
96+ }
97+ logger .Info ("Policy deleted successfully after AddressGroup deletion" )
98+ return ctrl.Result {}, nil
9399 }
94- return ctrl.Result {RequeueAfter : time .Minute }, nil
100+ logger .Error (err , "Failed to get AddressGroup" )
101+ return ctrl.Result {}, err
95102 }
96103
97- // 2. Verify Service exists
104+ // Check if the Service exists
98105 serviceRef := policy .Spec .ServiceRef
99106 serviceNamespace := v1alpha1 .ResolveNamespace (serviceRef .GetNamespace (), policy .GetNamespace ())
100-
101- service := & netguardv1alpha1.Service {}
102107 serviceKey := client.ObjectKey {
103108 Name : serviceRef .GetName (),
104109 Namespace : serviceNamespace ,
105110 }
106111
112+ service := & netguardv1alpha1.Service {}
107113 if err := r .Get (ctx , serviceKey , service ); err != nil {
108- // Set condition to indicate that the Service was not found
109- setAddressGroupBindingPolicyCondition (policy , "ServiceFound" , metav1 .ConditionFalse , "ServiceNotFound" ,
110- fmt .Sprintf ("Service %s not found in namespace %s" , serviceRef .GetName (), serviceNamespace ))
111- if err := UpdateStatusWithRetry (ctx , r .Client , policy , DefaultMaxRetries ); err != nil {
112- logger .Error (err , "Failed to update AddressGroupBindingPolicy status" )
114+ if apierrors .IsNotFound (err ) {
115+ logger .Info ("Service not found, deleting policy" ,
116+ "service" , serviceKey .String ())
117+ // Service deleted, delete the policy with retry
118+ if err := DeleteWithRetry (ctx , r .Client , policy , DefaultMaxRetries ); err != nil {
119+ logger .Error (err , "Failed to delete policy after Service deletion" )
120+ return ctrl.Result {}, err
121+ }
122+ logger .Info ("Policy deleted successfully after Service deletion" )
123+ return ctrl.Result {}, nil
113124 }
114- return ctrl.Result {RequeueAfter : time .Minute }, nil
125+ logger .Error (err , "Failed to get Service" )
126+ return ctrl.Result {}, err
115127 }
116128
117129 // All resources exist, set Ready condition to true
@@ -152,10 +164,137 @@ func setAddressGroupBindingPolicyCondition(policy *netguardv1alpha1.AddressGroup
152164 policy .Status .Conditions = append (policy .Status .Conditions , condition )
153165}
154166
167+ // findPoliciesForService finds policies that reference a specific service
168+ func (r * AddressGroupBindingPolicyReconciler ) findPoliciesForService (ctx context.Context , obj client.Object ) []reconcile.Request {
169+ service , ok := obj .(* netguardv1alpha1.Service )
170+ if ! ok {
171+ return nil
172+ }
173+
174+ logger := log .FromContext (ctx )
175+ logger .Info ("Finding policies for Service" ,
176+ "service" , service .GetName (),
177+ "namespace" , service .GetNamespace ())
178+
179+ // Use index for faster lookup
180+ policyList := & netguardv1alpha1.AddressGroupBindingPolicyList {}
181+ if err := r .List (ctx , policyList , client.MatchingFields {"spec.serviceRef.name" : service .GetName ()}); err != nil {
182+ logger .Error (err , "Failed to list AddressGroupBindingPolicies by service index" )
183+ return nil
184+ }
185+
186+ var requests []reconcile.Request
187+
188+ // Filter policies that reference this service (additional namespace check)
189+ for _ , policy := range policyList .Items {
190+ // Resolve the namespace for the ServiceRef
191+ resolvedNamespace := v1alpha1 .ResolveNamespace (policy .Spec .ServiceRef .GetNamespace (), policy .GetNamespace ())
192+
193+ if resolvedNamespace == service .GetNamespace () {
194+ logger .Info ("Found policy that references this Service" ,
195+ "policy" , policy .GetName (),
196+ "policyNamespace" , policy .GetNamespace (),
197+ "serviceRef" , policy .Spec .ServiceRef .GetName (),
198+ "resolvedNamespace" , resolvedNamespace )
199+
200+ requests = append (requests , reconcile.Request {
201+ NamespacedName : types.NamespacedName {
202+ Name : policy .GetName (),
203+ Namespace : policy .GetNamespace (),
204+ },
205+ })
206+ }
207+ }
208+
209+ logger .Info ("Found policies for Service" ,
210+ "service" , service .GetName (),
211+ "policiesCount" , len (requests ))
212+
213+ return requests
214+ }
215+
216+ // findPoliciesForAddressGroup finds policies that reference a specific address group
217+ func (r * AddressGroupBindingPolicyReconciler ) findPoliciesForAddressGroup (ctx context.Context , obj client.Object ) []reconcile.Request {
218+ addressGroup , ok := obj .(* providerv1alpha1.AddressGroup )
219+ if ! ok {
220+ return nil
221+ }
222+
223+ logger := log .FromContext (ctx )
224+ logger .Info ("Finding policies for AddressGroup" ,
225+ "addressGroup" , addressGroup .GetName (),
226+ "namespace" , addressGroup .GetNamespace ())
227+
228+ // Use index for faster lookup
229+ policyList := & netguardv1alpha1.AddressGroupBindingPolicyList {}
230+ if err := r .List (ctx , policyList , client.MatchingFields {"spec.addressGroupRef.name" : addressGroup .GetName ()}); err != nil {
231+ logger .Error (err , "Failed to list AddressGroupBindingPolicies by addressGroup index" )
232+ return nil
233+ }
234+
235+ var requests []reconcile.Request
236+
237+ // Filter policies that reference this address group (additional namespace check)
238+ for _ , policy := range policyList .Items {
239+ // Resolve the namespace for the AddressGroupRef
240+ resolvedNamespace := v1alpha1 .ResolveNamespace (policy .Spec .AddressGroupRef .GetNamespace (), policy .GetNamespace ())
241+
242+ if resolvedNamespace == addressGroup .GetNamespace () {
243+ logger .Info ("Found policy that references this AddressGroup" ,
244+ "policy" , policy .GetName (),
245+ "policyNamespace" , policy .GetNamespace (),
246+ "addressGroupRef" , policy .Spec .AddressGroupRef .GetName (),
247+ "resolvedNamespace" , resolvedNamespace )
248+
249+ requests = append (requests , reconcile.Request {
250+ NamespacedName : types.NamespacedName {
251+ Name : policy .GetName (),
252+ Namespace : policy .GetNamespace (),
253+ },
254+ })
255+ }
256+ }
257+
258+ logger .Info ("Found policies for AddressGroup" ,
259+ "addressGroup" , addressGroup .GetName (),
260+ "policiesCount" , len (requests ))
261+
262+ return requests
263+ }
264+
155265// SetupWithManager sets up the controller with the Manager.
156266func (r * AddressGroupBindingPolicyReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
267+ // Add indexes for faster lookups
268+ if err := mgr .GetFieldIndexer ().IndexField (context .Background (),
269+ & netguardv1alpha1.AddressGroupBindingPolicy {}, "spec.serviceRef.name" ,
270+ func (obj client.Object ) []string {
271+ policy := obj .(* netguardv1alpha1.AddressGroupBindingPolicy )
272+ return []string {policy .Spec .ServiceRef .Name }
273+ }); err != nil {
274+ return err
275+ }
276+
277+ if err := mgr .GetFieldIndexer ().IndexField (context .Background (),
278+ & netguardv1alpha1.AddressGroupBindingPolicy {}, "spec.addressGroupRef.name" ,
279+ func (obj client.Object ) []string {
280+ policy := obj .(* netguardv1alpha1.AddressGroupBindingPolicy )
281+ return []string {policy .Spec .AddressGroupRef .Name }
282+ }); err != nil {
283+ return err
284+ }
285+
157286 return ctrl .NewControllerManagedBy (mgr ).
158287 For (& netguardv1alpha1.AddressGroupBindingPolicy {}).
288+ // Watch for changes to Service
289+ Watches (
290+ & netguardv1alpha1.Service {},
291+ handler .EnqueueRequestsFromMapFunc (r .findPoliciesForService ),
292+ ).
293+ // Watch for changes to AddressGroup
294+ Watches (
295+ & providerv1alpha1.AddressGroup {},
296+ handler .EnqueueRequestsFromMapFunc (r .findPoliciesForAddressGroup ),
297+ ).
159298 Named ("addressgroupbindingpolicy" ).
160299 Complete (r )
161300}
0 commit comments