Skip to content

Commit

Permalink
Sync endpoint updates for service mappings of headless services (#1481)
Browse files Browse the repository at this point in the history
* Add watch for updates to from.endpoints

* Add rbac for endpoints if mapServices.Host exists

* Add e2e tests
  • Loading branch information
neogopher authored Jan 30, 2024
1 parent acd9c71 commit 619f186
Show file tree
Hide file tree
Showing 8 changed files with 337 additions and 16 deletions.
2 changes: 1 addition & 1 deletion charts/eks/templates/rbac/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ rules:
{{- include "vcluster.generic.clusterRoleExtraRules" . | indent 2 }}
{{- if (not (empty (include "vcluster.serviceMapping.fromHost" . ))) }}
- apiGroups: [""]
resources: ["services"]
resources: ["services", "endpoints"]
verbs: ["get", "watch", "list"]
{{- end }}
{{- if .Values.multiNamespaceMode.enabled }}
Expand Down
2 changes: 1 addition & 1 deletion charts/k0s/templates/rbac/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ rules:
{{- include "vcluster.generic.clusterRoleExtraRules" . | indent 2 }}
{{- if (not (empty (include "vcluster.serviceMapping.fromHost" . ))) }}
- apiGroups: [""]
resources: ["services"]
resources: ["services", "endpoints"]
verbs: ["get", "watch", "list"]
{{- end }}
{{- if .Values.multiNamespaceMode.enabled }}
Expand Down
2 changes: 1 addition & 1 deletion charts/k3s/templates/rbac/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ rules:
{{- include "vcluster.generic.clusterRoleExtraRules" . | indent 2 }}
{{- if (not (empty (include "vcluster.serviceMapping.fromHost" . ))) }}
- apiGroups: [""]
resources: ["services"]
resources: ["services", "endpoints"]
verbs: ["get", "watch", "list"]
{{- end }}
{{- if .Values.multiNamespaceMode.enabled }}
Expand Down
2 changes: 1 addition & 1 deletion charts/k8s/templates/rbac/clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ rules:
{{- include "vcluster.generic.clusterRoleExtraRules" . | indent 2 }}
{{- if (not (empty (include "vcluster.serviceMapping.fromHost" . ))) }}
- apiGroups: [""]
resources: ["services"]
resources: ["services", "endpoints"]
verbs: ["get", "watch", "list"]
{{- end }}
{{- if .Values.multiNamespaceMode.enabled }}
Expand Down
46 changes: 38 additions & 8 deletions pkg/controllers/servicesync/servicesync.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,20 @@ func (e *ServiceSyncer) Register() error {

return []reconcile.Request{{NamespacedName: from}}
})).
WatchesRawSource(source.Kind(e.From.GetCache(), &corev1.Endpoints{}), handler.EnqueueRequestsFromMapFunc(func(_ context.Context, object client.Object) []reconcile.Request {
if object == nil {
return nil
}

_, ok := e.SyncServices[object.GetNamespace()+"/"+object.GetName()]
if !ok {
return nil
}

return []reconcile.Request{{
NamespacedName: types.NamespacedName{Namespace: object.GetNamespace(), Name: object.GetName()},
}}
})).
Complete(e)
}

Expand All @@ -81,7 +95,7 @@ func (e *ServiceSyncer) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.R
}

// make sure the to service is deleted
e.Log.Infof("Delete target service %s/%s because from service is missing", to.Name, to.Namespace)
e.Log.Infof("Delete target service %s/%s because from service is missing", to.Namespace, to.Name)
err = e.To.GetClient().Delete(ctx, &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: to.Name,
Expand Down Expand Up @@ -281,16 +295,32 @@ func (e *ServiceSyncer) syncServiceAndEndpoints(ctx context.Context, fromService
}

// check if update is needed
expectedSubsets := []corev1.EndpointSubset{
{
Addresses: []corev1.EndpointAddress{
{
IP: fromService.Spec.ClusterIP,
var expectedSubsets []corev1.EndpointSubset
if fromService.Spec.ClusterIP == corev1.ClusterIPNone {
// fetch the corresponding endpoint and assign address from there to here
fromEndpoint := &corev1.Endpoints{}
err = e.From.GetClient().Get(ctx, types.NamespacedName{
Name: fromService.GetName(),
Namespace: fromService.GetNamespace(),
}, fromEndpoint)
if err != nil {
return ctrl.Result{}, err
}

expectedSubsets = fromEndpoint.Subsets
} else {
expectedSubsets = []corev1.EndpointSubset{
{
Addresses: []corev1.EndpointAddress{
{
IP: fromService.Spec.ClusterIP,
},
},
Ports: convertPorts(toService.Spec.Ports),
},
Ports: convertPorts(toService.Spec.Ports),
},
}
}

if !apiequality.Semantic.DeepEqual(toEndpoints.Subsets, expectedSubsets) {
e.Log.Infof("Update target endpoints %s/%s because subsets are different", to.Namespace, to.Name)
toEndpoints.Subsets = expectedSubsets
Expand Down
4 changes: 4 additions & 0 deletions test/commonValues.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,13 @@ mapServices:
fromVirtual:
- from: test/test
to: test
- from: test/nginx
to: nginx
fromHost:
- from: test/test
to: default/test
- from: test/nginx
to: default/nginx

init:
helm:
Expand Down
Loading

0 comments on commit 619f186

Please sign in to comment.