feat(rancher): add rate limit and error pages labels.
This commit is contained in:
parent
d0a6689413
commit
22405a1259
3 changed files with 186 additions and 18 deletions
|
@ -15,17 +15,12 @@ import (
|
|||
func (p *Provider) buildConfiguration(services []rancherData) *types.Configuration {
|
||||
|
||||
var RancherFuncMap = template.FuncMap{
|
||||
"getDomain": getFuncString(label.TraefikDomain, p.Domain), // FIXME dead ?
|
||||
|
||||
// Backend functions
|
||||
"getPort": getFuncString(label.TraefikPort, ""),
|
||||
"getBackend": getBackend,
|
||||
"getWeight": getFuncString(label.TraefikWeight, label.DefaultWeight),
|
||||
"getDomain": getFuncString(label.TraefikDomain, p.Domain),
|
||||
"getProtocol": getFuncString(label.TraefikProtocol, label.DefaultProtocol),
|
||||
"getPassHostHeader": getFuncString(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
|
||||
"getPassTLSCert": getFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getPriority": getFuncString(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
|
||||
"getEntryPoints": getFuncSliceString(label.TraefikFrontendEntryPoints),
|
||||
"getBasicAuth": getFuncSliceString(label.TraefikFrontendAuthBasic),
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"getWeight": getFuncString(label.TraefikWeight, label.DefaultWeight),
|
||||
"hasCircuitBreakerLabel": hasFunc(label.TraefikBackendCircuitBreakerExpression),
|
||||
"getCircuitBreakerExpression": getFuncString(label.TraefikBackendCircuitBreakerExpression, label.DefaultCircuitBreakerExpression),
|
||||
"hasLoadBalancerLabel": hasLoadBalancerLabel,
|
||||
|
@ -33,19 +28,33 @@ func (p *Provider) buildConfiguration(services []rancherData) *types.Configurati
|
|||
"hasMaxConnLabels": hasMaxConnLabels,
|
||||
"getMaxConnAmount": getFuncInt64(label.TraefikBackendMaxConnAmount, math.MaxInt64),
|
||||
"getMaxConnExtractorFunc": getFuncString(label.TraefikBackendMaxConnExtractorFunc, label.DefaultBackendMaxconnExtractorFunc),
|
||||
"getSticky": getSticky, // deprecated
|
||||
"getSticky": getSticky,
|
||||
"hasStickinessLabel": hasFunc(label.TraefikBackendLoadBalancerStickiness),
|
||||
"getStickinessCookieName": getFuncString(label.TraefikBackendLoadBalancerStickinessCookieName, label.DefaultBackendLoadbalancerStickinessCookieName),
|
||||
"hasRedirect": hasRedirect,
|
||||
"getRedirectEntryPoint": getFuncString(label.TraefikFrontendRedirectEntryPoint, label.DefaultFrontendRedirectEntryPoint),
|
||||
"getRedirectRegex": getFuncString(label.TraefikFrontendRedirectRegex, ""),
|
||||
"getRedirectReplacement": getFuncString(label.TraefikFrontendRedirectReplacement, ""),
|
||||
"getWhitelistSourceRange": getFuncSliceString(label.TraefikFrontendWhitelistSourceRange),
|
||||
"hasHealthCheckLabels": hasFunc(label.TraefikBackendHealthCheckPath),
|
||||
"getHealthCheckPath": getFuncString(label.TraefikBackendHealthCheckPath, ""),
|
||||
"getHealthCheckPort": getFuncInt(label.TraefikBackendHealthCheckPort, label.DefaultBackendHealthCheckPort),
|
||||
"getHealthCheckInterval": getFuncString(label.TraefikBackendHealthCheckInterval, ""),
|
||||
|
||||
// Frontend functions
|
||||
"getBackend": getBackend,
|
||||
"getPriority": getFuncString(label.TraefikFrontendPriority, label.DefaultFrontendPriority),
|
||||
"getPassHostHeader": getFuncString(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader),
|
||||
"getPassTLSCert": getFuncBool(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getEntryPoints": getFuncSliceString(label.TraefikFrontendEntryPoints),
|
||||
"getBasicAuth": getFuncSliceString(label.TraefikFrontendAuthBasic),
|
||||
"getWhitelistSourceRange": getFuncSliceString(label.TraefikFrontendWhitelistSourceRange),
|
||||
"getFrontendRule": p.getFrontendRule,
|
||||
"hasRedirect": hasRedirect,
|
||||
"getRedirectEntryPoint": getFuncString(label.TraefikFrontendRedirectEntryPoint, label.DefaultFrontendRedirectEntryPoint),
|
||||
"getRedirectRegex": getFuncString(label.TraefikFrontendRedirectRegex, ""),
|
||||
"getRedirectReplacement": getFuncString(label.TraefikFrontendRedirectReplacement, ""),
|
||||
"hasErrorPages": hasPrefixFunc(label.Prefix + label.BaseFrontendErrorPage),
|
||||
"getErrorPages": getErrorPages,
|
||||
"hasRateLimits": hasFunc(label.TraefikFrontendRateLimitExtractorFunc),
|
||||
"getRateLimitsExtractorFunc": getFuncString(label.TraefikFrontendRateLimitExtractorFunc, ""),
|
||||
"getRateLimits": getRateLimits,
|
||||
// Headers
|
||||
"hasRequestHeaders": hasFunc(label.TraefikFrontendRequestHeaders),
|
||||
"getRequestHeaders": getFuncMap(label.TraefikFrontendRequestHeaders),
|
||||
"hasResponseHeaders": hasFunc(label.TraefikFrontendResponseHeaders),
|
||||
|
@ -195,8 +204,21 @@ func getBackend(service rancherData) string {
|
|||
}
|
||||
|
||||
func hasRedirect(service rancherData) bool {
|
||||
return label.Has(service.Labels, label.TraefikFrontendRedirectEntryPoint) ||
|
||||
label.Has(service.Labels, label.TraefikFrontendRedirectRegex) && label.Has(service.Labels, label.TraefikFrontendRedirectReplacement)
|
||||
frep := label.Has(service.Labels, label.TraefikFrontendRedirectEntryPoint)
|
||||
frrg := label.Has(service.Labels, label.TraefikFrontendRedirectRegex)
|
||||
frrp := label.Has(service.Labels, label.TraefikFrontendRedirectReplacement)
|
||||
|
||||
return frep || frrg && frrp
|
||||
}
|
||||
|
||||
func getErrorPages(service rancherData) map[string]*types.ErrorPage {
|
||||
prefix := label.Prefix + label.BaseFrontendErrorPage
|
||||
return label.ParseErrorPages(service.Labels, prefix, label.RegexpFrontendErrorPage)
|
||||
}
|
||||
|
||||
func getRateLimits(service rancherData) map[string]*types.Rate {
|
||||
prefix := label.Prefix + label.BaseFrontendRateLimit
|
||||
return label.ParseRateSets(service.Labels, prefix, label.RegexpFrontendRateLimit)
|
||||
}
|
||||
|
||||
// Label functions
|
||||
|
@ -242,3 +264,9 @@ func hasFunc(labelName string) func(service rancherData) bool {
|
|||
return label.Has(service.Labels, labelName)
|
||||
}
|
||||
}
|
||||
|
||||
func hasPrefixFunc(prefix string) func(service rancherData) bool {
|
||||
return func(service rancherData) bool {
|
||||
return label.HasPrefix(service.Labels, prefix)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@ package rancher
|
|||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -70,6 +72,118 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "with Error Pages",
|
||||
services: []rancherData{
|
||||
{
|
||||
Name: "test/service",
|
||||
Labels: map[string]string{
|
||||
label.TraefikPort: "80",
|
||||
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageStatus: "404",
|
||||
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageBackend: "foobar",
|
||||
label.Prefix + label.BaseFrontendErrorPage + "foo." + label.SuffixErrorPageQuery: "foo_query",
|
||||
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageStatus: "500,600",
|
||||
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageBackend: "foobar",
|
||||
label.Prefix + label.BaseFrontendErrorPage + "bar." + label.SuffixErrorPageQuery: "bar_query",
|
||||
},
|
||||
Health: "healthy",
|
||||
Containers: []string{"127.0.0.1"},
|
||||
},
|
||||
},
|
||||
expectedBackends: map[string]*types.Backend{
|
||||
"backend-test-service": {
|
||||
Servers: map[string]types.Server{
|
||||
"server-0": {
|
||||
URL: "http://127.0.0.1:80",
|
||||
Weight: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedFrontends: map[string]*types.Frontend{
|
||||
"frontend-Host-test-service-rancher-localhost": {
|
||||
EntryPoints: []string{},
|
||||
BasicAuth: []string{},
|
||||
Backend: "backend-test-service",
|
||||
Routes: map[string]types.Route{
|
||||
"route-frontend-Host-test-service-rancher-localhost": {
|
||||
Rule: "Host:test.service.rancher.localhost",
|
||||
},
|
||||
},
|
||||
PassHostHeader: true,
|
||||
Errors: map[string]*types.ErrorPage{
|
||||
"foo": {
|
||||
Status: []string{"404"},
|
||||
Query: "foo_query",
|
||||
Backend: "foobar",
|
||||
},
|
||||
"bar": {
|
||||
Status: []string{"500", "600"},
|
||||
Query: "bar_query",
|
||||
Backend: "foobar",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "with rate Limits",
|
||||
services: []rancherData{
|
||||
{
|
||||
Name: "test/service",
|
||||
Labels: map[string]string{
|
||||
label.TraefikPort: "80",
|
||||
label.TraefikFrontendRateLimitExtractorFunc: "client.ip",
|
||||
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitPeriod: "6",
|
||||
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitAverage: "12",
|
||||
label.Prefix + label.BaseFrontendRateLimit + "foo." + label.SuffixRateLimitBurst: "18",
|
||||
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitPeriod: "3",
|
||||
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitAverage: "6",
|
||||
label.Prefix + label.BaseFrontendRateLimit + "bar." + label.SuffixRateLimitBurst: "9",
|
||||
},
|
||||
Health: "healthy",
|
||||
Containers: []string{"127.0.0.1"},
|
||||
},
|
||||
},
|
||||
expectedBackends: map[string]*types.Backend{
|
||||
"backend-test-service": {
|
||||
Servers: map[string]types.Server{
|
||||
"server-0": {
|
||||
URL: "http://127.0.0.1:80",
|
||||
Weight: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expectedFrontends: map[string]*types.Frontend{
|
||||
"frontend-Host-test-service-rancher-localhost": {
|
||||
EntryPoints: []string{},
|
||||
BasicAuth: []string{},
|
||||
Backend: "backend-test-service",
|
||||
Routes: map[string]types.Route{
|
||||
"route-frontend-Host-test-service-rancher-localhost": {
|
||||
Rule: "Host:test.service.rancher.localhost",
|
||||
},
|
||||
},
|
||||
PassHostHeader: true,
|
||||
RateLimit: &types.RateLimit{
|
||||
ExtractorFunc: "client.ip",
|
||||
RateSet: map[string]*types.Rate{
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
[backends]
|
||||
{{range $backendName, $backend := .Backends}}
|
||||
|
||||
[backends.backend-{{$backendName}}]
|
||||
|
||||
{{if hasCircuitBreakerLabel $backend}}
|
||||
[backends.backend-{{$backendName}}.circuitBreaker]
|
||||
expression = "{{getCircuitBreakerExpression $backend}}"
|
||||
|
@ -68,7 +70,31 @@
|
|||
replacement = "{{getRedirectReplacement $service}}"
|
||||
{{end}}
|
||||
|
||||
[frontends."frontend-{{$frontendName}}".headers]
|
||||
{{ if hasErrorPages $service }}
|
||||
[frontends."frontend-{{$frontendName}}".errors]
|
||||
{{ range $pageName, $page := getErrorPages $service }}
|
||||
[frontends."frontend-{{$frontendName}}".errors.{{ $pageName }}]
|
||||
status = [{{range $page.Status}}
|
||||
"{{.}}",
|
||||
{{end}}]
|
||||
backend = "{{$page.Backend}}"
|
||||
query = "{{$page.Query}}"
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{ if hasRateLimits $service }}
|
||||
[frontends."frontend-{{$frontendName}}".rateLimit]
|
||||
extractorFunc = "{{ getRateLimitsExtractorFunc $service }}"
|
||||
[frontends."frontend-{{$frontendName}}".rateLimit.rateSet]
|
||||
{{ range $limitName, $rateLimit := getRateLimits $service }}
|
||||
[frontends."frontend-{{$frontendName}}".rateLimit.rateSet.{{ $limitName }}]
|
||||
period = "{{ $rateLimit.Period }}"
|
||||
average = {{ $rateLimit.Average }}
|
||||
burst = {{ $rateLimit.Burst }}
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
[frontends."frontend-{{$frontendName}}".headers]
|
||||
{{if hasSSLRedirectHeaders $service}}
|
||||
SSLRedirect = {{getSSLRedirectHeaders $service}}
|
||||
{{end}}
|
||||
|
|
Loading…
Reference in a new issue