From 04af55af3c6fd104caa36cad084a421b2b4bee94 Mon Sep 17 00:00:00 2001 From: Ricardo Pchevuzinske Katz Date: Sun, 12 Mar 2017 19:06:10 -0300 Subject: [PATCH] Adds support for root context redirection --- controllers/nginx/configuration.md | 3 +++ .../nginx/rootfs/etc/nginx/template/nginx.tmpl | 6 +++++- core/pkg/ingress/annotations/rewrite/main.go | 6 +++++- .../ingress/annotations/rewrite/main_test.go | 17 +++++++++++++++++ core/pkg/ingress/defaults/main.go | 2 ++ 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/controllers/nginx/configuration.md b/controllers/nginx/configuration.md index e8ffd81ff..b637f196e 100644 --- a/controllers/nginx/configuration.md +++ b/controllers/nginx/configuration.md @@ -40,6 +40,7 @@ The following annotations are supported: |Name |type| |---------------------------|------| |[ingress.kubernetes.io/add-base-url](#rewrite)|true or false| +|[ingress.kubernetes.io/app-root](#rewrite)|string| |[ingress.kubernetes.io/affinity](#session-affinity)|true or false| |[ingress.kubernetes.io/auth-realm](#authentication)|string| |[ingress.kubernetes.io/auth-secret](#authentication)|string| @@ -174,6 +175,8 @@ Set the annotation `ingress.kubernetes.io/rewrite-target` to the path expected b If the application contains relative links it is possible to add an additional annotation `ingress.kubernetes.io/add-base-url` that will prepend a [`base` tag](https://developer.mozilla.org/en/docs/Web/HTML/Element/base) in the header of the returned HTML from the backend. +If the Application Root is exposed in a different path and needs to be redirected, the annotation `ingress.kubernetes.io/app-root` might be used. + Please check the [rewrite](examples/rewrite/README.md) example. diff --git a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl index 9813bcd24..652ddcd4e 100644 --- a/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl +++ b/controllers/nginx/rootfs/etc/nginx/template/nginx.tmpl @@ -236,7 +236,11 @@ http { ssl_verify_client on; ssl_verify_depth {{ $location.CertificateAuth.ValidationDepth }}; {{ end }} - + {{ if not (empty $location.Redirect.AppRoot)}} + location = / { + return 302 ${{ location.Redirect.AppRoot }}; + } + {{ end }} {{ if not (empty $authPath) }} location = {{ $authPath }} { internal; diff --git a/core/pkg/ingress/annotations/rewrite/main.go b/core/pkg/ingress/annotations/rewrite/main.go index 999ef7844..c48573a74 100644 --- a/core/pkg/ingress/annotations/rewrite/main.go +++ b/core/pkg/ingress/annotations/rewrite/main.go @@ -28,6 +28,7 @@ const ( addBaseURL = "ingress.kubernetes.io/add-base-url" sslRedirect = "ingress.kubernetes.io/ssl-redirect" forceSSLRedirect = "ingress.kubernetes.io/force-ssl-redirect" + appRoot = "ingress.kubernetes.io/app-root" ) // Redirect describes the per location redirect config @@ -40,7 +41,8 @@ type Redirect struct { // SSLRedirect indicates if the location section is accessible SSL only SSLRedirect bool `json:"sslRedirect"` // ForceSSLRedirect indicates if the location section is accessible SSL only - ForceSSLRedirect bool `json:"forceSSLRedirect"` + ForceSSLRedirect bool `json:"forceSSLRedirect"` + AppRoot string `json:"appRoot"` } type rewrite struct { @@ -65,10 +67,12 @@ func (a rewrite) Parse(ing *extensions.Ingress) (interface{}, error) { fSslRe = a.backendResolver.GetDefaultBackend().ForceSSLRedirect } abu, _ := parser.GetBoolAnnotation(addBaseURL, ing) + ar, _ := parser.GetStringAnnotation(appRoot, ing) return &Redirect{ Target: rt, AddBaseURL: abu, SSLRedirect: sslRe, ForceSSLRedirect: fSslRe, + AppRoot: ar, }, nil } diff --git a/core/pkg/ingress/annotations/rewrite/main_test.go b/core/pkg/ingress/annotations/rewrite/main_test.go index 75daf01bc..2a3252184 100644 --- a/core/pkg/ingress/annotations/rewrite/main_test.go +++ b/core/pkg/ingress/annotations/rewrite/main_test.go @@ -158,3 +158,20 @@ func TestForceSSLRedirect(t *testing.T) { t.Errorf("Expected true but returned false") } } +func TestAppRoot(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + data[appRoot] = "/app1" + ing.SetAnnotations(data) + + i, _ := NewParser(mockBackend{true}).Parse(ing) + redirect, ok := i.(*Redirect) + if !ok { + t.Errorf("expected a App Context") + } + if redirect.AppRoot != "/app1" { + t.Errorf("Unexpected value got in AppRoot") + } + +} diff --git a/core/pkg/ingress/defaults/main.go b/core/pkg/ingress/defaults/main.go index d8420da04..92f5a72a2 100644 --- a/core/pkg/ingress/defaults/main.go +++ b/core/pkg/ingress/defaults/main.go @@ -6,6 +6,8 @@ import "net" // The reason of this requirements is the annotations are generic. If some implementation do not supports // one or more annotations it just can provides defaults type Backend struct { + // AppRoot contains the AppRoot for apps that doesn't exposes its content in the 'root' context + AppRoot string `json:"app-root"` // enables which HTTP codes should be passed for processing with the error_page directive // http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors