refactor: simplify template and use typed function.
This commit is contained in:
parent
750878d668
commit
b1ea36793b
4 changed files with 790 additions and 170 deletions
|
@ -890,91 +890,88 @@ func templatesKubernetesTmpl() (*asset, error) {
|
|||
}
|
||||
|
||||
var _templatesKvTmpl = []byte(`[backends]
|
||||
{{range $backend := List .Prefix "/backends/"}}
|
||||
{{$backendName := Last $backend}}
|
||||
{{range $backend := List .Prefix "/backends/" }}
|
||||
{{ $backendName := Last $backend }}
|
||||
|
||||
{{$circuitBreaker := Get "" $backend "/circuitbreaker/expression"}}
|
||||
{{with $circuitBreaker}}
|
||||
[backends."{{$backendName}}".circuitBreaker]
|
||||
expression = "{{$circuitBreaker}}"
|
||||
{{ $circuitBreaker := getCircuitBreaker $backend }}
|
||||
{{if $circuitBreaker }}
|
||||
[backends."{{ $backendName }}".circuitBreaker]
|
||||
expression = "{{ $circuitBreaker.Expression }}"
|
||||
{{end}}
|
||||
|
||||
{{$loadBalancer := Get "" $backend "/loadbalancer/method"}}
|
||||
{{with $loadBalancer}}
|
||||
[backends."{{$backendName}}".loadBalancer]
|
||||
method = "{{$loadBalancer}}"
|
||||
sticky = {{ getSticky $backend }}
|
||||
{{if hasStickinessLabel $backend}}
|
||||
[backends."{{$backendName}}".loadBalancer.stickiness]
|
||||
cookieName = "{{getStickinessCookieName $backend}}"
|
||||
{{end}}
|
||||
{{ $loadBalancer := getLoadBalancer $backend }}
|
||||
{{if $loadBalancer }}
|
||||
[backends."{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{$maxConnAmt := Get "" $backend "/maxconn/amount"}}
|
||||
{{$maxConnExtractorFunc := Get "" $backend "/maxconn/extractorfunc"}}
|
||||
{{with $maxConnAmt}}
|
||||
{{with $maxConnExtractorFunc}}
|
||||
[backends."{{$backendName}}".maxConn]
|
||||
amount = {{$maxConnAmt}}
|
||||
extractorFunc = "{{$maxConnExtractorFunc}}"
|
||||
{{end}}
|
||||
{{ $maxConn := getMaxConn $backend }}
|
||||
{{if $maxConn }}
|
||||
[backends."{{ $backendName }}".maxConn]
|
||||
extractorFunc = "{{ $maxConn.ExtractorFunc }}"
|
||||
amount = {{ $maxConn.Amount }}
|
||||
{{end}}
|
||||
|
||||
{{$healthCheck := Get "" $backend "/healthcheck/path"}}
|
||||
{{with $healthCheck}}
|
||||
[backends."{{$backendName}}".healthCheck]
|
||||
path = "{{$healthCheck}}"
|
||||
port = {{ Get "0" $backend "/healthcheck/port" }}
|
||||
interval = "{{ Get "30s" $backend "/healthcheck/interval" }}"
|
||||
{{ $healthCheck := getHealthCheck $backend }}
|
||||
{{if $healthCheck }}
|
||||
[backends.{{ $backendName }}.healthCheck]
|
||||
path = "{{ $healthCheck.Path }}"
|
||||
port = {{ $healthCheck.Port }}
|
||||
interval = "{{ $healthCheck.Interval }}"
|
||||
{{end}}
|
||||
|
||||
{{range $server := ListServers $backend}}
|
||||
[backends."{{$backendName}}".servers."{{Last $server}}"]
|
||||
url = "{{Get "" $server "/url"}}"
|
||||
weight = {{Get "0" $server "/weight"}}
|
||||
{{range $serverName, $server := getServers $backend}}
|
||||
[backends."{{ $backendName }}".servers."{{ $serverName }}"]
|
||||
url = "{{ $server.URL }}"
|
||||
weight = {{ $server.Weight }}
|
||||
{{end}}
|
||||
|
||||
{{end}}
|
||||
|
||||
[frontends]
|
||||
{{range $frontend := List .Prefix "/frontends/" }}
|
||||
{{$frontendName := Last $frontend}}
|
||||
{{ $frontendName := Last $frontend }}
|
||||
|
||||
[frontends."{{$frontendName}}"]
|
||||
backend = "{{Get "" $frontend "/backend"}}"
|
||||
priority = {{Get "0" $frontend "/priority"}}
|
||||
passHostHeader = {{Get "true" $frontend "/passHostHeader"}}
|
||||
passTLSCert = {{Get "false" $frontend "/passtlscert"}}
|
||||
[frontends."{{ $frontendName }}"]
|
||||
backend = "{{ getBackendName $frontend }}"
|
||||
priority = {{ getPriority $frontend }}
|
||||
passHostHeader = {{ getPassHostHeader $frontend }}
|
||||
passTLSCert = {{ getPassTLSCert $frontend }}
|
||||
|
||||
{{$entryPoints := SplitGet $frontend "/entrypoints"}}
|
||||
entryPoints = [{{range $entryPoints}}
|
||||
entryPoints = [{{range getEntryPoints $frontend }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
|
||||
{{$whitelistSourceRange := SplitGet $frontend "/whitelistsourcerange"}}
|
||||
whitelistSourceRange = [{{range $whitelistSourceRange}}
|
||||
{{ $whitelistSourceRange := getWhitelistSourceRange $frontend }}
|
||||
{{if $whitelistSourceRange }}
|
||||
whitelistSourceRange = [{{range $whitelistSourceRange }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
{{end}}
|
||||
|
||||
basicAuth = [{{range getBasicAuth $frontend }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
|
||||
{{$basicAuth := SplitGet $frontend "/basicauth"}}
|
||||
basicAuth = [{{range $basicAuth}}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
|
||||
{{$redirect := getRedirect $frontend }}
|
||||
{{ if $redirect }}
|
||||
[frontends."{{$frontendName}}".redirect]
|
||||
{{ $redirect := getRedirect $frontend }}
|
||||
{{if $redirect }}
|
||||
[frontends."{{ $frontendName }}".redirect]
|
||||
entryPoint = "{{ $redirect.EntryPoint }}"
|
||||
regex = "{{ $redirect.Regex }}"
|
||||
replacement = "{{ $redirect.Replacement }}"
|
||||
{{end}}
|
||||
|
||||
{{ $errorPages := getErrorPages $frontend }}
|
||||
{{ if $errorPages }}
|
||||
[frontends."{{$frontendName}}".errors]
|
||||
{{ range $pageName, $page := $errorPages }}
|
||||
{{if $errorPages }}
|
||||
[frontends."{{ $frontendName }}".errors]
|
||||
{{range $pageName, $page := $errorPages }}
|
||||
[frontends."{{$frontendName}}".errors.{{ $pageName }}]
|
||||
status = [{{range $page.Status}}
|
||||
status = [{{range $page.Status }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
backend = "{{$page.Backend}}"
|
||||
|
@ -983,12 +980,12 @@ var _templatesKvTmpl = []byte(`[backends]
|
|||
{{end}}
|
||||
|
||||
{{ $rateLimit := getRateLimit $frontend }}
|
||||
{{ if $rateLimit }}
|
||||
[frontends."{{$frontendName}}".rateLimit]
|
||||
{{if $rateLimit }}
|
||||
[frontends."{{ $frontendName }}".rateLimit]
|
||||
extractorFunc = "{{ $rateLimit.ExtractorFunc }}"
|
||||
[frontends."{{$frontendName}}".rateLimit.rateSet]
|
||||
{{ range $limitName, $rateLimit := $rateLimit.RateSet }}
|
||||
[frontends."{{$frontendName}}".rateLimit.rateSet.{{ $limitName }}]
|
||||
[frontends."{{ $frontendName }}".rateLimit.rateSet]
|
||||
{{range $limitName, $rateLimit := $rateLimit.RateSet }}
|
||||
[frontends."{{ $frontendName }}".rateLimit.rateSet.{{ $limitName }}]
|
||||
period = "{{ $rateLimit.Period }}"
|
||||
average = {{ $rateLimit.Average }}
|
||||
burst = {{ $rateLimit.Burst }}
|
||||
|
@ -996,7 +993,7 @@ var _templatesKvTmpl = []byte(`[backends]
|
|||
{{end}}
|
||||
|
||||
{{ $headers := getHeaders $frontend }}
|
||||
{{ if $headers }}
|
||||
{{if $headers }}
|
||||
[frontends."{{ $frontendName }}".headers]
|
||||
SSLRedirect = {{ $headers.SSLRedirect }}
|
||||
SSLTemporaryRedirect = {{ $headers.SSLTemporaryRedirect }}
|
||||
|
@ -1014,33 +1011,33 @@ var _templatesKvTmpl = []byte(`[backends]
|
|||
ReferrerPolicy = "{{ $headers.ReferrerPolicy }}"
|
||||
IsDevelopment = {{ $headers.IsDevelopment }}
|
||||
|
||||
{{ if $headers.AllowedHosts }}
|
||||
AllowedHosts = [{{ range $headers.AllowedHosts }}
|
||||
{{if $headers.AllowedHosts }}
|
||||
AllowedHosts = [{{range $headers.AllowedHosts }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
{{end}}
|
||||
|
||||
{{ if $headers.HostsProxyHeaders }}
|
||||
HostsProxyHeaders = [{{ range $headers.HostsProxyHeaders }}
|
||||
{{if $headers.HostsProxyHeaders }}
|
||||
HostsProxyHeaders = [{{range $headers.HostsProxyHeaders }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
{{end}}
|
||||
|
||||
{{ if $headers.CustomRequestHeaders }}
|
||||
{{if $headers.CustomRequestHeaders }}
|
||||
[frontends."{{ $frontendName }}".headers.customRequestHeaders]
|
||||
{{ range $k, $v := $headers.CustomRequestHeaders }}
|
||||
{{range $k, $v := $headers.CustomRequestHeaders }}
|
||||
{{$k}} = "{{$v}}"
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{ if $headers.CustomResponseHeaders }}
|
||||
{{if $headers.CustomResponseHeaders }}
|
||||
[frontends."{{ $frontendName }}".headers.customResponseHeaders]
|
||||
{{ range $k, $v := $headers.CustomResponseHeaders }}
|
||||
{{range $k, $v := $headers.CustomResponseHeaders }}
|
||||
{{$k}} = "{{$v}}"
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{ if $headers.SSLProxyHeaders }}
|
||||
{{if $headers.SSLProxyHeaders }}
|
||||
[frontends."{{ $frontendName }}".headers.SSLProxyHeaders]
|
||||
{{range $k, $v := $headers.SSLProxyHeaders}}
|
||||
{{$k}} = "{{$v}}"
|
||||
|
@ -1048,25 +1045,23 @@ var _templatesKvTmpl = []byte(`[backends]
|
|||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{range $route := List $frontend "/routes/"}}
|
||||
[frontends."{{$frontendName}}".routes."{{Last $route}}"]
|
||||
rule = "{{Get "" $route "/rule"}}"
|
||||
{{range $routeName, $route := getRoutes $frontend }}
|
||||
[frontends."{{ $frontendName }}".routes."{{ $routeName }}"]
|
||||
rule = "{{ $route.Rule }}"
|
||||
{{end}}
|
||||
|
||||
{{end}}
|
||||
|
||||
{{range $tlsConfiguration := List .Prefix "/tlsconfiguration/"}}
|
||||
|
||||
{{range $tlsConfiguration := getTLSConfigurations .Prefix }}
|
||||
[[tlsConfiguration]]
|
||||
|
||||
{{$entryPoints := SplitGet $tlsConfiguration "/entrypoints"}}
|
||||
entryPoints = [{{range $entryPoints}}
|
||||
entryPoints = [{{range $tlsConfiguration.EntryPoints }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
|
||||
[tlsConfiguration.certificate]
|
||||
certFile = """{{Get "" $tlsConfiguration "/certificate/certfile"}}"""
|
||||
keyFile = """{{Get "" $tlsConfiguration "/certificate/keyfile"}}"""
|
||||
certFile = """{{ $tlsConfiguration.Certificate.CertFile }}"""
|
||||
keyFile = """{{ $tlsConfiguration.Certificate.KeyFile }}"""
|
||||
|
||||
{{end}}
|
||||
`)
|
||||
|
|
|
@ -2,6 +2,7 @@ package kv
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
@ -12,6 +13,7 @@ import (
|
|||
"github.com/containous/flaeg"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/tls"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/docker/libkv/store"
|
||||
)
|
||||
|
@ -35,16 +37,31 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||
"Last": p.last,
|
||||
"Has": p.has,
|
||||
|
||||
"getTLSConfigurations": p.getTLSConfigurations,
|
||||
|
||||
// Frontend functions
|
||||
"getRedirect": p.getRedirect,
|
||||
"getErrorPages": p.getErrorPages,
|
||||
"getRateLimit": p.getRateLimit,
|
||||
"getHeaders": p.getHeaders,
|
||||
"getBackendName": p.getFuncString(pathFrontendBackend, ""),
|
||||
"getPriority": p.getFuncInt(pathFrontendPriority, 0),
|
||||
"getPassHostHeader": p.getFuncBool(pathFrontendPassHostHeader, true),
|
||||
"getPassTLSCert": p.getFuncBool(pathFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getEntryPoints": p.getFuncSlice(pathFrontendEntryPoints),
|
||||
"getWhitelistSourceRange": p.getFuncSlice(pathFrontendWhiteListSourceRange),
|
||||
"getBasicAuth": p.getFuncSlice(pathFrontendBasicAuth),
|
||||
"getRoutes": p.getRoutes,
|
||||
"getRedirect": p.getRedirect,
|
||||
"getErrorPages": p.getErrorPages,
|
||||
"getRateLimit": p.getRateLimit,
|
||||
"getHeaders": p.getHeaders,
|
||||
|
||||
// Backend functions
|
||||
"getSticky": p.getSticky,
|
||||
"hasStickinessLabel": p.hasStickinessLabel,
|
||||
"getStickinessCookieName": p.getStickinessCookieName,
|
||||
"getServers": p.getServers,
|
||||
"getCircuitBreaker": p.getCircuitBreaker,
|
||||
"getLoadBalancer": p.getLoadBalancer,
|
||||
"getMaxConn": p.getMaxConn,
|
||||
"getHealthCheck": p.getHealthCheck,
|
||||
"getSticky": p.getSticky, // Deprecated [breaking]
|
||||
"hasStickinessLabel": p.hasStickinessLabel, // Deprecated [breaking]
|
||||
"getStickinessCookieName": p.getStickinessCookieName, // Deprecated [breaking]
|
||||
}
|
||||
|
||||
configuration, err := p.GetConfiguration("templates/kv.tmpl", KvFuncMap, templateObjects)
|
||||
|
@ -61,6 +78,7 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||
return configuration
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
func (p *Provider) getSticky(rootPath string) bool {
|
||||
stickyValue := p.get("", rootPath, pathBackendLoadBalancerSticky)
|
||||
if len(stickyValue) > 0 {
|
||||
|
@ -77,10 +95,12 @@ func (p *Provider) getSticky(rootPath string) bool {
|
|||
return sticky
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
func (p *Provider) hasStickinessLabel(rootPath string) bool {
|
||||
return p.getBool(false, rootPath, pathBackendLoadBalancerStickiness)
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
func (p *Provider) getStickinessCookieName(rootPath string) string {
|
||||
return p.get("", rootPath, pathBackendLoadBalancerStickinessCookieName)
|
||||
}
|
||||
|
@ -193,6 +213,145 @@ func (p *Provider) getHeaders(rootPath string) *types.Headers {
|
|||
return headers
|
||||
}
|
||||
|
||||
func (p *Provider) getLoadBalancer(rootPath string) *types.LoadBalancer {
|
||||
lb := &types.LoadBalancer{
|
||||
Method: p.get(label.DefaultBackendLoadBalancerMethod, rootPath, pathBackendLoadBalancerMethod),
|
||||
Sticky: p.getSticky(rootPath),
|
||||
}
|
||||
|
||||
if p.getBool(false, rootPath, pathBackendLoadBalancerStickiness) {
|
||||
lb.Stickiness = &types.Stickiness{
|
||||
CookieName: p.get("", rootPath, pathBackendLoadBalancerStickinessCookieName),
|
||||
}
|
||||
}
|
||||
|
||||
return lb
|
||||
}
|
||||
|
||||
func (p *Provider) getCircuitBreaker(rootPath string) *types.CircuitBreaker {
|
||||
if !p.has(rootPath, pathBackendCircuitBreakerExpression) {
|
||||
return nil
|
||||
}
|
||||
|
||||
circuitBreaker := p.get(label.DefaultCircuitBreakerExpression, rootPath, pathBackendCircuitBreakerExpression)
|
||||
if len(circuitBreaker) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &types.CircuitBreaker{Expression: circuitBreaker}
|
||||
}
|
||||
|
||||
func (p *Provider) getMaxConn(rootPath string) *types.MaxConn {
|
||||
amount := p.getInt64(math.MinInt64, rootPath, pathBackendMaxConnAmount)
|
||||
extractorFunc := p.get(label.DefaultBackendMaxconnExtractorFunc, rootPath, pathBackendMaxConnExtractorFunc)
|
||||
|
||||
if amount == math.MinInt64 || len(extractorFunc) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &types.MaxConn{
|
||||
Amount: amount,
|
||||
ExtractorFunc: extractorFunc,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provider) getHealthCheck(rootPath string) *types.HealthCheck {
|
||||
path := p.get("", rootPath, pathBackendHealthCheckPath)
|
||||
|
||||
if len(path) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
port := p.getInt(label.DefaultBackendHealthCheckPort, rootPath, pathBackendHealthCheckPort)
|
||||
interval := p.get("30s", rootPath, pathBackendHealthCheckInterval)
|
||||
|
||||
return &types.HealthCheck{
|
||||
Path: path,
|
||||
Port: port,
|
||||
Interval: interval,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provider) getTLSConfigurations(prefix string) []*tls.Configuration {
|
||||
var tlsConfiguration []*tls.Configuration
|
||||
|
||||
for _, tlsConfPath := range p.list(prefix, pathTLSConfiguration) {
|
||||
certFile := p.get("", tlsConfPath, pathTLSConfigurationCertFile)
|
||||
keyFile := p.get("", tlsConfPath, pathTLSConfigurationKeyFile)
|
||||
|
||||
if len(certFile) == 0 && len(keyFile) == 0 {
|
||||
log.Warnf("Invalid TLS configuration (no cert and no key): %s", tlsConfPath)
|
||||
continue
|
||||
}
|
||||
|
||||
entryPoints := p.splitGet(tlsConfPath, pathTLSConfigurationEntryPoints)
|
||||
if len(entryPoints) == 0 {
|
||||
log.Warnf("Invalid TLS configuration (no entry points): %s", tlsConfPath)
|
||||
continue
|
||||
}
|
||||
|
||||
tlsConf := &tls.Configuration{
|
||||
EntryPoints: entryPoints,
|
||||
Certificate: &tls.Certificate{
|
||||
CertFile: tls.FileOrContent(certFile),
|
||||
KeyFile: tls.FileOrContent(keyFile),
|
||||
},
|
||||
}
|
||||
|
||||
tlsConfiguration = append(tlsConfiguration, tlsConf)
|
||||
}
|
||||
|
||||
return tlsConfiguration
|
||||
}
|
||||
|
||||
func (p *Provider) getRoutes(rootPath string) map[string]types.Route {
|
||||
var routes map[string]types.Route
|
||||
|
||||
rts := p.list(rootPath, pathFrontendRoutes)
|
||||
for _, rt := range rts {
|
||||
|
||||
rule := p.get("", rt, pathFrontendRule)
|
||||
if len(rule) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if routes == nil {
|
||||
routes = make(map[string]types.Route)
|
||||
}
|
||||
|
||||
routeName := p.last(rt)
|
||||
routes[routeName] = types.Route{
|
||||
Rule: rule,
|
||||
}
|
||||
}
|
||||
|
||||
return routes
|
||||
}
|
||||
|
||||
func (p *Provider) getServers(rootPath string) map[string]types.Server {
|
||||
var servers map[string]types.Server
|
||||
|
||||
serverKeys := p.listServers(rootPath)
|
||||
for _, serverKey := range serverKeys {
|
||||
serverURL := p.get("", serverKey, pathBackendServerURL)
|
||||
if len(serverURL) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if servers == nil {
|
||||
servers = make(map[string]types.Server)
|
||||
}
|
||||
|
||||
serverName := p.last(serverKey)
|
||||
servers[serverName] = types.Server{
|
||||
URL: serverURL,
|
||||
Weight: p.getInt(0, serverKey, pathBackendServerWeight),
|
||||
}
|
||||
}
|
||||
|
||||
return servers
|
||||
}
|
||||
|
||||
func (p *Provider) listServers(backend string) []string {
|
||||
serverNames := p.list(backend, pathBackendServers)
|
||||
return fun.Filter(p.serverFilter, serverNames).([]string)
|
||||
|
@ -229,6 +388,30 @@ func (p *Provider) checkConstraints(keys ...string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (p *Provider) getFuncString(key string, defaultValue string) func(rootPath string) string {
|
||||
return func(rootPath string) string {
|
||||
return p.get(defaultValue, rootPath, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provider) getFuncBool(key string, defaultValue bool) func(rootPath string) bool {
|
||||
return func(rootPath string) bool {
|
||||
return p.getBool(defaultValue, rootPath, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provider) getFuncInt(key string, defaultValue int) func(rootPath string) int {
|
||||
return func(rootPath string) int {
|
||||
return p.getInt(defaultValue, rootPath, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provider) getFuncSlice(key string) func(rootPath string) []string {
|
||||
return func(rootPath string) []string {
|
||||
return p.splitGet(rootPath, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provider) get(defaultValue string, keyParts ...string) string {
|
||||
key := strings.Join(keyParts, "")
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
expected: &types.Configuration{
|
||||
Backends: map[string]*types.Backend{
|
||||
"backend.with.dot.too": {
|
||||
LoadBalancer: &types.LoadBalancer{Method: label.DefaultBackendLoadBalancerMethod},
|
||||
Servers: map[string]types.Server{
|
||||
"server.with.dot": {
|
||||
URL: "http://172.17.0.2:80",
|
||||
|
@ -48,11 +49,10 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
Frontends: map[string]*types.Frontend{
|
||||
"frontend.with.dot": {
|
||||
Backend: "backend.with.dot.too",
|
||||
PassHostHeader: true,
|
||||
EntryPoints: []string{},
|
||||
WhitelistSourceRange: []string{},
|
||||
BasicAuth: []string{},
|
||||
Backend: "backend.with.dot.too",
|
||||
PassHostHeader: true,
|
||||
EntryPoints: []string{},
|
||||
BasicAuth: []string{},
|
||||
Routes: map[string]types.Route{
|
||||
"route.with.dot": {
|
||||
Rule: "Host:test.localhost",
|
||||
|
@ -1292,3 +1292,450 @@ func TestProviderGetHeaders(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderGetLoadBalancer(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
rootPath string
|
||||
kvPairs []*store.KVPair
|
||||
expected *types.LoadBalancer
|
||||
}{
|
||||
{
|
||||
desc: "when all keys",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendLoadBalancerMethod, "drr"),
|
||||
withPair(pathBackendLoadBalancerSticky, "true"),
|
||||
withPair(pathBackendLoadBalancerStickiness, "true"),
|
||||
withPair(pathBackendLoadBalancerStickinessCookieName, "aubergine"))),
|
||||
expected: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "aubergine",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when no specific configuration",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik", backend("foo")),
|
||||
expected: &types.LoadBalancer{
|
||||
Method: "wrr",
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when method is set",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendLoadBalancerMethod, "drr"))),
|
||||
expected: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when sticky is set",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendLoadBalancerSticky, "true"))),
|
||||
expected: &types.LoadBalancer{
|
||||
Method: "wrr",
|
||||
Sticky: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when stickiness is set",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendLoadBalancerStickiness, "true"))),
|
||||
expected: &types.LoadBalancer{
|
||||
Method: "wrr",
|
||||
Stickiness: &types.Stickiness{},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when stickiness cookie name is set",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendLoadBalancerStickiness, "true"),
|
||||
withPair(pathBackendLoadBalancerStickinessCookieName, "aubergine"))),
|
||||
expected: &types.LoadBalancer{
|
||||
Method: "wrr",
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "aubergine",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when stickiness cookie name is set but not stickiness",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendLoadBalancerStickinessCookieName, "aubergine"))),
|
||||
expected: &types.LoadBalancer{
|
||||
Method: "wrr",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := newProviderMock(test.kvPairs)
|
||||
|
||||
result := p.getLoadBalancer(test.rootPath)
|
||||
|
||||
assert.Equal(t, test.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderGetCircuitBreaker(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
rootPath string
|
||||
kvPairs []*store.KVPair
|
||||
expected *types.CircuitBreaker
|
||||
}{
|
||||
{
|
||||
desc: "when cb expression defined",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendCircuitBreakerExpression, label.DefaultCircuitBreakerExpression))),
|
||||
expected: &types.CircuitBreaker{
|
||||
Expression: label.DefaultCircuitBreakerExpression,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when no cb expression",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik", backend("foo")),
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := newProviderMock(test.kvPairs)
|
||||
|
||||
result := p.getCircuitBreaker(test.rootPath)
|
||||
|
||||
assert.Equal(t, test.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderGetMaxConn(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
rootPath string
|
||||
kvPairs []*store.KVPair
|
||||
expected *types.MaxConn
|
||||
}{
|
||||
{
|
||||
desc: "when max conn keys are defined",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendMaxConnAmount, "5"),
|
||||
withPair(pathBackendMaxConnExtractorFunc, "client.ip"))),
|
||||
expected: &types.MaxConn{
|
||||
Amount: 5,
|
||||
ExtractorFunc: "client.ip",
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when only extractor func is defined",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendMaxConnExtractorFunc, "client.ip"))),
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "when only amount is defined",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendMaxConnAmount, "5"))),
|
||||
expected: &types.MaxConn{
|
||||
Amount: 5,
|
||||
ExtractorFunc: "request.host",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := newProviderMock(test.kvPairs)
|
||||
|
||||
result := p.getMaxConn(test.rootPath)
|
||||
|
||||
assert.Equal(t, test.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderGetHealthCheck(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
rootPath string
|
||||
kvPairs []*store.KVPair
|
||||
expected *types.HealthCheck
|
||||
}{
|
||||
{
|
||||
desc: "when all configuration keys defined",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendHealthCheckPath, "/health"),
|
||||
withPair(pathBackendHealthCheckPort, "80"),
|
||||
withPair(pathBackendHealthCheckInterval, "10s"))),
|
||||
expected: &types.HealthCheck{
|
||||
Interval: "10s",
|
||||
Path: "/health",
|
||||
Port: 80,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "when only path defined",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendHealthCheckPath, "/health"))),
|
||||
expected: &types.HealthCheck{
|
||||
Interval: "30s",
|
||||
Path: "/health",
|
||||
Port: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when no path",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendHealthCheckPort, "80"),
|
||||
withPair(pathBackendHealthCheckInterval, "30s"))),
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := newProviderMock(test.kvPairs)
|
||||
|
||||
result := p.getHealthCheck(test.rootPath)
|
||||
|
||||
assert.Equal(t, test.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderGetTLSConfigurations(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
kvPairs []*store.KVPair
|
||||
expected []*tls.Configuration
|
||||
}{
|
||||
{
|
||||
desc: "when several TLS configuration defined",
|
||||
kvPairs: filler("traefik",
|
||||
entry("tlsconfiguration/foo",
|
||||
withPair("entrypoints", "http,https"),
|
||||
withPair("certificate/certfile", "certfile1"),
|
||||
withPair("certificate/keyfile", "keyfile1")),
|
||||
entry("tlsconfiguration/bar",
|
||||
withPair("entrypoints", "http,https"),
|
||||
withPair("certificate/certfile", "certfile2"),
|
||||
withPair("certificate/keyfile", "keyfile2"))),
|
||||
expected: []*tls.Configuration{
|
||||
{
|
||||
EntryPoints: []string{"http", "https"},
|
||||
Certificate: &tls.Certificate{
|
||||
CertFile: "certfile2",
|
||||
KeyFile: "keyfile2",
|
||||
},
|
||||
},
|
||||
{
|
||||
EntryPoints: []string{"http", "https"},
|
||||
Certificate: &tls.Certificate{
|
||||
CertFile: "certfile1",
|
||||
KeyFile: "keyfile1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return nil when no TLS configuration",
|
||||
kvPairs: filler("traefik", entry("tlsconfiguration/foo")),
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return nil when no entry points",
|
||||
kvPairs: filler("traefik",
|
||||
entry("tlsconfiguration/foo",
|
||||
withPair("certificate/certfile", "certfile2"),
|
||||
withPair("certificate/keyfile", "keyfile2"))),
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return nil when no cert file and no key file",
|
||||
kvPairs: filler("traefik",
|
||||
entry("tlsconfiguration/foo",
|
||||
withPair("entrypoints", "http,https"))),
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
prefix := "traefik"
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := newProviderMock(test.kvPairs)
|
||||
|
||||
result := p.getTLSConfigurations(prefix)
|
||||
|
||||
assert.Equal(t, test.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderGetRoutes(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
rootPath string
|
||||
kvPairs []*store.KVPair
|
||||
expected map[string]types.Route
|
||||
}{
|
||||
{
|
||||
desc: "should return nil when no data",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return nil when route key exists but without rule key",
|
||||
rootPath: "traefik/frontends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair(pathFrontendRoutes+"bar", "test1"),
|
||||
withPair(pathFrontendRoutes+"bir", "test2"))),
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return a map when configuration keys are defined",
|
||||
rootPath: "traefik/frontends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
frontend("foo",
|
||||
withPair(pathFrontendRoutes+"bar"+pathFrontendRule, "test1"),
|
||||
withPair(pathFrontendRoutes+"bir"+pathFrontendRule, "test2"))),
|
||||
expected: map[string]types.Route{
|
||||
"bar": {
|
||||
Rule: "test1",
|
||||
},
|
||||
"bir": {
|
||||
Rule: "test2",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := newProviderMock(test.kvPairs)
|
||||
|
||||
result := p.getRoutes(test.rootPath)
|
||||
|
||||
assert.Equal(t, test.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProviderGetServers(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
rootPath string
|
||||
kvPairs []*store.KVPair
|
||||
expected map[string]types.Server
|
||||
}{
|
||||
{
|
||||
desc: "should return nil when no data",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should return nil when server has no URL",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendServers+"server1/weight", "7"),
|
||||
withPair(pathBackendServers+"server2/weight", "6"))),
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
desc: "should use default weight when invalid weight value",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendServers+"server1/url", "http://172.17.0.2:80"),
|
||||
withPair(pathBackendServers+"server1/weight", "kls"))),
|
||||
expected: map[string]types.Server{
|
||||
"server1": {
|
||||
URL: "http://172.17.0.2:80",
|
||||
Weight: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "should return a map when configuration keys are defined",
|
||||
rootPath: "traefik/backends/foo",
|
||||
kvPairs: filler("traefik",
|
||||
backend("foo",
|
||||
withPair(pathBackendServers+"server1/url", "http://172.17.0.2:80"),
|
||||
withPair(pathBackendServers+"server2/url", "http://172.17.0.3:80"),
|
||||
withPair(pathBackendServers+"server2/weight", "6"))),
|
||||
expected: map[string]types.Server{
|
||||
"server1": {
|
||||
URL: "http://172.17.0.2:80",
|
||||
Weight: 0,
|
||||
},
|
||||
"server2": {
|
||||
URL: "http://172.17.0.3:80",
|
||||
Weight: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
p := newProviderMock(test.kvPairs)
|
||||
|
||||
result := p.getServers(test.rootPath)
|
||||
|
||||
assert.Equal(t, test.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,89 +1,86 @@
|
|||
[backends]
|
||||
{{range $backend := List .Prefix "/backends/"}}
|
||||
{{$backendName := Last $backend}}
|
||||
{{range $backend := List .Prefix "/backends/" }}
|
||||
{{ $backendName := Last $backend }}
|
||||
|
||||
{{$circuitBreaker := Get "" $backend "/circuitbreaker/expression"}}
|
||||
{{with $circuitBreaker}}
|
||||
[backends."{{$backendName}}".circuitBreaker]
|
||||
expression = "{{$circuitBreaker}}"
|
||||
{{ $circuitBreaker := getCircuitBreaker $backend }}
|
||||
{{if $circuitBreaker }}
|
||||
[backends."{{ $backendName }}".circuitBreaker]
|
||||
expression = "{{ $circuitBreaker.Expression }}"
|
||||
{{end}}
|
||||
|
||||
{{$loadBalancer := Get "" $backend "/loadbalancer/method"}}
|
||||
{{with $loadBalancer}}
|
||||
[backends."{{$backendName}}".loadBalancer]
|
||||
method = "{{$loadBalancer}}"
|
||||
sticky = {{ getSticky $backend }}
|
||||
{{if hasStickinessLabel $backend}}
|
||||
[backends."{{$backendName}}".loadBalancer.stickiness]
|
||||
cookieName = "{{getStickinessCookieName $backend}}"
|
||||
{{end}}
|
||||
{{ $loadBalancer := getLoadBalancer $backend }}
|
||||
{{if $loadBalancer }}
|
||||
[backends."{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{$maxConnAmt := Get "" $backend "/maxconn/amount"}}
|
||||
{{$maxConnExtractorFunc := Get "" $backend "/maxconn/extractorfunc"}}
|
||||
{{with $maxConnAmt}}
|
||||
{{with $maxConnExtractorFunc}}
|
||||
[backends."{{$backendName}}".maxConn]
|
||||
amount = {{$maxConnAmt}}
|
||||
extractorFunc = "{{$maxConnExtractorFunc}}"
|
||||
{{end}}
|
||||
{{ $maxConn := getMaxConn $backend }}
|
||||
{{if $maxConn }}
|
||||
[backends."{{ $backendName }}".maxConn]
|
||||
extractorFunc = "{{ $maxConn.ExtractorFunc }}"
|
||||
amount = {{ $maxConn.Amount }}
|
||||
{{end}}
|
||||
|
||||
{{$healthCheck := Get "" $backend "/healthcheck/path"}}
|
||||
{{with $healthCheck}}
|
||||
[backends."{{$backendName}}".healthCheck]
|
||||
path = "{{$healthCheck}}"
|
||||
port = {{ Get "0" $backend "/healthcheck/port" }}
|
||||
interval = "{{ Get "30s" $backend "/healthcheck/interval" }}"
|
||||
{{ $healthCheck := getHealthCheck $backend }}
|
||||
{{if $healthCheck }}
|
||||
[backends.{{ $backendName }}.healthCheck]
|
||||
path = "{{ $healthCheck.Path }}"
|
||||
port = {{ $healthCheck.Port }}
|
||||
interval = "{{ $healthCheck.Interval }}"
|
||||
{{end}}
|
||||
|
||||
{{range $server := ListServers $backend}}
|
||||
[backends."{{$backendName}}".servers."{{Last $server}}"]
|
||||
url = "{{Get "" $server "/url"}}"
|
||||
weight = {{Get "0" $server "/weight"}}
|
||||
{{range $serverName, $server := getServers $backend}}
|
||||
[backends."{{ $backendName }}".servers."{{ $serverName }}"]
|
||||
url = "{{ $server.URL }}"
|
||||
weight = {{ $server.Weight }}
|
||||
{{end}}
|
||||
|
||||
{{end}}
|
||||
|
||||
[frontends]
|
||||
{{range $frontend := List .Prefix "/frontends/" }}
|
||||
{{$frontendName := Last $frontend}}
|
||||
{{ $frontendName := Last $frontend }}
|
||||
|
||||
[frontends."{{$frontendName}}"]
|
||||
backend = "{{Get "" $frontend "/backend"}}"
|
||||
priority = {{Get "0" $frontend "/priority"}}
|
||||
passHostHeader = {{Get "true" $frontend "/passHostHeader"}}
|
||||
passTLSCert = {{Get "false" $frontend "/passtlscert"}}
|
||||
[frontends."{{ $frontendName }}"]
|
||||
backend = "{{ getBackendName $frontend }}"
|
||||
priority = {{ getPriority $frontend }}
|
||||
passHostHeader = {{ getPassHostHeader $frontend }}
|
||||
passTLSCert = {{ getPassTLSCert $frontend }}
|
||||
|
||||
{{$entryPoints := SplitGet $frontend "/entrypoints"}}
|
||||
entryPoints = [{{range $entryPoints}}
|
||||
entryPoints = [{{range getEntryPoints $frontend }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
|
||||
{{$whitelistSourceRange := SplitGet $frontend "/whitelistsourcerange"}}
|
||||
whitelistSourceRange = [{{range $whitelistSourceRange}}
|
||||
{{ $whitelistSourceRange := getWhitelistSourceRange $frontend }}
|
||||
{{if $whitelistSourceRange }}
|
||||
whitelistSourceRange = [{{range $whitelistSourceRange }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
{{end}}
|
||||
|
||||
basicAuth = [{{range getBasicAuth $frontend }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
|
||||
{{$basicAuth := SplitGet $frontend "/basicauth"}}
|
||||
basicAuth = [{{range $basicAuth}}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
|
||||
{{$redirect := getRedirect $frontend }}
|
||||
{{ if $redirect }}
|
||||
[frontends."{{$frontendName}}".redirect]
|
||||
{{ $redirect := getRedirect $frontend }}
|
||||
{{if $redirect }}
|
||||
[frontends."{{ $frontendName }}".redirect]
|
||||
entryPoint = "{{ $redirect.EntryPoint }}"
|
||||
regex = "{{ $redirect.Regex }}"
|
||||
replacement = "{{ $redirect.Replacement }}"
|
||||
{{end}}
|
||||
|
||||
{{ $errorPages := getErrorPages $frontend }}
|
||||
{{ if $errorPages }}
|
||||
[frontends."{{$frontendName}}".errors]
|
||||
{{ range $pageName, $page := $errorPages }}
|
||||
{{if $errorPages }}
|
||||
[frontends."{{ $frontendName }}".errors]
|
||||
{{range $pageName, $page := $errorPages }}
|
||||
[frontends."{{$frontendName}}".errors.{{ $pageName }}]
|
||||
status = [{{range $page.Status}}
|
||||
status = [{{range $page.Status }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
backend = "{{$page.Backend}}"
|
||||
|
@ -92,12 +89,12 @@
|
|||
{{end}}
|
||||
|
||||
{{ $rateLimit := getRateLimit $frontend }}
|
||||
{{ if $rateLimit }}
|
||||
[frontends."{{$frontendName}}".rateLimit]
|
||||
{{if $rateLimit }}
|
||||
[frontends."{{ $frontendName }}".rateLimit]
|
||||
extractorFunc = "{{ $rateLimit.ExtractorFunc }}"
|
||||
[frontends."{{$frontendName}}".rateLimit.rateSet]
|
||||
{{ range $limitName, $rateLimit := $rateLimit.RateSet }}
|
||||
[frontends."{{$frontendName}}".rateLimit.rateSet.{{ $limitName }}]
|
||||
[frontends."{{ $frontendName }}".rateLimit.rateSet]
|
||||
{{range $limitName, $rateLimit := $rateLimit.RateSet }}
|
||||
[frontends."{{ $frontendName }}".rateLimit.rateSet.{{ $limitName }}]
|
||||
period = "{{ $rateLimit.Period }}"
|
||||
average = {{ $rateLimit.Average }}
|
||||
burst = {{ $rateLimit.Burst }}
|
||||
|
@ -105,7 +102,7 @@
|
|||
{{end}}
|
||||
|
||||
{{ $headers := getHeaders $frontend }}
|
||||
{{ if $headers }}
|
||||
{{if $headers }}
|
||||
[frontends."{{ $frontendName }}".headers]
|
||||
SSLRedirect = {{ $headers.SSLRedirect }}
|
||||
SSLTemporaryRedirect = {{ $headers.SSLTemporaryRedirect }}
|
||||
|
@ -123,33 +120,33 @@
|
|||
ReferrerPolicy = "{{ $headers.ReferrerPolicy }}"
|
||||
IsDevelopment = {{ $headers.IsDevelopment }}
|
||||
|
||||
{{ if $headers.AllowedHosts }}
|
||||
AllowedHosts = [{{ range $headers.AllowedHosts }}
|
||||
{{if $headers.AllowedHosts }}
|
||||
AllowedHosts = [{{range $headers.AllowedHosts }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
{{end}}
|
||||
|
||||
{{ if $headers.HostsProxyHeaders }}
|
||||
HostsProxyHeaders = [{{ range $headers.HostsProxyHeaders }}
|
||||
{{if $headers.HostsProxyHeaders }}
|
||||
HostsProxyHeaders = [{{range $headers.HostsProxyHeaders }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
{{end}}
|
||||
|
||||
{{ if $headers.CustomRequestHeaders }}
|
||||
{{if $headers.CustomRequestHeaders }}
|
||||
[frontends."{{ $frontendName }}".headers.customRequestHeaders]
|
||||
{{ range $k, $v := $headers.CustomRequestHeaders }}
|
||||
{{range $k, $v := $headers.CustomRequestHeaders }}
|
||||
{{$k}} = "{{$v}}"
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{ if $headers.CustomResponseHeaders }}
|
||||
{{if $headers.CustomResponseHeaders }}
|
||||
[frontends."{{ $frontendName }}".headers.customResponseHeaders]
|
||||
{{ range $k, $v := $headers.CustomResponseHeaders }}
|
||||
{{range $k, $v := $headers.CustomResponseHeaders }}
|
||||
{{$k}} = "{{$v}}"
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{ if $headers.SSLProxyHeaders }}
|
||||
{{if $headers.SSLProxyHeaders }}
|
||||
[frontends."{{ $frontendName }}".headers.SSLProxyHeaders]
|
||||
{{range $k, $v := $headers.SSLProxyHeaders}}
|
||||
{{$k}} = "{{$v}}"
|
||||
|
@ -157,24 +154,22 @@
|
|||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{range $route := List $frontend "/routes/"}}
|
||||
[frontends."{{$frontendName}}".routes."{{Last $route}}"]
|
||||
rule = "{{Get "" $route "/rule"}}"
|
||||
{{range $routeName, $route := getRoutes $frontend }}
|
||||
[frontends."{{ $frontendName }}".routes."{{ $routeName }}"]
|
||||
rule = "{{ $route.Rule }}"
|
||||
{{end}}
|
||||
|
||||
{{end}}
|
||||
|
||||
{{range $tlsConfiguration := List .Prefix "/tlsconfiguration/"}}
|
||||
|
||||
{{range $tlsConfiguration := getTLSConfigurations .Prefix }}
|
||||
[[tlsConfiguration]]
|
||||
|
||||
{{$entryPoints := SplitGet $tlsConfiguration "/entrypoints"}}
|
||||
entryPoints = [{{range $entryPoints}}
|
||||
entryPoints = [{{range $tlsConfiguration.EntryPoints }}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
|
||||
[tlsConfiguration.certificate]
|
||||
certFile = """{{Get "" $tlsConfiguration "/certificate/certfile"}}"""
|
||||
keyFile = """{{Get "" $tlsConfiguration "/certificate/keyfile"}}"""
|
||||
certFile = """{{ $tlsConfiguration.Certificate.CertFile }}"""
|
||||
keyFile = """{{ $tlsConfiguration.Certificate.KeyFile }}"""
|
||||
|
||||
{{end}}
|
||||
|
|
Loading…
Reference in a new issue