Add header Host into mirror annotations (#8178)

This commit is contained in:
serge-r 2022-05-08 07:39:17 +07:00 committed by GitHub
parent ec1b01092e
commit 730b7408ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 2 deletions

View file

@ -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/modsecurity-snippet](#modsecurity)|string|
|[nginx.ingress.kubernetes.io/mirror-request-body](#mirror)|string| |[nginx.ingress.kubernetes.io/mirror-request-body](#mirror)|string|
|[nginx.ingress.kubernetes.io/mirror-target](#mirror)|string| |[nginx.ingress.kubernetes.io/mirror-target](#mirror)|string|
|[nginx.ingress.kubernetes.io/mirror-host](#mirror)|string|
### Canary ### 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" 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. **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. 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.

View file

@ -18,9 +18,9 @@ package mirror
import ( import (
"fmt" "fmt"
"strings"
networking "k8s.io/api/networking/v1" networking "k8s.io/api/networking/v1"
"k8s.io/ingress-nginx/internal/ingress/annotations/parser" "k8s.io/ingress-nginx/internal/ingress/annotations/parser"
"k8s.io/ingress-nginx/internal/ingress/resolver" "k8s.io/ingress-nginx/internal/ingress/resolver"
) )
@ -30,6 +30,7 @@ type Config struct {
Source string `json:"source"` Source string `json:"source"`
RequestBody string `json:"requestBody"` RequestBody string `json:"requestBody"`
Target string `json:"target"` Target string `json:"target"`
Host string `json:"host"`
} }
// Equal tests for equality between two Configuration types // Equal tests for equality between two Configuration types
@ -54,6 +55,10 @@ func (m1 *Config) Equal(m2 *Config) bool {
return false return false
} }
if m1.Host != m2.Host {
return false
}
return true return true
} }
@ -85,5 +90,18 @@ func (a mirror) Parse(ing *networking.Ingress) (interface{}, error) {
config.Source = "" 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 return config, nil
} }

View file

@ -30,6 +30,7 @@ import (
func TestParse(t *testing.T) { func TestParse(t *testing.T) {
requestBody := parser.GetAnnotationWithPrefix("mirror-request-body") requestBody := parser.GetAnnotationWithPrefix("mirror-request-body")
backendURL := parser.GetAnnotationWithPrefix("mirror-target") backendURL := parser.GetAnnotationWithPrefix("mirror-target")
host := parser.GetAnnotationWithPrefix("mirror-host")
ap := NewParser(&resolver.Mock{}) ap := NewParser(&resolver.Mock{})
if ap == nil { if ap == nil {
@ -45,11 +46,43 @@ func TestParse(t *testing.T) {
Source: ngxURI, Source: ngxURI,
RequestBody: "on", RequestBody: "on",
Target: "https://test.env.com/$request_uri", Target: "https://test.env.com/$request_uri",
Host: "test.env.com",
}}, }},
{map[string]string{requestBody: "off"}, &Config{ {map[string]string{requestBody: "off"}, &Config{
Source: "", Source: "",
RequestBody: "off", RequestBody: "off",
Target: "", 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",
}}, }},
} }

View file

@ -1667,10 +1667,11 @@ func buildMirrorLocations(locs []*ingress.Location) string {
mapped.Insert(loc.Mirror.Source) mapped.Insert(loc.Mirror.Source)
buffer.WriteString(fmt.Sprintf(`location = %v { buffer.WriteString(fmt.Sprintf(`location = %v {
internal; internal;
proxy_set_header Host %v;
proxy_pass %v; proxy_pass %v;
} }
`, loc.Mirror.Source, loc.Mirror.Target)) `, loc.Mirror.Source, loc.Mirror.Host, loc.Mirror.Target))
} }
return buffer.String() return buffer.String()