auto backend protocol for HTTP/HTTPS (#6985)
* add auto backend protocol for HTTP/HTTPS * e2e test for AUTO_HTTP backend protocol * unit test for AUTO_HTTP backend protocol Co-authored-by: Luca Del Monte <luca.delmonte5@gmail.com>
This commit is contained in:
parent
b1f9f83810
commit
a327a809d9
4 changed files with 96 additions and 16 deletions
|
@ -31,7 +31,7 @@ import (
|
||||||
const HTTP = "HTTP"
|
const HTTP = "HTTP"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
validProtocols = regexp.MustCompile(`^(HTTP|HTTPS|AJP|GRPC|GRPCS|FCGI)$`)
|
validProtocols = regexp.MustCompile(`^(AUTO_HTTP|HTTP|HTTPS|AJP|GRPC|GRPCS|FCGI)$`)
|
||||||
)
|
)
|
||||||
|
|
||||||
type backendProtocol struct {
|
type backendProtocol struct {
|
||||||
|
|
|
@ -617,6 +617,8 @@ func buildProxyPass(host string, b interface{}, loc interface{}) string {
|
||||||
proxyPass := "proxy_pass"
|
proxyPass := "proxy_pass"
|
||||||
|
|
||||||
switch location.BackendProtocol {
|
switch location.BackendProtocol {
|
||||||
|
case "AUTO_HTTP":
|
||||||
|
proto = "$scheme://"
|
||||||
case "HTTPS":
|
case "HTTPS":
|
||||||
proto = "https://"
|
proto = "https://"
|
||||||
case "GRPC":
|
case "GRPC":
|
||||||
|
|
|
@ -59,20 +59,22 @@ func init() {
|
||||||
var (
|
var (
|
||||||
// TODO: add tests for SSLPassthrough
|
// TODO: add tests for SSLPassthrough
|
||||||
tmplFuncTestcases = map[string]struct {
|
tmplFuncTestcases = map[string]struct {
|
||||||
Path string
|
Path string
|
||||||
Target string
|
Target string
|
||||||
Location string
|
Location string
|
||||||
ProxyPass string
|
ProxyPass string
|
||||||
Sticky bool
|
AutoHttpProxyPass string
|
||||||
XForwardedPrefix string
|
Sticky bool
|
||||||
SecureBackend bool
|
XForwardedPrefix string
|
||||||
enforceRegex bool
|
SecureBackend bool
|
||||||
|
enforceRegex bool
|
||||||
}{
|
}{
|
||||||
"when secure backend enabled": {
|
"when secure backend enabled": {
|
||||||
"/",
|
"/",
|
||||||
"/",
|
"/",
|
||||||
"/",
|
"/",
|
||||||
"proxy_pass https://upstream_balancer;",
|
"proxy_pass https://upstream_balancer;",
|
||||||
|
"proxy_pass https://upstream_balancer;",
|
||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
true,
|
true,
|
||||||
|
@ -83,6 +85,7 @@ var (
|
||||||
"/",
|
"/",
|
||||||
"/",
|
"/",
|
||||||
"proxy_pass https://upstream_balancer;",
|
"proxy_pass https://upstream_balancer;",
|
||||||
|
"proxy_pass https://upstream_balancer;",
|
||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
true,
|
true,
|
||||||
|
@ -93,6 +96,7 @@ var (
|
||||||
"/",
|
"/",
|
||||||
"/",
|
"/",
|
||||||
"proxy_pass https://upstream_balancer;",
|
"proxy_pass https://upstream_balancer;",
|
||||||
|
"proxy_pass https://upstream_balancer;",
|
||||||
true,
|
true,
|
||||||
"",
|
"",
|
||||||
true,
|
true,
|
||||||
|
@ -103,6 +107,7 @@ var (
|
||||||
"/",
|
"/",
|
||||||
"/",
|
"/",
|
||||||
"proxy_pass http://upstream_balancer;",
|
"proxy_pass http://upstream_balancer;",
|
||||||
|
"proxy_pass $scheme://upstream_balancer;",
|
||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
|
@ -113,6 +118,7 @@ var (
|
||||||
"/",
|
"/",
|
||||||
"/",
|
"/",
|
||||||
"proxy_pass http://upstream_balancer;",
|
"proxy_pass http://upstream_balancer;",
|
||||||
|
"proxy_pass $scheme://upstream_balancer;",
|
||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
|
@ -125,6 +131,9 @@ var (
|
||||||
`
|
`
|
||||||
rewrite "(?i)/" /jenkins break;
|
rewrite "(?i)/" /jenkins break;
|
||||||
proxy_pass http://upstream_balancer;`,
|
proxy_pass http://upstream_balancer;`,
|
||||||
|
`
|
||||||
|
rewrite "(?i)/" /jenkins break;
|
||||||
|
proxy_pass $scheme://upstream_balancer;`,
|
||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
|
@ -137,6 +146,9 @@ proxy_pass http://upstream_balancer;`,
|
||||||
`
|
`
|
||||||
rewrite "(?i)/" /something break;
|
rewrite "(?i)/" /something break;
|
||||||
proxy_pass http://upstream_balancer;`,
|
proxy_pass http://upstream_balancer;`,
|
||||||
|
`
|
||||||
|
rewrite "(?i)/" /something break;
|
||||||
|
proxy_pass $scheme://upstream_balancer;`,
|
||||||
true,
|
true,
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
|
@ -149,6 +161,9 @@ proxy_pass http://upstream_balancer;`,
|
||||||
`
|
`
|
||||||
rewrite "(?i)/" /something break;
|
rewrite "(?i)/" /something break;
|
||||||
proxy_pass http://upstream_balancer;`,
|
proxy_pass http://upstream_balancer;`,
|
||||||
|
`
|
||||||
|
rewrite "(?i)/" /something break;
|
||||||
|
proxy_pass $scheme://upstream_balancer;`,
|
||||||
true,
|
true,
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
|
@ -162,6 +177,10 @@ proxy_pass http://upstream_balancer;`,
|
||||||
rewrite "(?i)/there" /something break;
|
rewrite "(?i)/there" /something break;
|
||||||
proxy_set_header X-Forwarded-Prefix "/there";
|
proxy_set_header X-Forwarded-Prefix "/there";
|
||||||
proxy_pass http://upstream_balancer;`,
|
proxy_pass http://upstream_balancer;`,
|
||||||
|
`
|
||||||
|
rewrite "(?i)/there" /something break;
|
||||||
|
proxy_set_header X-Forwarded-Prefix "/there";
|
||||||
|
proxy_pass $scheme://upstream_balancer;`,
|
||||||
true,
|
true,
|
||||||
"/there",
|
"/there",
|
||||||
false,
|
false,
|
||||||
|
@ -172,6 +191,7 @@ proxy_pass http://upstream_balancer;`,
|
||||||
"/something",
|
"/something",
|
||||||
`~* "^/something"`,
|
`~* "^/something"`,
|
||||||
"proxy_pass http://upstream_balancer;",
|
"proxy_pass http://upstream_balancer;",
|
||||||
|
"proxy_pass $scheme://upstream_balancer;",
|
||||||
false,
|
false,
|
||||||
"",
|
"",
|
||||||
false,
|
false,
|
||||||
|
@ -344,6 +364,48 @@ func TestBuildProxyPass(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuildProxyPassAutoHttp(t *testing.T) {
|
||||||
|
defaultBackend := "upstream-name"
|
||||||
|
defaultHost := "example.com"
|
||||||
|
|
||||||
|
for k, tc := range tmplFuncTestcases {
|
||||||
|
loc := &ingress.Location{
|
||||||
|
Path: tc.Path,
|
||||||
|
Rewrite: rewrite.Config{Target: tc.Target},
|
||||||
|
Backend: defaultBackend,
|
||||||
|
XForwardedPrefix: tc.XForwardedPrefix,
|
||||||
|
}
|
||||||
|
|
||||||
|
if tc.SecureBackend {
|
||||||
|
loc.BackendProtocol = "HTTPS"
|
||||||
|
} else {
|
||||||
|
loc.BackendProtocol = "AUTO_HTTP"
|
||||||
|
}
|
||||||
|
|
||||||
|
backend := &ingress.Backend{
|
||||||
|
Name: defaultBackend,
|
||||||
|
}
|
||||||
|
|
||||||
|
if tc.Sticky {
|
||||||
|
backend.SessionAffinity = ingress.SessionAffinityConfig{
|
||||||
|
AffinityType: "cookie",
|
||||||
|
CookieSessionAffinity: ingress.CookieSessionAffinity{
|
||||||
|
Locations: map[string][]string{
|
||||||
|
defaultHost: {tc.Path},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
backends := []*ingress.Backend{backend}
|
||||||
|
|
||||||
|
pp := buildProxyPass(defaultHost, backends, loc)
|
||||||
|
if !strings.EqualFold(tc.AutoHttpProxyPass, pp) {
|
||||||
|
t.Errorf("%s: expected \n'%v'\nbut returned \n'%v'", k, tc.ProxyPass, pp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBuildAuthLocation(t *testing.T) {
|
func TestBuildAuthLocation(t *testing.T) {
|
||||||
invalidType := &ingress.Ingress{}
|
invalidType := &ingress.Ingress{}
|
||||||
expected := ""
|
expected := ""
|
||||||
|
@ -899,13 +961,14 @@ func TestEscapeLiteralDollar(t *testing.T) {
|
||||||
|
|
||||||
func TestOpentracingPropagateContext(t *testing.T) {
|
func TestOpentracingPropagateContext(t *testing.T) {
|
||||||
tests := map[*ingress.Location]string{
|
tests := map[*ingress.Location]string{
|
||||||
{BackendProtocol: "HTTP"}: "opentracing_propagate_context;",
|
{BackendProtocol: "HTTP"}: "opentracing_propagate_context;",
|
||||||
{BackendProtocol: "HTTPS"}: "opentracing_propagate_context;",
|
{BackendProtocol: "HTTPS"}: "opentracing_propagate_context;",
|
||||||
{BackendProtocol: "GRPC"}: "opentracing_grpc_propagate_context;",
|
{BackendProtocol: "AUTO_HTTP"}: "opentracing_propagate_context;",
|
||||||
{BackendProtocol: "GRPCS"}: "opentracing_grpc_propagate_context;",
|
{BackendProtocol: "GRPC"}: "opentracing_grpc_propagate_context;",
|
||||||
{BackendProtocol: "AJP"}: "opentracing_propagate_context;",
|
{BackendProtocol: "GRPCS"}: "opentracing_grpc_propagate_context;",
|
||||||
{BackendProtocol: "FCGI"}: "opentracing_propagate_context;",
|
{BackendProtocol: "AJP"}: "opentracing_propagate_context;",
|
||||||
nil: "",
|
{BackendProtocol: "FCGI"}: "opentracing_propagate_context;",
|
||||||
|
nil: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
for loc, expectedDirective := range tests {
|
for loc, expectedDirective := range tests {
|
||||||
|
|
|
@ -46,6 +46,21 @@ var _ = framework.DescribeAnnotation("backend-protocol", func() {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ginkgo.It("should set backend protocol to $scheme:// and use proxy_pass", func() {
|
||||||
|
host := "backendprotocol.foo.com"
|
||||||
|
annotations := map[string]string{
|
||||||
|
"nginx.ingress.kubernetes.io/backend-protocol": "AUTO_HTTP",
|
||||||
|
}
|
||||||
|
|
||||||
|
ing := framework.NewSingleIngress(host, "/", host, f.Namespace, framework.EchoService, 80, annotations)
|
||||||
|
f.EnsureIngress(ing)
|
||||||
|
|
||||||
|
f.WaitForNginxServer(host,
|
||||||
|
func(server string) bool {
|
||||||
|
return strings.Contains(server, "proxy_pass $scheme://upstream_balancer;")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
ginkgo.It("should set backend protocol to grpc:// and use grpc_pass", func() {
|
ginkgo.It("should set backend protocol to grpc:// and use grpc_pass", func() {
|
||||||
host := "backendprotocol.foo.com"
|
host := "backendprotocol.foo.com"
|
||||||
annotations := map[string]string{
|
annotations := map[string]string{
|
||||||
|
|
Loading…
Reference in a new issue