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:
Dmitry Kuleshov 2021-07-29 22:49:19 +03:00 committed by GitHub
parent b1f9f83810
commit a327a809d9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 96 additions and 16 deletions

View file

@ -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 {

View file

@ -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":

View file

@ -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 {

View file

@ -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{