From d155a133e212323859480a8328cd4d392e77d80a Mon Sep 17 00:00:00 2001 From: Dmitry Kuleshov Date: Fri, 16 Jul 2021 16:18:46 +0300 Subject: [PATCH 1/3] add auto backend protocol for HTTP/HTTPS --- internal/ingress/annotations/backendprotocol/main.go | 2 +- internal/ingress/controller/template/template.go | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/internal/ingress/annotations/backendprotocol/main.go b/internal/ingress/annotations/backendprotocol/main.go index d6e7beb4ce..65566d6e98 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 0529369fe4..60645245a9 100644 --- a/internal/ingress/controller/template/template.go +++ b/internal/ingress/controller/template/template.go @@ -505,6 +505,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": From 945c83bb6198e6a3d7ad6c15a6a35e9517c9fc06 Mon Sep 17 00:00:00 2001 From: Luca Del Monte Date: Wed, 28 Jul 2021 16:27:01 +0200 Subject: [PATCH 2/3] e2e test for AUTO_HTTP backend protocol --- test/e2e/annotations/backendprotocol.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/e2e/annotations/backendprotocol.go b/test/e2e/annotations/backendprotocol.go index db7e509089..a215cbe83e 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{ From b809f81666f678fdd09bb37c1d6a16cbb50c027a Mon Sep 17 00:00:00 2001 From: Luca Del Monte Date: Wed, 28 Jul 2021 16:27:14 +0200 Subject: [PATCH 3/3] unit test for AUTO_HTTP backend protocol --- .../controller/template/template_test.go | 93 ++++++++++++++++--- 1 file changed, 78 insertions(+), 15 deletions(-) diff --git a/internal/ingress/controller/template/template_test.go b/internal/ingress/controller/template/template_test.go index a37f6cc879..0a54f6e25d 100644 --- a/internal/ingress/controller/template/template_test.go +++ b/internal/ingress/controller/template/template_test.go @@ -57,20 +57,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, @@ -81,6 +83,7 @@ var ( "/", "/", "proxy_pass https://upstream_balancer;", + "proxy_pass https://upstream_balancer;", false, "", true, @@ -91,6 +94,7 @@ var ( "/", "/", "proxy_pass https://upstream_balancer;", + "proxy_pass https://upstream_balancer;", true, "", true, @@ -101,6 +105,7 @@ var ( "/", "/", "proxy_pass http://upstream_balancer;", + "proxy_pass $scheme://upstream_balancer;", false, "", false, @@ -111,6 +116,7 @@ var ( "/", "/", "proxy_pass http://upstream_balancer;", + "proxy_pass $scheme://upstream_balancer;", false, "", false, @@ -123,6 +129,9 @@ var ( ` rewrite "(?i)/" /jenkins break; proxy_pass http://upstream_balancer;`, + ` +rewrite "(?i)/" /jenkins break; +proxy_pass $scheme://upstream_balancer;`, false, "", false, @@ -135,6 +144,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, @@ -147,6 +159,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, @@ -160,6 +175,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, @@ -170,6 +189,7 @@ proxy_pass http://upstream_balancer;`, "/something", `~* "^/something"`, "proxy_pass http://upstream_balancer;", + "proxy_pass $scheme://upstream_balancer;", false, "", false, @@ -334,6 +354,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 := "" @@ -889,13 +951,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 {