Add quote function in template

Co-authored-by: Charle Demers <charle.demers@gmail.com>
This commit is contained in:
Pierrick Charron 2019-08-09 15:47:29 -04:00
parent 8c472190d1
commit f459515d0d
4 changed files with 50 additions and 18 deletions

View file

@ -30,6 +30,7 @@ In addition to the built-in functions provided by the Go package the following f
- hasSuffix: [strings.HasSuffix](https://golang.org/pkg/strings/#HasSuffix) - hasSuffix: [strings.HasSuffix](https://golang.org/pkg/strings/#HasSuffix)
- toUpper: [strings.ToUpper](https://golang.org/pkg/strings/#ToUpper) - toUpper: [strings.ToUpper](https://golang.org/pkg/strings/#ToUpper)
- toLower: [strings.ToLower](https://golang.org/pkg/strings/#ToLower) - toLower: [strings.ToLower](https://golang.org/pkg/strings/#ToLower)
- quote: wraps a string in double quotes
- buildLocation: helps to build the NGINX Location section in each server - buildLocation: helps to build the NGINX Location section in each server
- buildProxyPass: builds the reverse proxy configuration - buildProxyPass: builds the reverse proxy configuration
- buildRateLimit: helps to build a limit zone inside a location if contains a rate limit annotation - buildRateLimit: helps to build a limit zone inside a location if contains a rate limit annotation

View file

@ -160,6 +160,7 @@ var (
"toUpper": strings.ToUpper, "toUpper": strings.ToUpper,
"toLower": strings.ToLower, "toLower": strings.ToLower,
"formatIP": formatIP, "formatIP": formatIP,
"quote": quote,
"buildNextUpstream": buildNextUpstream, "buildNextUpstream": buildNextUpstream,
"getIngressInformation": getIngressInformation, "getIngressInformation": getIngressInformation,
"serverConfig": func(all config.TemplateConfig, server *ingress.Server) interface{} { "serverConfig": func(all config.TemplateConfig, server *ingress.Server) interface{} {
@ -208,6 +209,21 @@ func formatIP(input string) string {
return fmt.Sprintf("[%s]", input) return fmt.Sprintf("[%s]", input)
} }
func quote(input interface{}) string {
var inputStr string
switch input := input.(type) {
case string:
inputStr = input
break
case fmt.Stringer:
inputStr = input.String()
break
default:
inputStr = fmt.Sprintf("%v", input)
}
return fmt.Sprintf("%q", inputStr)
}
func shouldConfigureLuaRestyWAF(disableLuaRestyWAF bool, mode string) bool { func shouldConfigureLuaRestyWAF(disableLuaRestyWAF bool, mode string) bool {
if !disableLuaRestyWAF && len(mode) > 0 { if !disableLuaRestyWAF && len(mode) > 0 {
return true return true

View file

@ -231,6 +231,21 @@ func TestFormatIP(t *testing.T) {
} }
} }
func TestQuote(t *testing.T) {
cases := map[interface{}]string{
"foo": `"foo"`,
"\"foo\"": `"\"foo\""`,
"foo\nbar": `"foo\nbar"`,
10: `"10"`,
}
for input, output := range cases {
actual := quote(input)
if actual != output {
t.Errorf("quote('%s'): expected '%v' but returned '%v'", input, output, actual)
}
}
}
func TestBuildLocation(t *testing.T) { func TestBuildLocation(t *testing.T) {
invalidType := &ingress.Ingress{} invalidType := &ingress.Ingress{}
expected := "/" expected := "/"

View file

@ -253,7 +253,7 @@ http {
# Custom headers for response # Custom headers for response
{{ range $k, $v := $addHeaders }} {{ range $k, $v := $addHeaders }}
add_header {{ $k }} "{{ $v }}"; add_header {{ $k }} {{ $v | quote }};
{{ end }} {{ end }}
server_tokens {{ if $cfg.ShowServerTokens }}on{{ else }}off{{ end }}; server_tokens {{ if $cfg.ShowServerTokens }}on{{ else }}off{{ end }};
@ -911,7 +911,7 @@ stream {
# ngx_auth_request module overrides variables in the parent request, # ngx_auth_request module overrides variables in the parent request,
# therefore we have to explicitly set this variable again so that when the parent request # therefore we have to explicitly set this variable again so that when the parent request
# resumes it has the correct value set for this variable so that Lua can pick backend correctly # resumes it has the correct value set for this variable so that Lua can pick backend correctly
set $proxy_upstream_name "{{ buildUpstreamName $location }}"; set $proxy_upstream_name {{ buildUpstreamName $location | quote }};
proxy_pass_request_body off; proxy_pass_request_body off;
proxy_set_header Content-Length ""; proxy_set_header Content-Length "";
@ -981,11 +981,11 @@ stream {
location {{ $path }} { location {{ $path }} {
{{ $ing := (getIngressInformation $location.Ingress $server.Hostname $location.Path) }} {{ $ing := (getIngressInformation $location.Ingress $server.Hostname $location.Path) }}
set $namespace "{{ $ing.Namespace }}"; set $namespace {{ $ing.Namespace | quote}};
set $ingress_name "{{ $ing.Rule }}"; set $ingress_name {{ $ing.Rule | quote }};
set $service_name "{{ $ing.Service }}"; set $service_name {{ $ing.Service | quote }};
set $service_port "{{ $location.Port }}"; set $service_port {{ $location.Port | quote }};
set $location_path "{{ $location.Path | escapeLiteralDollar }}"; set $location_path {{ $location.Path | escapeLiteralDollar | quote }};
{{ if $all.Cfg.EnableOpentracing }} {{ if $all.Cfg.EnableOpentracing }}
{{ opentracingPropagateContext $location }}; {{ opentracingPropagateContext $location }};
@ -1006,7 +1006,7 @@ stream {
local lua_resty_waf = require("resty.waf") local lua_resty_waf = require("resty.waf")
local waf = lua_resty_waf:new() local waf = lua_resty_waf:new()
waf:set_option("mode", "{{ $location.LuaRestyWAF.Mode }}") waf:set_option("mode", {{ $location.LuaRestyWAF.Mode | quote }})
waf:set_option("storage_zone", "waf_storage") waf:set_option("storage_zone", "waf_storage")
{{ if $location.LuaRestyWAF.AllowUnknownContentTypes }} {{ if $location.LuaRestyWAF.AllowUnknownContentTypes }}
@ -1035,7 +1035,7 @@ stream {
{{ end }} {{ end }}
{{ range $ruleset := $location.LuaRestyWAF.IgnoredRuleSets }} {{ range $ruleset := $location.LuaRestyWAF.IgnoredRuleSets }}
waf:set_option("ignore_ruleset", "{{ $ruleset }}") waf:set_option("ignore_ruleset", {{ $ruleset | quote }})
{{ end }} {{ end }}
{{ if gt (len $location.LuaRestyWAF.ExtraRulesetString) 0 }} {{ if gt (len $location.LuaRestyWAF.ExtraRulesetString) 0 }}
@ -1099,7 +1099,7 @@ stream {
port_in_redirect {{ if $location.UsePortInRedirects }}on{{ else }}off{{ end }}; port_in_redirect {{ if $location.UsePortInRedirects }}on{{ else }}off{{ end }};
set $balancer_ewma_score -1; set $balancer_ewma_score -1;
set $proxy_upstream_name "{{ buildUpstreamName $location }}"; set $proxy_upstream_name {{ buildUpstreamName $location | quote }};
set $proxy_host $proxy_upstream_name; set $proxy_host $proxy_upstream_name;
set $pass_access_scheme $scheme; set $pass_access_scheme $scheme;
set $pass_server_port $server_port; set $pass_server_port $server_port;
@ -1124,7 +1124,7 @@ stream {
{{ end }} {{ end }}
{{ if (not (empty $location.ModSecurity.TransactionID)) }} {{ if (not (empty $location.ModSecurity.TransactionID)) }}
modsecurity_transaction_id "{{ $location.ModSecurity.TransactionID }}"; modsecurity_transaction_id {{ $location.ModSecurity.TransactionID | quote }};
{{ end }} {{ end }}
{{ end }} {{ end }}
@ -1153,10 +1153,10 @@ stream {
{{ if $location.BasicDigestAuth.Secured }} {{ if $location.BasicDigestAuth.Secured }}
{{ if eq $location.BasicDigestAuth.Type "basic" }} {{ if eq $location.BasicDigestAuth.Type "basic" }}
auth_basic "{{ $location.BasicDigestAuth.Realm }}"; auth_basic {{ $location.BasicDigestAuth.Realm | quote }};
auth_basic_user_file {{ $location.BasicDigestAuth.File }}; auth_basic_user_file {{ $location.BasicDigestAuth.File }};
{{ else }} {{ else }}
auth_digest "{{ $location.BasicDigestAuth.Realm }}"; auth_digest {{ $location.BasicDigestAuth.Realm | quote }};
auth_digest_user_file {{ $location.BasicDigestAuth.File }}; auth_digest_user_file {{ $location.BasicDigestAuth.File }};
{{ end }} {{ end }}
proxy_set_header Authorization ""; proxy_set_header Authorization "";
@ -1190,7 +1190,7 @@ stream {
{{/* By default use vhost as Host to upstream, but allow overrides */}} {{/* By default use vhost as Host to upstream, but allow overrides */}}
{{ if not (eq $proxySetHeader "grpc_set_header") }} {{ if not (eq $proxySetHeader "grpc_set_header") }}
{{ if not (empty $location.UpstreamVhost) }} {{ if not (empty $location.UpstreamVhost) }}
{{ $proxySetHeader }} Host "{{ $location.UpstreamVhost }}"; {{ $proxySetHeader }} Host {{ $location.UpstreamVhost | quote }};
{{ else }} {{ else }}
{{ $proxySetHeader }} Host $best_http_host; {{ $proxySetHeader }} Host $best_http_host;
{{ end }} {{ end }}
@ -1238,7 +1238,7 @@ stream {
# Custom headers to proxied server # Custom headers to proxied server
{{ range $k, $v := $all.ProxySetHeaders }} {{ range $k, $v := $all.ProxySetHeaders }}
{{ $proxySetHeader }} {{ $k }} "{{ $v }}"; {{ $proxySetHeader }} {{ $k }} {{ $v | quote }};
{{ end }} {{ end }}
proxy_connect_timeout {{ $location.Proxy.ConnectTimeout }}s; proxy_connect_timeout {{ $location.Proxy.ConnectTimeout }}s;
@ -1295,10 +1295,10 @@ stream {
include /etc/nginx/fastcgi_params; include /etc/nginx/fastcgi_params;
{{ end }} {{ end }}
{{- if $location.FastCGI.Index -}} {{- if $location.FastCGI.Index -}}
fastcgi_index "{{ $location.FastCGI.Index }}"; fastcgi_index {{ $location.FastCGI.Index | quote }};
{{- end -}} {{- end -}}
{{ range $k, $v := $location.FastCGI.Params }} {{ range $k, $v := $location.FastCGI.Params }}
fastcgi_param {{ $k }} "{{ $v }}"; fastcgi_param {{ $k }} {{ $v | quote }};
{{ end }} {{ end }}
{{ buildProxyPass $server.Hostname $all.Backends $location }} {{ buildProxyPass $server.Hostname $all.Backends $location }}
@ -1308,7 +1308,7 @@ stream {
proxy_redirect {{ $location.Proxy.ProxyRedirectFrom }} {{ $location.Proxy.ProxyRedirectTo }}; proxy_redirect {{ $location.Proxy.ProxyRedirectFrom }} {{ $location.Proxy.ProxyRedirectTo }};
{{ end }} {{ end }}
{{ else }} {{ else }}
# Location denied. Reason: {{ $location.Denied | printf "%q" }} # Location denied. Reason: {{ $location.Denied | quote }}
return 503; return 503;
{{ end }} {{ end }}
} }