Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions internal/controller/decoredirect_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,14 @@ func (r *DecoRedirectReconciler) reconcileIngress(ctx context.Context, rd *decos
code = *rd.Spec.RedirectCode
}

// server-snippet injects a raw nginx return directive that preserves the full request path and
// query string via $request_uri. The permanent-redirect annotation cannot be used here because
// the nginx admission webhook rejects values containing nginx variables (e.g. $request_uri).
// configuration-snippet injects the return directive into the location / block so the path and
// query string are preserved via $request_uri. server-snippet cannot be used because it runs at
// the server block level (HTTP + HTTPS) before location matching, which intercepts Let's Encrypt
// HTTP-01 ACME challenge requests (/.well-known/acme-challenge/) and breaks cert issuance.
// With configuration-snippet the cert-manager ACME solver location (more specific path) wins.
_, err := controllerutil.CreateOrUpdate(ctx, r.Client, ingress, func() error {
ingress.Annotations = map[string]string{
"nginx.ingress.kubernetes.io/server-snippet": fmt.Sprintf("return %d %s$request_uri;", code, rd.Spec.To),
"nginx.ingress.kubernetes.io/configuration-snippet": fmt.Sprintf("return %d %s$request_uri;", code, rd.Spec.To),
}
ingress.Spec = networkingv1.IngressSpec{
IngressClassName: &r.IngressClass,
Expand Down
12 changes: 6 additions & 6 deletions internal/controller/decoredirect_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ var _ = Describe("DecoRedirect Controller", func() {
Expect(cert.Spec.SecretName).To(Equal("tls-client-com"))
})

It("should create an Ingress with server-snippet redirect preserving path", func() {
It("should create an Ingress with configuration-snippet redirect preserving path", func() {
_, err := newReconciler().Reconcile(ctx, reconcile.Request{NamespacedName: nn})
Expect(err).NotTo(HaveOccurred())

Expand All @@ -80,7 +80,7 @@ var _ = Describe("DecoRedirect Controller", func() {
Name: "redirect-client-com", Namespace: rdNS,
}, ing)).To(Succeed())
Expect(*ing.Spec.IngressClassName).To(Equal("nginx"))
Expect(ing.Annotations["nginx.ingress.kubernetes.io/server-snippet"]).To(Equal("return 307 " + toDomain + "$request_uri;"))
Expect(ing.Annotations["nginx.ingress.kubernetes.io/configuration-snippet"]).To(Equal("return 307 " + toDomain + "$request_uri;"))
Expect(ing.Spec.TLS[0].Hosts).To(ContainElement(fromDomain))
Expect(ing.Spec.TLS[0].SecretName).To(Equal("tls-client-com"))
Expect(ing.Spec.Rules[0].Host).To(Equal(fromDomain))
Expand Down Expand Up @@ -149,18 +149,18 @@ var _ = Describe("DecoRedirect Controller", func() {
Expect(count).To(Equal(1))
})

It("should use return 307 in server-snippet by default", func() {
It("should use return 307 in configuration-snippet by default", func() {
_, err := newReconciler().Reconcile(ctx, reconcile.Request{NamespacedName: nn})
Expect(err).NotTo(HaveOccurred())

ing := &networkingv1.Ingress{}
Expect(k8sClient.Get(ctx, types.NamespacedName{
Name: "redirect-client-com", Namespace: rdNS,
}, ing)).To(Succeed())
Expect(ing.Annotations["nginx.ingress.kubernetes.io/server-snippet"]).To(ContainSubstring("return 307 "))
Expect(ing.Annotations["nginx.ingress.kubernetes.io/configuration-snippet"]).To(ContainSubstring("return 307 "))
})

It("should use return 301 in server-snippet when redirectCode is 301", func() {
It("should use return 301 in configuration-snippet when redirectCode is 301", func() {
code := 301
rd301 := &decositesv1alpha1.DecoRedirect{
ObjectMeta: metav1.ObjectMeta{Name: "test-redirect-301", Namespace: rdNS},
Expand All @@ -181,7 +181,7 @@ var _ = Describe("DecoRedirect Controller", func() {
Expect(k8sClient.Get(ctx, types.NamespacedName{
Name: "redirect-redirect301-com", Namespace: rdNS,
}, ing)).To(Succeed())
Expect(ing.Annotations["nginx.ingress.kubernetes.io/server-snippet"]).To(ContainSubstring("return 301 "))
Expect(ing.Annotations["nginx.ingress.kubernetes.io/configuration-snippet"]).To(ContainSubstring("return 301 "))
})
})

Expand Down
Loading