From 7d90d9f68dddc1729e0d35a943353138aba16623 Mon Sep 17 00:00:00 2001 From: Phil Quinn Date: Mon, 25 Sep 2017 17:42:09 +0200 Subject: [PATCH] Allow a 'location-modifier' annotation for regex paths In nginx a modifier can be passed which decides how locations will be parsed, i.e. regex or no regex. This change allows a location modifier to be passed as an annotatione e.g. ingress.kubernetes.io/location-modifier: "~" If no location-modifier is passed but 'rewrite-target' is provided, then a default of "*~" is assumed. --- pkg/ingress/annotations/rewrite/main.go | 29 ++++++++++++++------ pkg/ingress/annotations/rewrite/main_test.go | 25 +++++++++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/pkg/ingress/annotations/rewrite/main.go b/pkg/ingress/annotations/rewrite/main.go index ce97f657d..c88a0d1c0 100644 --- a/pkg/ingress/annotations/rewrite/main.go +++ b/pkg/ingress/annotations/rewrite/main.go @@ -24,18 +24,22 @@ import ( ) const ( - rewriteTo = "ingress.kubernetes.io/rewrite-target" - addBaseURL = "ingress.kubernetes.io/add-base-url" - baseURLScheme = "ingress.kubernetes.io/base-url-scheme" - sslRedirect = "ingress.kubernetes.io/ssl-redirect" - forceSSLRedirect = "ingress.kubernetes.io/force-ssl-redirect" - appRoot = "ingress.kubernetes.io/app-root" + rewriteTo = "ingress.kubernetes.io/rewrite-target" + locationModifier = "ingress.kubernetes.io/location-modifier" + defaultRewriteLocationModifier = "~*" + addBaseURL = "ingress.kubernetes.io/add-base-url" + baseURLScheme = "ingress.kubernetes.io/base-url-scheme" + 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 type Redirect struct { // Target URI where the traffic must be redirected Target string `json:"target"` + // Location modifier + LocationModifier string `json:"locationModifier"` // AddBaseURL indicates if is required to add a base tag in the head // of the responses from the upstream servers AddBaseURL bool `json:"addBaseUrl"` @@ -92,6 +96,11 @@ func NewParser(br resolver.DefaultBackend) parser.IngressAnnotation { // rule used to rewrite the defined paths func (a rewrite) Parse(ing *extensions.Ingress) (interface{}, error) { rt, _ := parser.GetStringAnnotation(rewriteTo, ing) + locMod, _ := parser.GetStringAnnotation(locationModifier, ing) + + if rt != "" && locMod == "" { + locMod = defaultRewriteLocationModifier + } sslRe, err := parser.GetBoolAnnotation(sslRedirect, ing) if err != nil { sslRe = a.backendResolver.GetDefaultBackend().SSLRedirect @@ -103,12 +112,16 @@ func (a rewrite) Parse(ing *extensions.Ingress) (interface{}, error) { abu, _ := parser.GetBoolAnnotation(addBaseURL, ing) bus, _ := parser.GetStringAnnotation(baseURLScheme, ing) ar, _ := parser.GetStringAnnotation(appRoot, ing) - return &Redirect{ + + redirect := &Redirect{ Target: rt, + LocationModifier: locMod, AddBaseURL: abu, BaseURLScheme: bus, SSLRedirect: sslRe, ForceSSLRedirect: fSslRe, AppRoot: ar, - }, nil + } + + return redirect, nil } diff --git a/pkg/ingress/annotations/rewrite/main_test.go b/pkg/ingress/annotations/rewrite/main_test.go index 5da0cfeee..451d63a40 100644 --- a/pkg/ingress/annotations/rewrite/main_test.go +++ b/pkg/ingress/annotations/rewrite/main_test.go @@ -100,6 +100,31 @@ func TestRedirect(t *testing.T) { if redirect.Target != defRoute { t.Errorf("Expected %v as redirect but returned %s", defRoute, redirect.Target) } + + if redirect.LocationModifier != defaultRewriteLocationModifier { + t.Errorf("Expected %v as implicit location modifier but returned %s", defaultRewriteLocationModifier, redirect.LocationModifier) + } +} + +func TestRegex(t *testing.T) { + ing := buildIngress() + + data := map[string]string{} + modifier := "~" + data[locationModifier] = modifier + ing.SetAnnotations(data) + + i, err := NewParser(mockBackend{}).Parse(ing) + if err != nil { + t.Errorf("Unexpected error with ingress: %v", err) + } + redirect, ok := i.(*Redirect) + if !ok { + t.Errorf("expected a Redirect type") + } + if redirect.LocationModifier != modifier { + t.Errorf("Expected %v as location modifier but returned %s", modifier, redirect.LocationModifier) + } } func TestSSLRedirect(t *testing.T) {