From c1aefb8ad8d8d55695efeee26d51e31b3dcbc27a Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Wed, 20 Dec 2017 16:33:57 +0100 Subject: [PATCH] feat(marathon): add error pages and rate limits. --- provider/marathon/config.go | 76 +++++++++++++++++++++++++------------ templates/marathon.tmpl | 26 ++++++++++++- 2 files changed, 77 insertions(+), 25 deletions(-) diff --git a/provider/marathon/config.go b/provider/marathon/config.go index 1c3b1de18..f1d19647f 100644 --- a/provider/marathon/config.go +++ b/provider/marathon/config.go @@ -19,42 +19,51 @@ import ( func (p *Provider) buildConfiguration() *types.Configuration { var MarathonFuncMap = template.FuncMap{ - "getBackend": p.getBackend, + "getBackend": p.getBackend, + "getDomain": getFuncStringService(label.TraefikDomain, p.Domain), // see https://github.com/containous/traefik/pull/1693 + "getSubDomain": p.getSubDomain, // see https://github.com/containous/traefik/pull/1693 + + // Backend functions "getBackendServer": p.getBackendServer, "getPort": getPort, "getWeight": getFuncStringService(label.TraefikWeight, label.DefaultWeight), - "getDomain": getFuncStringService(label.TraefikDomain, p.Domain), // FIXME DEAD? - "getSubDomain": p.getSubDomain, // FIXME DEAD ? "getProtocol": getFuncStringService(label.TraefikProtocol, label.DefaultProtocol), - "getPassHostHeader": getFuncStringService(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), - "getPassTLSCert": getFuncBoolService(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), - "getPriority": getFuncStringService(label.TraefikFrontendPriority, label.DefaultFrontendPriority), - "getEntryPoints": getFuncSliceStringService(label.TraefikFrontendEntryPoints), - "getFrontendRule": p.getFrontendRule, - "getFrontendName": p.getFrontendName, "hasCircuitBreakerLabels": hasFunc(label.TraefikBackendCircuitBreakerExpression), - "hasLoadBalancerLabels": hasLoadBalancerLabels, - "hasMaxConnLabels": hasMaxConnLabels, - "getMaxConnExtractorFunc": getFuncString(label.TraefikBackendMaxConnExtractorFunc, label.DefaultBackendMaxconnExtractorFunc), - "getMaxConnAmount": getFuncInt64(label.TraefikBackendMaxConnAmount, math.MaxInt64), - "getLoadBalancerMethod": getFuncString(label.TraefikBackendLoadBalancerMethod, label.DefaultBackendLoadBalancerMethod), "getCircuitBreakerExpression": getFuncString(label.TraefikBackendCircuitBreakerExpression, label.DefaultCircuitBreakerExpression), + "hasLoadBalancerLabels": hasLoadBalancerLabels, + "getLoadBalancerMethod": getFuncString(label.TraefikBackendLoadBalancerMethod, label.DefaultBackendLoadBalancerMethod), "getSticky": getSticky, "hasStickinessLabel": hasFunc(label.TraefikBackendLoadBalancerStickiness), "getStickinessCookieName": getFuncString(label.TraefikBackendLoadBalancerStickinessCookieName, ""), + "hasMaxConnLabels": hasMaxConnLabels, + "getMaxConnExtractorFunc": getFuncString(label.TraefikBackendMaxConnExtractorFunc, label.DefaultBackendMaxconnExtractorFunc), + "getMaxConnAmount": getFuncInt64(label.TraefikBackendMaxConnAmount, math.MaxInt64), "hasHealthCheckLabels": hasFunc(label.TraefikBackendHealthCheckPath), "getHealthCheckPath": getFuncString(label.TraefikBackendHealthCheckPath, ""), "getHealthCheckPort": getFuncInt(label.TraefikBackendHealthCheckPort, label.DefaultBackendHealthCheckPort), "getHealthCheckInterval": getFuncString(label.TraefikBackendHealthCheckInterval, ""), - "getBasicAuth": getFuncSliceStringService(label.TraefikFrontendAuthBasic), - "getServiceNames": getServiceNames, - "getServiceNameSuffix": getServiceNameSuffix, - "getWhitelistSourceRange": getFuncSliceStringService(label.TraefikFrontendWhitelistSourceRange), - "hasRedirect": hasRedirect, - "getRedirectEntryPoint": getFuncStringService(label.TraefikFrontendRedirectEntryPoint, label.DefaultFrontendRedirectEntryPoint), - "getRedirectRegex": getFuncStringService(label.TraefikFrontendRedirectRegex, ""), - "getRedirectReplacement": getFuncStringService(label.TraefikFrontendRedirectReplacement, ""), + // Frontend functions + "getPassHostHeader": getFuncStringService(label.TraefikFrontendPassHostHeader, label.DefaultPassHostHeader), + "getPassTLSCert": getFuncBoolService(label.TraefikFrontendPassTLSCert, label.DefaultPassTLSCert), + "getPriority": getFuncStringService(label.TraefikFrontendPriority, label.DefaultFrontendPriority), + "getEntryPoints": getFuncSliceStringService(label.TraefikFrontendEntryPoints), + "getFrontendRule": p.getFrontendRule, + "getFrontendName": p.getFrontendName, + "getBasicAuth": getFuncSliceStringService(label.TraefikFrontendAuthBasic), + "getServiceNames": getServiceNames, + "getServiceNameSuffix": getServiceNameSuffix, + "getWhitelistSourceRange": getFuncSliceStringService(label.TraefikFrontendWhitelistSourceRange), + "hasRedirect": hasRedirect, + "getRedirectEntryPoint": getFuncStringService(label.TraefikFrontendRedirectEntryPoint, label.DefaultFrontendRedirectEntryPoint), + "getRedirectRegex": getFuncStringService(label.TraefikFrontendRedirectRegex, ""), + "getRedirectReplacement": getFuncStringService(label.TraefikFrontendRedirectReplacement, ""), + "hasErrorPages": hasErrorPages, + "getErrorPages": getErrorPages, + "hasRateLimits": hasFuncService(label.TraefikFrontendRateLimitExtractorFunc), + "getRateLimitsExtractorFunc": getFuncStringService(label.TraefikFrontendRateLimitExtractorFunc, ""), + "getRateLimits": getRateLimits, + // Headers "hasRequestHeaders": hasFuncService(label.TraefikFrontendRequestHeaders), "getRequestHeaders": getFuncMapService(label.TraefikFrontendRequestHeaders), "hasResponseHeaders": hasFuncService(label.TraefikFrontendResponseHeaders), @@ -120,10 +129,10 @@ func (p *Provider) buildConfiguration() *types.Configuration { templateObjects := struct { Applications []marathon.Application - Domain string // FIXME DEAD ? + Domain string }{ Applications: filteredApps, - Domain: p.Domain, // FIXME DEAD ? + Domain: p.Domain, } configuration, err := p.GetConfiguration("templates/marathon.tmpl", MarathonFuncMap, templateObjects) @@ -419,6 +428,25 @@ func hasRedirect(application marathon.Application, serviceName string) bool { return frep || frrg && frrp } +func hasErrorPages(application marathon.Application, serviceName string) bool { + labels := getLabels(application, serviceName) + return label.HasPrefix(labels, label.Prefix+label.BaseFrontendErrorPage) +} + +func getErrorPages(application marathon.Application, serviceName string) map[string]*types.ErrorPage { + labels := getLabels(application, serviceName) + + prefix := label.Prefix + label.BaseFrontendErrorPage + return label.ParseErrorPages(labels, prefix, label.RegexpFrontendErrorPage) +} + +func getRateLimits(application marathon.Application, serviceName string) map[string]*types.Rate { + labels := getLabels(application, serviceName) + + prefix := label.Prefix + label.BaseFrontendRateLimit + return label.ParseRateSets(labels, prefix, label.RegexpFrontendRateLimit) +} + // Label functions func getLabels(application marathon.Application, serviceName string) map[string]string { diff --git a/templates/marathon.tmpl b/templates/marathon.tmpl index 158a88f4c..46edaa6ce 100644 --- a/templates/marathon.tmpl +++ b/templates/marathon.tmpl @@ -79,7 +79,31 @@ replacement = "{{getRedirectReplacement $app $serviceName}}" {{end}} - [frontends."{{ getFrontendName $app $serviceName }}".headers] + {{ if hasErrorPages $app $serviceName }} + [frontends."{{ getFrontendName $app $serviceName }}".errors] + {{ range $pageName, $page := getErrorPages $app $serviceName }} + [frontends."{{ getFrontendName $app $serviceName }}".errors.{{ $pageName }}] + status = [{{range $page.Status}} + "{{.}}", + {{end}}] + backend = "{{$page.Backend}}" + query = "{{$page.Query}}" + {{end}} + {{end}} + + {{ if hasRateLimits $app $serviceName }} + [frontends."{{ getFrontendName $app $serviceName }}".rateLimit] + extractorFunc = "{{ getRateLimitsExtractorFunc $app $serviceName }}" + [frontends."{{ getFrontendName $app $serviceName }}".rateLimit.rateSet] + {{ range $limitName, $rateLimit := getRateLimits $app $serviceName }} + [frontends."{{ getFrontendName $app $serviceName }}".rateLimit.rateSet.{{ $limitName }}] + period = "{{ $rateLimit.Period }}" + average = {{ $rateLimit.Average }} + burst = {{ $rateLimit.Burst }} + {{end}} + {{end}} + + [frontends."{{ getFrontendName $app $serviceName }}".headers] {{if hasSSLRedirectHeaders $app $serviceName}} SSLRedirect = {{getSSLRedirectHeaders $app $serviceName}} {{end}}