@@ -5,6 +5,7 @@ package service
55
66import (
77 "context"
8+ "fmt"
89 "time"
910
1011 v1 "k8s.io/api/core/v1"
@@ -15,15 +16,20 @@ import (
1516 "k8s.io/client-go/rest"
1617 "k8s.io/client-go/tools/record"
1718 ctrl "sigs.k8s.io/controller-runtime"
19+ "sigs.k8s.io/controller-runtime/pkg/builder"
1820 "sigs.k8s.io/controller-runtime/pkg/client"
1921 "sigs.k8s.io/controller-runtime/pkg/controller"
22+ "sigs.k8s.io/controller-runtime/pkg/handler"
23+ "sigs.k8s.io/controller-runtime/pkg/manager"
2024 "sigs.k8s.io/controller-runtime/pkg/webhook"
2125
26+ "github.com/vmware-tanzu/nsx-operator/pkg/apis/vpc/v1alpha1"
2227 "github.com/vmware-tanzu/nsx-operator/pkg/controllers/common"
2328 "github.com/vmware-tanzu/nsx-operator/pkg/logger"
2429 "github.com/vmware-tanzu/nsx-operator/pkg/metrics"
2530 _ "github.com/vmware-tanzu/nsx-operator/pkg/nsx/ratelimiter"
2631 servicecommon "github.com/vmware-tanzu/nsx-operator/pkg/nsx/services/common"
32+ "github.com/vmware-tanzu/nsx-operator/pkg/nsx/services/dns"
2733)
2834
2935var (
@@ -38,6 +44,7 @@ type ServiceLbReconciler struct {
3844 Client client.Client
3945 Scheme * apimachineryruntime.Scheme
4046 Service * servicecommon.Service
47+ DNS dns.DNSRecordProvider
4148 Recorder record.EventRecorder
4249}
4350
@@ -53,6 +60,14 @@ func updateSuccess(r *ServiceLbReconciler, c context.Context, lbService *v1.Serv
5360 return err
5461}
5562
63+ func (r * ServiceLbReconciler ) deleteDNSForService (ctx context.Context , namespace , name string , op string ) error {
64+ if _ , err := r .DNS .DeleteRecordByOwnerNN (ctx , dns .ResourceKindService , namespace , name ); err != nil {
65+ log .Error (err , "Failed to delete DNS records for Service" , "Namespace" , namespace , "Name" , name , "Operation" , op )
66+ return fmt .Errorf ("deleting DNS records for %s: %w" , op , err )
67+ }
68+ return nil
69+ }
70+
5671func (r * ServiceLbReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (ctrl.Result , error ) {
5772 service := & v1.Service {}
5873 startTime := time .Now ()
@@ -63,25 +78,36 @@ func (r *ServiceLbReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
6378 if err := r .Client .Get (ctx , req .NamespacedName , service ); err != nil {
6479 if apierrors .IsNotFound (err ) {
6580 log .Info ("Not found LB service" , "req" , req .NamespacedName )
66- return ResultNormal , client .IgnoreNotFound (err )
81+ if err := r .deleteDNSForService (ctx , req .Namespace , req .Name , "deleted Service" ); err != nil {
82+ return common .ResultRequeueAfter10sec , err
83+ }
84+ return ResultNormal , nil
6785 }
6886 log .Error (err , "Failed to fetch LB service" , "req" , req .NamespacedName )
6987 return common .ResultRequeueAfter10sec , err
7088 }
7189
72- if service .Spec .Type == v1 .ServiceTypeLoadBalancer {
73- log .Info ("Reconciling LB service" , "LBService" , req .NamespacedName )
74- log .Debug ("Reconciling LB Service" , "name" , service .Name , "version" , service .ResourceVersion , "status" , service .Status )
75- metrics .CounterInc (r .Service .NSXConfig , metrics .ControllerSyncTotal , MetricResType )
76-
77- if service .ObjectMeta .DeletionTimestamp .IsZero () {
78- metrics .CounterInc (r .Service .NSXConfig , metrics .ControllerUpdateTotal , MetricResType )
79- err := updateSuccess (r , ctx , service )
80- if err != nil {
81- log .Error (err , "Failed to update LB service" , "Name" , service .Name , "Namespace" , service .Namespace )
82- return common .ResultRequeueAfter10sec , err
83- }
90+ if service .Spec .Type != v1 .ServiceTypeLoadBalancer || ! service .ObjectMeta .DeletionTimestamp .IsZero () {
91+ // Try to delete DNS records for Service when it is not a LoadBalancer or is marked for deletion
92+ if err := r .clearDNSAndConditionForService (ctx , req .NamespacedName , "non-LB or terminating Service" ); err != nil {
93+ return common .ResultRequeueAfter10sec , err
8494 }
95+ return ResultNormal , nil
96+ }
97+
98+ log .Info ("Reconciling LB service" , "LBService" , req .NamespacedName )
99+ log .Debug ("Reconciling LB Service" , "name" , service .Name , "version" , service .ResourceVersion , "status" , service .Status )
100+ metrics .CounterInc (r .Service .NSXConfig , metrics .ControllerSyncTotal , MetricResType )
101+
102+ if err := r .reconcileLoadBalancerServiceDNS (ctx , service ); err != nil {
103+ log .Error (err , "Failed to reconcile DNS for LoadBalancer Service" , "Name" , service .Name , "Namespace" , service .Namespace )
104+ return common .ResultRequeueAfter10sec , fmt .Errorf ("reconciling DNS: %w" , err )
105+ }
106+
107+ metrics .CounterInc (r .Service .NSXConfig , metrics .ControllerUpdateTotal , MetricResType )
108+ if err := updateSuccess (r , ctx , service ); err != nil {
109+ log .Error (err , "Failed to update LB service" , "Name" , service .Name , "Namespace" , service .Namespace )
110+ return common .ResultRequeueAfter10sec , fmt .Errorf ("updating LB service: %w" , err )
85111 }
86112
87113 return ResultNormal , nil
@@ -119,13 +145,18 @@ func (r *ServiceLbReconciler) setServiceLbStatus(ctx context.Context, lbService
119145}
120146
121147func (r * ServiceLbReconciler ) setupWithManager (mgr ctrl.Manager ) error {
122- return ctrl .NewControllerManagedBy (mgr ).
148+ b := ctrl .NewControllerManagedBy (mgr ).
123149 For (& v1.Service {}).
150+ Watches (
151+ & v1alpha1.NetworkInfo {},
152+ handler .EnqueueRequestsFromMapFunc (r .enqueueLBServiceRequestsFromNetworkInfo ),
153+ builder .WithPredicates (predicateNetworkInfoAllowedDNSDomainsChanged ()),
154+ ).
124155 WithOptions (
125156 controller.Options {
126157 MaxConcurrentReconciles : common .NumReconcile (),
127- }).
128- Complete (r )
158+ })
159+ return b . Complete (r )
129160}
130161
131162// Start setup manager
@@ -172,18 +203,36 @@ func (r *ServiceLbReconciler) StartController(mgr ctrl.Manager, _ webhook.Server
172203 log .Error (err , "Failed to create controller" , "controller" , "ServiceLb" )
173204 return err
174205 }
206+ err := mgr .Add (manager .RunnableFunc (func (ctx context.Context ) error {
207+ stop := make (chan bool )
208+ go func () {
209+ <- ctx .Done ()
210+ close (stop )
211+ }()
212+ common .GenericGarbageCollector (stop , servicecommon .GCInterval , r .CollectGarbage )
213+ return nil
214+ }))
215+ if err != nil {
216+ log .Error (err , "Failed to add LB GC to manager" )
217+ return err
218+ }
175219 return nil
176220}
177221
178222func (r * ServiceLbReconciler ) CollectGarbage (ctx context.Context ) error {
179- return nil
223+ return r . collectDNSGarbage ( ctx )
180224}
181225
182- func NewServiceLbReconciler (mgr ctrl.Manager , commonService servicecommon.Service ) * ServiceLbReconciler {
226+ func NewServiceLbReconciler (mgr ctrl.Manager , commonService servicecommon.Service , dnsRecordService * dns. DNSRecordService ) * ServiceLbReconciler {
183227 if isServiceLbStatusIpModeSupported (mgr .GetConfig ()) {
228+ var dnsProv dns.DNSRecordProvider
229+ if dnsRecordService != nil {
230+ dnsProv = dnsRecordService
231+ }
184232 serviceLbReconciler := & ServiceLbReconciler {
185233 Client : mgr .GetClient (),
186234 Scheme : mgr .GetScheme (),
235+ DNS : dnsProv ,
187236 Recorder : mgr .GetEventRecorderFor ("serviceLb-controller" ), //nolint:staticcheck // record.EventRecorder; StatusUpdater not on events.EventRecorder yet
188237 }
189238 serviceLbReconciler .Service = & commonService
0 commit comments