diff --git a/internal/ingress/annotations/backendprotocol/main.go b/internal/ingress/annotations/backendprotocol/main.go index d6e7beb4c..65566d6e9 100644 --- a/internal/ingress/annotations/backendprotocol/main.go +++ b/internal/ingress/annotations/backendprotocol/main.go @@ -31,7 +31,7 @@ import ( const HTTP = "HTTP" var ( - validProtocols = regexp.MustCompile(`^(HTTP|HTTPS|AJP|GRPC|GRPCS|FCGI)$`) + validProtocols = regexp.MustCompile(`^(AUTO_HTTP|HTTP|HTTPS|AJP|GRPC|GRPCS|FCGI)$`) ) type backendProtocol struct { diff --git a/internal/ingress/controller/template/template.go b/internal/ingress/controller/template/template.go index 3aa521c87..a14e2d50b 100644 --- a/internal/ingress/controller/template/template.go +++ b/internal/ingress/controller/template/template.go @@ -617,6 +617,8 @@ func buildProxyPass(host string, b interface{}, loc interface{}) string { proxyPass := "proxy_pass" switch location.BackendProtocol { + case "AUTO_HTTP": + proto = "$scheme://" case "HTTPS": proto = "https://" case "GRPC": diff --git a/internal/ingress/controller/template/template_test.go b/internal/ingress/controller/template/template_test.go index 411b24349..c5f40c246 100644 --- a/internal/ingress/controller/template/template_test.go +++ b/internal/ingress/controller/template/template_test.go @@ -59,20 +59,22 @@ func init() { var ( // TODO: add tests for SSLPassthrough tmplFuncTestcases = map[string]struct { - Path string - Target string - Location string - ProxyPass string - Sticky bool - XForwardedPrefix string - SecureBackend bool - enforceRegex bool + Path string + Target string + Location string + ProxyPass string + AutoHttpProxyPass string + Sticky bool + XForwardedPrefix string + SecureBackend bool + enforceRegex bool }{ "when secure backend enabled": { "/", "/", "/", "proxy_pass https://upstream_balancer;", + "proxy_pass https://upstream_balancer;", false, "", true, @@ -83,6 +85,7 @@ var ( "/", "/", "proxy_pass https://upstream_balancer;", + "proxy_pass https://upstream_balancer;", false, "", true, @@ -93,6 +96,7 @@ var ( "/", "/", "proxy_pass https://upstream_balancer;", + "proxy_pass https://upstream_balancer;", true, "", true, @@ -103,6 +107,7 @@ var ( "/", "/", "proxy_pass http://upstream_balancer;", + "proxy_pass $scheme://upstream_balancer;", false, "", false, @@ -113,6 +118,7 @@ var ( "/", "/", "proxy_pass http://upstream_balancer;", + "proxy_pass $scheme://upstream_balancer;", false, "", false, @@ -125,6 +131,9 @@ var ( ` rewrite "(?i)/" /jenkins break; proxy_pass http://upstream_balancer;`, + ` +rewrite "(?i)/" /jenkins break; +proxy_pass $scheme://upstream_balancer;`, false, "", false, @@ -137,6 +146,9 @@ proxy_pass http://upstream_balancer;`, ` rewrite "(?i)/" /something break; proxy_pass http://upstream_balancer;`, + ` +rewrite "(?i)/" /something break; +proxy_pass $scheme://upstream_balancer;`, true, "", false, @@ -149,6 +161,9 @@ proxy_pass http://upstream_balancer;`, ` rewrite "(?i)/" /something break; proxy_pass http://upstream_balancer;`, + ` +rewrite "(?i)/" /something break; +proxy_pass $scheme://upstream_balancer;`, true, "", false, @@ -162,6 +177,10 @@ proxy_pass http://upstream_balancer;`, rewrite "(?i)/there" /something break; proxy_set_header X-Forwarded-Prefix "/there"; proxy_pass http://upstream_balancer;`, + ` +rewrite "(?i)/there" /something break; +proxy_set_header X-Forwarded-Prefix "/there"; +proxy_pass $scheme://upstream_balancer;`, true, "/there", false, @@ -172,6 +191,7 @@ proxy_pass http://upstream_balancer;`, "/something", `~* "^/something"`, "proxy_pass http://upstream_balancer;", + "proxy_pass $scheme://upstream_balancer;", 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) { invalidType := &ingress.Ingress{} expected := "" @@ -899,13 +961,14 @@ func TestEscapeLiteralDollar(t *testing.T) { func TestOpentracingPropagateContext(t *testing.T) { tests := map[*ingress.Location]string{ - {BackendProtocol: "HTTP"}: "opentracing_propagate_context;", - {BackendProtocol: "HTTPS"}: "opentracing_propagate_context;", - {BackendProtocol: "GRPC"}: "opentracing_grpc_propagate_context;", - {BackendProtocol: "GRPCS"}: "opentracing_grpc_propagate_context;", - {BackendProtocol: "AJP"}: "opentracing_propagate_context;", - {BackendProtocol: "FCGI"}: "opentracing_propagate_context;", - nil: "", + {BackendProtocol: "HTTP"}: "opentracing_propagate_context;", + {BackendProtocol: "HTTPS"}: "opentracing_propagate_context;", + {BackendProtocol: "AUTO_HTTP"}: "opentracing_propagate_context;", + {BackendProtocol: "GRPC"}: "opentracing_grpc_propagate_context;", + {BackendProtocol: "GRPCS"}: "opentracing_grpc_propagate_context;", + {BackendProtocol: "AJP"}: "opentracing_propagate_context;", + {BackendProtocol: "FCGI"}: "opentracing_propagate_context;", + nil: "", } for loc, expectedDirective := range tests { diff --git a/test/e2e/annotations/backendprotocol.go b/test/e2e/annotations/backendprotocol.go index db7e50908..a215cbe83 100644 --- a/test/e2e/annotations/backendprotocol.go +++ b/test/e2e/annotations/backendprotocol.go @@ -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() { host := "backendprotocol.foo.com" annotations := map[string]string{