diff --git a/pkg/controllers/resources/endpoints/syncer.go b/pkg/controllers/resources/endpoints/syncer.go index 608a226411..3a61d248e7 100644 --- a/pkg/controllers/resources/endpoints/syncer.go +++ b/pkg/controllers/resources/endpoints/syncer.go @@ -3,6 +3,7 @@ package endpoints import ( "errors" "fmt" + "context" "github.com/loft-sh/vcluster/pkg/mappings" "github.com/loft-sh/vcluster/pkg/patcher" @@ -19,6 +20,8 @@ import ( "k8s.io/klog/v2" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/handler" ) func New(ctx *synccontext.RegisterContext) (syncertypes.Object, error) { @@ -56,6 +59,48 @@ func (s *endpointsSyncer) Syncer() syncertypes.Sync[client.Object] { return syncer.ToGenericSyncer(s) } +var _ syncertypes.ControllerModifier = &endpointsSyncer{} + +func (s *endpointsSyncer) ModifyController(ctx *synccontext.RegisterContext, bld *builder.Builder) (*builder.Builder, error) { + klog.Info("Starting to modify the controller to watch for Service changes and reconcile Endpoints") + + // Watch for changes to Services and reconcile Endpoints + bld = bld.Watches(&corev1.Service{}, handler.EnqueueRequestsFromMapFunc(func(_ context.Context, obj client.Object) []ctrl.Request { + service, ok := obj.(*corev1.Service) + if !ok || service == nil { + klog.Info("Received an object that is not a Service or is nil, skipping") + return []ctrl.Request{} + } + endpoint:= &corev1.Endpoints{} + err:= ctx.VirtualManager.GetClient().Get(ctx, types.NamespacedName{ + Namespace: service.Namespace, + Name: service.Name, + }, endpoint) + if err != nil { + if kerrors.IsNotFound(err) { + klog.Infof("Endpoints for Service %s/%s not found, skipping", service.Namespace, service.Name) + return []ctrl.Request{} + } + klog.Errorf("Error retrieving Endpoints for Service %s/%s: %v", service.Namespace, service.Name, err) + return []ctrl.Request{} + } + + klog.Infof("Enqueuing reconciliation request of Endpoint for Service: %s/%s", service.Namespace, service.Name) + + // Enqueue a request to reconcile the corresponding Endpoints + return []ctrl.Request{ + { + NamespacedName: types.NamespacedName{ + Namespace: service.Namespace, + Name: service.Name, + }, + }, + } + })) + + return bld, nil +} + func (s *endpointsSyncer) SyncToHost(ctx *synccontext.SyncContext, event *synccontext.SyncToHostEvent[*corev1.Endpoints]) (ctrl.Result, error) { if event.HostOld != nil { return patcher.DeleteVirtualObject(ctx, event.Virtual, event.HostOld, "host object was deleted")