diff --git a/pkg/controllers/resources/ingresses/syncer.go b/pkg/controllers/resources/ingresses/syncer.go index 39b5f3576..455253c4d 100644 --- a/pkg/controllers/resources/ingresses/syncer.go +++ b/pkg/controllers/resources/ingresses/syncer.go @@ -4,10 +4,12 @@ import ( "github.com/loft-sh/vcluster/pkg/controllers/syncer" synccontext "github.com/loft-sh/vcluster/pkg/controllers/syncer/context" "github.com/loft-sh/vcluster/pkg/controllers/syncer/translator" + "github.com/loft-sh/vcluster/pkg/util/translate" networkingv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/api/equality" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" + "strings" ) func NewSyncer(ctx *synccontext.RegisterContext) (syncer.Object, error) { @@ -60,6 +62,8 @@ func (s *ingressSyncer) Sync(ctx *synccontext.SyncContext, pObj client.Object, v func SecretNamesFromIngress(ingress *networkingv1.Ingress) []string { secrets := []string{} + _, extraSecrets := translateIngressAnnotations(ingress.Annotations, ingress.Namespace) + secrets = append(secrets, extraSecrets...) for _, tls := range ingress.Spec.TLS { if tls.SecretName != "" { secrets = append(secrets, ingress.Namespace+"/"+tls.SecretName) @@ -67,3 +71,33 @@ func SecretNamesFromIngress(ingress *networkingv1.Ingress) []string { } return translator.UniqueSlice(secrets) } + +var TranslateAnnotations = map[string]bool{ + "nginx.ingress.kubernetes.io/auth-secret": true, + "nginx.ingress.kubernetes.io/auth-tls-secret": true, + "nginx.ingress.kubernetes.io/proxy-ssl-secret": true, +} + +func translateIngressAnnotations(annotations map[string]string, ingressNamespace string) (map[string]string, []string) { + foundSecrets := []string{} + newAnnotations := map[string]string{} + for k, v := range annotations { + if !TranslateAnnotations[k] { + newAnnotations[k] = v + continue + } + + splitted := strings.Split(annotations[k], "/") + if len(splitted) == 1 { + foundSecrets = append(foundSecrets, ingressNamespace+"/"+splitted[0]) + newAnnotations[k] = translate.PhysicalName(splitted[0], ingressNamespace) + } else if len(splitted) == 2 { + foundSecrets = append(foundSecrets, splitted[0]+"/"+splitted[1]) + newAnnotations[k] = translate.PhysicalName(splitted[1], splitted[0]) + } else { + newAnnotations[k] = v + } + } + + return newAnnotations, foundSecrets +} diff --git a/pkg/controllers/resources/ingresses/syncer_test.go b/pkg/controllers/resources/ingresses/syncer_test.go index d41ef9b2b..cd2389a80 100644 --- a/pkg/controllers/resources/ingresses/syncer_test.go +++ b/pkg/controllers/resources/ingresses/syncer_test.go @@ -284,6 +284,75 @@ func TestSync(t *testing.T) { assert.NilError(t, err) }, }, + { + Name: "Translate annotation", + InitialVirtualState: []runtime.Object{ + &networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: baseIngress.Name, + Namespace: baseIngress.Namespace, + Labels: baseIngress.Labels, + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/auth-secret": "my-secret", + }, + }, + }, + }, + InitialPhysicalState: []runtime.Object{ + &networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: createdIngress.Name, + Namespace: createdIngress.Namespace, + Labels: createdIngress.Labels, + }, + }, + }, + ExpectedVirtualState: map[schema.GroupVersionKind][]runtime.Object{ + networkingv1.SchemeGroupVersion.WithKind("Ingress"): { + &networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: baseIngress.Name, + Namespace: baseIngress.Namespace, + Labels: baseIngress.Labels, + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/auth-secret": "my-secret", + }, + }, + }, + }, + }, + ExpectedPhysicalState: map[schema.GroupVersionKind][]runtime.Object{ + networkingv1.SchemeGroupVersion.WithKind("Ingress"): { + &networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Name: createdIngress.Name, + Namespace: createdIngress.Namespace, + Labels: createdIngress.Labels, + Annotations: map[string]string{ + "nginx.ingress.kubernetes.io/auth-secret": translate.PhysicalName("my-secret", baseIngress.Namespace), + "vcluster.loft.sh/managed-annotations": "nginx.ingress.kubernetes.io/auth-secret", + "vcluster.loft.sh/object-name": baseIngress.Name, + "vcluster.loft.sh/object-namespace": baseIngress.Namespace, + }, + }, + }, + }, + }, + Sync: func(registerContext *synccontext.RegisterContext) { + syncCtx, syncer := generictesting.FakeStartSyncer(t, registerContext, NewSyncer) + + vIngress := &networkingv1.Ingress{} + err := syncCtx.VirtualClient.Get(syncCtx.Context, types.NamespacedName{Name: baseIngress.Name, Namespace: baseIngress.Namespace}, vIngress) + assert.NilError(t, err) + + pIngress := &networkingv1.Ingress{} + err = syncCtx.PhysicalClient.Get(syncCtx.Context, types.NamespacedName{Name: createdIngress.Name, Namespace: createdIngress.Namespace}, pIngress) + assert.NilError(t, err) + + _, err = syncer.(*ingressSyncer).Sync(syncCtx, pIngress, vIngress) + assert.NilError(t, err) + }, + }, }) } diff --git a/pkg/controllers/resources/ingresses/translate.go b/pkg/controllers/resources/ingresses/translate.go index 78a1ab864..9a1e3ac42 100644 --- a/pkg/controllers/resources/ingresses/translate.go +++ b/pkg/controllers/resources/ingresses/translate.go @@ -9,6 +9,7 @@ import ( func (s *ingressSyncer) translate(vIngress *networkingv1.Ingress) *networkingv1.Ingress { newIngress := s.TranslateMetadata(vIngress).(*networkingv1.Ingress) newIngress.Spec = *translateSpec(vIngress.Namespace, &vIngress.Spec) + newIngress.Annotations, _ = translateIngressAnnotations(newIngress.Annotations, vIngress.Namespace) return newIngress } @@ -21,8 +22,9 @@ func (s *ingressSyncer) translateUpdate(pObj, vObj *networkingv1.Ingress) *netwo updated.Spec = translatedSpec } - changed, translatedAnnotations, translatedLabels := s.TranslateMetadataUpdate(vObj, pObj) - if changed { + _, translatedAnnotations, translatedLabels := s.TranslateMetadataUpdate(vObj, pObj) + translatedAnnotations, _ = translateIngressAnnotations(translatedAnnotations, vObj.Namespace) + if !equality.Semantic.DeepEqual(translatedAnnotations, pObj.GetAnnotations()) || !equality.Semantic.DeepEqual(translatedLabels, pObj.GetLabels()) { updated = newIfNil(updated, pObj) updated.Annotations = translatedAnnotations updated.Labels = translatedLabels