From 730b7408ca5d247a31e50aaf479f081dd66949b9 Mon Sep 17 00:00:00 2001 From: serge-r Date: Sun, 8 May 2022 07:39:17 +0700 Subject: [PATCH] Add header Host into mirror annotations (#8178) --- .../nginx-configuration/annotations.md | 8 +++++ internal/ingress/annotations/mirror/main.go | 20 ++++++++++- .../ingress/annotations/mirror/main_test.go | 33 +++++++++++++++++++ .../ingress/controller/template/template.go | 3 +- 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/docs/user-guide/nginx-configuration/annotations.md b/docs/user-guide/nginx-configuration/annotations.md index 3a70ba14c..2a019ea27 100755 --- a/docs/user-guide/nginx-configuration/annotations.md +++ b/docs/user-guide/nginx-configuration/annotations.md @@ -131,6 +131,7 @@ You can add these Kubernetes annotations to specific Ingress objects to customiz |[nginx.ingress.kubernetes.io/modsecurity-snippet](#modsecurity)|string| |[nginx.ingress.kubernetes.io/mirror-request-body](#mirror)|string| |[nginx.ingress.kubernetes.io/mirror-target](#mirror)|string| +|[nginx.ingress.kubernetes.io/mirror-host](#mirror)|string| ### Canary @@ -941,6 +942,13 @@ By default the request-body is sent to the mirror backend, but can be turned off nginx.ingress.kubernetes.io/mirror-request-body: "off" ``` +Also by default header Host for mirrored requests will be set the same as a host part of uri in the "mirror-target" annotation. You can override it by "mirror-host" annotation: + +```yaml +nginx.ingress.kubernetes.io/mirror-target: https://1.2.3.4/$request_uri +nginx.ingress.kubernetes.io/mirror-host: "test.env.com" +``` + **Note:** The mirror directive will be applied to all paths within the ingress resource. The request sent to the mirror is linked to the original request. If you have a slow mirror backend, then the original request will throttle. diff --git a/internal/ingress/annotations/mirror/main.go b/internal/ingress/annotations/mirror/main.go index e11d4b4fb..cd54a9826 100644 --- a/internal/ingress/annotations/mirror/main.go +++ b/internal/ingress/annotations/mirror/main.go @@ -18,9 +18,9 @@ package mirror import ( "fmt" + "strings" networking "k8s.io/api/networking/v1" - "k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/resolver" ) @@ -30,6 +30,7 @@ type Config struct { Source string `json:"source"` RequestBody string `json:"requestBody"` Target string `json:"target"` + Host string `json:"host"` } // Equal tests for equality between two Configuration types @@ -54,6 +55,10 @@ func (m1 *Config) Equal(m2 *Config) bool { return false } + if m1.Host != m2.Host { + return false + } + return true } @@ -85,5 +90,18 @@ func (a mirror) Parse(ing *networking.Ingress) (interface{}, error) { config.Source = "" } + config.Host, err = parser.GetStringAnnotation("mirror-host", ing) + if err != nil { + if config.Target != "" { + url, err := parser.StringToURL(config.Target) + if err != nil { + config.Host = "" + } else { + hostname := strings.Split(url.Hostname(), "$") + config.Host = hostname[0] + } + } + } + return config, nil } diff --git a/internal/ingress/annotations/mirror/main_test.go b/internal/ingress/annotations/mirror/main_test.go index af7ed1b1f..f744ab552 100644 --- a/internal/ingress/annotations/mirror/main_test.go +++ b/internal/ingress/annotations/mirror/main_test.go @@ -30,6 +30,7 @@ import ( func TestParse(t *testing.T) { requestBody := parser.GetAnnotationWithPrefix("mirror-request-body") backendURL := parser.GetAnnotationWithPrefix("mirror-target") + host := parser.GetAnnotationWithPrefix("mirror-host") ap := NewParser(&resolver.Mock{}) if ap == nil { @@ -45,11 +46,43 @@ func TestParse(t *testing.T) { Source: ngxURI, RequestBody: "on", Target: "https://test.env.com/$request_uri", + Host: "test.env.com", }}, {map[string]string{requestBody: "off"}, &Config{ Source: "", RequestBody: "off", Target: "", + Host: "", + }}, + {map[string]string{host: "test.env.com", backendURL: "http://some.test.env.com/$someparam"}, &Config{ + Source: ngxURI, + RequestBody: "on", + Target: "http://some.test.env.com/$someparam", + Host: "test.env.com", + }}, + {map[string]string{backendURL: "IamNotAURL"}, &Config{ + Source: ngxURI, + RequestBody: "on", + Target: "IamNotAURL", + Host: "", + }}, + {map[string]string{backendURL: "http://some.test.env.com:2121/$someparam=1&$someotherparam=2"}, &Config{ + Source: ngxURI, + RequestBody: "on", + Target: "http://some.test.env.com:2121/$someparam=1&$someotherparam=2", + Host: "some.test.env.com", + }}, + {map[string]string{backendURL: "http://some.test.env.com", host: "someInvalidParm.%^&*()_=!@#'\""}, &Config{ + Source: ngxURI, + RequestBody: "on", + Target: "http://some.test.env.com", + Host: "someInvalidParm.%^&*()_=!@#'\"", + }}, + {map[string]string{backendURL: "http://some.test.env.com", host: "_sbrubles-i\"@xpto:12345"}, &Config{ + Source: ngxURI, + RequestBody: "on", + Target: "http://some.test.env.com", + Host: "_sbrubles-i\"@xpto:12345", }}, } diff --git a/internal/ingress/controller/template/template.go b/internal/ingress/controller/template/template.go index 73bc344c0..a331c196a 100644 --- a/internal/ingress/controller/template/template.go +++ b/internal/ingress/controller/template/template.go @@ -1667,10 +1667,11 @@ func buildMirrorLocations(locs []*ingress.Location) string { mapped.Insert(loc.Mirror.Source) buffer.WriteString(fmt.Sprintf(`location = %v { internal; +proxy_set_header Host %v; proxy_pass %v; } -`, loc.Mirror.Source, loc.Mirror.Target)) +`, loc.Mirror.Source, loc.Mirror.Host, loc.Mirror.Target)) } return buffer.String()