Remove Deprecated Step 1
This commit is contained in:
parent
1d53077fc7
commit
8627256e74
68 changed files with 168 additions and 1695 deletions
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/acme"
|
||||
"github.com/containous/traefik/configuration"
|
||||
"github.com/containous/traefik/provider"
|
||||
|
@ -33,15 +33,12 @@ func TestDo_globalConfiguration(t *testing.T) {
|
|||
|
||||
config := &configuration.GlobalConfiguration{}
|
||||
|
||||
config.GraceTimeOut = flaeg.Duration(666 * time.Second)
|
||||
config.Debug = true
|
||||
config.CheckNewVersion = true
|
||||
config.AccessLogsFile = "AccessLogsFile"
|
||||
config.AccessLog = &types.AccessLog{
|
||||
FilePath: "AccessLog FilePath",
|
||||
Format: "AccessLog Format",
|
||||
}
|
||||
config.TraefikLogsFile = "TraefikLogsFile"
|
||||
config.LogLevel = "LogLevel"
|
||||
config.EntryPoints = configuration.EntryPoints{
|
||||
"foo": {
|
||||
|
@ -177,25 +174,24 @@ func TestDo_globalConfiguration(t *testing.T) {
|
|||
},
|
||||
}
|
||||
config.DefaultEntryPoints = configuration.DefaultEntryPoints{"DefaultEntryPoints 1", "DefaultEntryPoints 2", "DefaultEntryPoints 3"}
|
||||
config.ProvidersThrottleDuration = flaeg.Duration(666 * time.Second)
|
||||
config.ProvidersThrottleDuration = parse.Duration(666 * time.Second)
|
||||
config.MaxIdleConnsPerHost = 666
|
||||
config.IdleTimeout = flaeg.Duration(666 * time.Second)
|
||||
config.InsecureSkipVerify = true
|
||||
config.RootCAs = traefiktls.RootCAs{"RootCAs 1", "RootCAs 2", "RootCAs 3"}
|
||||
config.Retry = &configuration.Retry{
|
||||
Attempts: 666,
|
||||
}
|
||||
config.HealthCheck = &configuration.HealthCheckConfig{
|
||||
Interval: flaeg.Duration(666 * time.Second),
|
||||
Interval: parse.Duration(666 * time.Second),
|
||||
}
|
||||
config.RespondingTimeouts = &configuration.RespondingTimeouts{
|
||||
ReadTimeout: flaeg.Duration(666 * time.Second),
|
||||
WriteTimeout: flaeg.Duration(666 * time.Second),
|
||||
IdleTimeout: flaeg.Duration(666 * time.Second),
|
||||
ReadTimeout: parse.Duration(666 * time.Second),
|
||||
WriteTimeout: parse.Duration(666 * time.Second),
|
||||
IdleTimeout: parse.Duration(666 * time.Second),
|
||||
}
|
||||
config.ForwardingTimeouts = &configuration.ForwardingTimeouts{
|
||||
DialTimeout: flaeg.Duration(666 * time.Second),
|
||||
ResponseHeaderTimeout: flaeg.Duration(666 * time.Second),
|
||||
DialTimeout: parse.Duration(666 * time.Second),
|
||||
ResponseHeaderTimeout: parse.Duration(666 * time.Second),
|
||||
}
|
||||
config.Docker = &docker.Provider{
|
||||
BaseProvider: provider.BaseProvider{
|
||||
|
@ -249,50 +245,6 @@ func TestDo_globalConfiguration(t *testing.T) {
|
|||
},
|
||||
Directory: "file Directory",
|
||||
}
|
||||
config.Web = &configuration.WebCompatibility{
|
||||
Address: "web Address",
|
||||
CertFile: "web CertFile",
|
||||
KeyFile: "web KeyFile",
|
||||
ReadOnly: true,
|
||||
Statistics: &types.Statistics{
|
||||
RecentErrors: 666,
|
||||
},
|
||||
Metrics: &types.Metrics{
|
||||
Prometheus: &types.Prometheus{
|
||||
Buckets: types.Buckets{6.5, 6.6, 6.7},
|
||||
},
|
||||
Datadog: &types.Datadog{
|
||||
Address: "Datadog Address",
|
||||
PushInterval: "Datadog PushInterval",
|
||||
},
|
||||
StatsD: &types.Statsd{
|
||||
Address: "StatsD Address",
|
||||
PushInterval: "StatsD PushInterval",
|
||||
},
|
||||
},
|
||||
Path: "web Path",
|
||||
Auth: &types.Auth{
|
||||
Basic: &types.Basic{
|
||||
UsersFile: "web Basic UsersFile",
|
||||
Users: types.Users{"web Basic Users 1", "web Basic Users 2", "web Basic Users 3"},
|
||||
},
|
||||
Digest: &types.Digest{
|
||||
UsersFile: "web Digest UsersFile",
|
||||
Users: types.Users{"web Digest Users 1", "web Digest Users 2", "web Digest Users 3"},
|
||||
},
|
||||
Forward: &types.Forward{
|
||||
Address: "web Address",
|
||||
TLS: &types.ClientTLS{
|
||||
CA: "web CA",
|
||||
Cert: "web Cert",
|
||||
Key: "web Key",
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
TrustForwardHeader: true,
|
||||
},
|
||||
},
|
||||
Debug: true,
|
||||
}
|
||||
config.Marathon = &marathon.Provider{
|
||||
BaseProvider: provider.BaseProvider{
|
||||
Watch: true,
|
||||
|
@ -324,8 +276,8 @@ func TestDo_globalConfiguration(t *testing.T) {
|
|||
Key: "marathon Key",
|
||||
InsecureSkipVerify: true,
|
||||
},
|
||||
DialerTimeout: flaeg.Duration(666 * time.Second),
|
||||
KeepAlive: flaeg.Duration(666 * time.Second),
|
||||
DialerTimeout: parse.Duration(666 * time.Second),
|
||||
KeepAlive: parse.Duration(666 * time.Second),
|
||||
ForceTaskHostname: true,
|
||||
Basic: &marathon.Basic{
|
||||
HTTPBasicAuthUser: "marathon HTTPBasicAuthUser",
|
||||
|
@ -433,8 +385,7 @@ func TestDo_globalConfiguration(t *testing.T) {
|
|||
DebugLogGeneratedTemplate: true,
|
||||
},
|
||||
Endpoint: "eureka Endpoint",
|
||||
Delay: flaeg.Duration(30 * time.Second),
|
||||
RefreshSeconds: flaeg.Duration(30 * time.Second),
|
||||
RefreshSeconds: parse.Duration(30 * time.Second),
|
||||
}
|
||||
config.ECS = &ecs.Provider{
|
||||
BaseProvider: provider.BaseProvider{
|
||||
|
@ -459,7 +410,6 @@ func TestDo_globalConfiguration(t *testing.T) {
|
|||
ExposedByDefault: true,
|
||||
RefreshSeconds: 666,
|
||||
Clusters: ecs.Clusters{"ecs Clusters 1", "ecs Clusters 2", "ecs Clusters 3"},
|
||||
Cluster: "ecs Cluster",
|
||||
AutoDiscoverClusters: true,
|
||||
Region: "ecs Region",
|
||||
AccessKeyID: "ecs AccessKeyID",
|
||||
|
|
|
@ -68,7 +68,6 @@ var _templatesConsul_catalogTmpl = []byte(`[backends]
|
|||
{{if $loadBalancer }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
@ -309,7 +308,6 @@ var _templatesDockerTmpl = []byte(`{{$backendServers := .Servers}}
|
|||
{{if $loadBalancer }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
@ -549,7 +547,6 @@ var _templatesEcsTmpl = []byte(`[backends]
|
|||
{{if $loadBalancer }}
|
||||
[backends."backend-{{ $serviceName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."backend-{{ $serviceName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
@ -827,7 +824,6 @@ var _templatesKubernetesTmpl = []byte(`[backends]
|
|||
|
||||
[backends."{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $backend.LoadBalancer.Method }}"
|
||||
sticky = {{ $backend.LoadBalancer.Sticky }}
|
||||
{{if $backend.LoadBalancer.Stickiness }}
|
||||
[backends."{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $backend.LoadBalancer.Stickiness.CookieName }}"
|
||||
|
@ -1042,7 +1038,6 @@ var _templatesKvTmpl = []byte(`[backends]
|
|||
{{if $loadBalancer }}
|
||||
[backends."{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
@ -1299,7 +1294,6 @@ var _templatesMarathonTmpl = []byte(`{{ $apps := .Applications }}
|
|||
{{if $loadBalancer }}
|
||||
[backends."{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
@ -1541,7 +1535,6 @@ var _templatesMesosTmpl = []byte(`[backends]
|
|||
{{if $loadBalancer }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
@ -1806,7 +1799,6 @@ var _templatesRancherTmpl = []byte(`{{ $backendServers := .Backends }}
|
|||
{{if $loadBalancer }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
|
|
@ -3,7 +3,7 @@ package cmd
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik-extra-service-fabric"
|
||||
"github.com/containous/traefik/api"
|
||||
"github.com/containous/traefik/configuration"
|
||||
|
@ -55,44 +55,16 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
|
|||
var defaultRest rest.Provider
|
||||
defaultRest.EntryPoint = configuration.DefaultInternalEntryPointName
|
||||
|
||||
// TODO: Deprecated - Web provider, use REST provider instead
|
||||
var defaultWeb configuration.WebCompatibility
|
||||
defaultWeb.Address = ":8080"
|
||||
defaultWeb.Statistics = &types.Statistics{
|
||||
RecentErrors: 10,
|
||||
}
|
||||
|
||||
// TODO: Deprecated - default Metrics
|
||||
defaultWeb.Metrics = &types.Metrics{
|
||||
Prometheus: &types.Prometheus{
|
||||
Buckets: types.Buckets{0.1, 0.3, 1.2, 5},
|
||||
EntryPoint: configuration.DefaultInternalEntryPointName,
|
||||
},
|
||||
Datadog: &types.Datadog{
|
||||
Address: "localhost:8125",
|
||||
PushInterval: "10s",
|
||||
},
|
||||
StatsD: &types.Statsd{
|
||||
Address: "localhost:8125",
|
||||
PushInterval: "10s",
|
||||
},
|
||||
InfluxDB: &types.InfluxDB{
|
||||
Address: "localhost:8089",
|
||||
Protocol: "udp",
|
||||
PushInterval: "10s",
|
||||
},
|
||||
}
|
||||
|
||||
// default Marathon
|
||||
var defaultMarathon marathon.Provider
|
||||
defaultMarathon.Watch = true
|
||||
defaultMarathon.Endpoint = "http://127.0.0.1:8080"
|
||||
defaultMarathon.ExposedByDefault = true
|
||||
defaultMarathon.Constraints = types.Constraints{}
|
||||
defaultMarathon.DialerTimeout = flaeg.Duration(5 * time.Second)
|
||||
defaultMarathon.ResponseHeaderTimeout = flaeg.Duration(60 * time.Second)
|
||||
defaultMarathon.TLSHandshakeTimeout = flaeg.Duration(5 * time.Second)
|
||||
defaultMarathon.KeepAlive = flaeg.Duration(10 * time.Second)
|
||||
defaultMarathon.DialerTimeout = parse.Duration(5 * time.Second)
|
||||
defaultMarathon.ResponseHeaderTimeout = parse.Duration(60 * time.Second)
|
||||
defaultMarathon.TLSHandshakeTimeout = parse.Duration(5 * time.Second)
|
||||
defaultMarathon.KeepAlive = parse.Duration(10 * time.Second)
|
||||
|
||||
// default Consul
|
||||
var defaultConsul consul.Provider
|
||||
|
@ -170,7 +142,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
|
|||
|
||||
// default Eureka
|
||||
var defaultEureka eureka.Provider
|
||||
defaultEureka.RefreshSeconds = flaeg.Duration(30 * time.Second)
|
||||
defaultEureka.RefreshSeconds = parse.Duration(30 * time.Second)
|
||||
|
||||
// default ServiceFabric
|
||||
var defaultServiceFabric servicefabric.Provider
|
||||
|
@ -203,17 +175,17 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
|
|||
|
||||
// default HealthCheckConfig
|
||||
healthCheck := configuration.HealthCheckConfig{
|
||||
Interval: flaeg.Duration(configuration.DefaultHealthCheckInterval),
|
||||
Interval: parse.Duration(configuration.DefaultHealthCheckInterval),
|
||||
}
|
||||
|
||||
// default RespondingTimeouts
|
||||
respondingTimeouts := configuration.RespondingTimeouts{
|
||||
IdleTimeout: flaeg.Duration(configuration.DefaultIdleTimeout),
|
||||
IdleTimeout: parse.Duration(configuration.DefaultIdleTimeout),
|
||||
}
|
||||
|
||||
// default ForwardingTimeouts
|
||||
forwardingTimeouts := configuration.ForwardingTimeouts{
|
||||
DialTimeout: flaeg.Duration(configuration.DefaultDialTimeout),
|
||||
DialTimeout: parse.Duration(configuration.DefaultDialTimeout),
|
||||
}
|
||||
|
||||
// default Tracing
|
||||
|
@ -236,7 +208,7 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
|
|||
|
||||
// default LifeCycle
|
||||
defaultLifeCycle := configuration.LifeCycle{
|
||||
GraceTimeOut: flaeg.Duration(configuration.DefaultGraceTimeout),
|
||||
GraceTimeOut: parse.Duration(configuration.DefaultGraceTimeout),
|
||||
}
|
||||
|
||||
// default ApiConfiguration
|
||||
|
@ -278,7 +250,6 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
|
|||
defaultConfiguration := configuration.GlobalConfiguration{
|
||||
Docker: &defaultDocker,
|
||||
File: &defaultFile,
|
||||
Web: &defaultWeb,
|
||||
Rest: &defaultRest,
|
||||
Marathon: &defaultMarathon,
|
||||
Consul: &defaultConsul,
|
||||
|
@ -315,19 +286,16 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
|
|||
func NewTraefikConfiguration() *TraefikConfiguration {
|
||||
return &TraefikConfiguration{
|
||||
GlobalConfiguration: configuration.GlobalConfiguration{
|
||||
AccessLogsFile: "",
|
||||
TraefikLogsFile: "",
|
||||
EntryPoints: map[string]*configuration.EntryPoint{},
|
||||
Constraints: types.Constraints{},
|
||||
DefaultEntryPoints: []string{"http"},
|
||||
ProvidersThrottleDuration: flaeg.Duration(2 * time.Second),
|
||||
ProvidersThrottleDuration: parse.Duration(2 * time.Second),
|
||||
MaxIdleConnsPerHost: 200,
|
||||
IdleTimeout: flaeg.Duration(0),
|
||||
HealthCheck: &configuration.HealthCheckConfig{
|
||||
Interval: flaeg.Duration(configuration.DefaultHealthCheckInterval),
|
||||
Interval: parse.Duration(configuration.DefaultHealthCheckInterval),
|
||||
},
|
||||
LifeCycle: &configuration.LifeCycle{
|
||||
GraceTimeOut: flaeg.Duration(configuration.DefaultGraceTimeout),
|
||||
GraceTimeOut: parse.Duration(configuration.DefaultGraceTimeout),
|
||||
},
|
||||
CheckNewVersion: true,
|
||||
},
|
||||
|
|
|
@ -66,8 +66,6 @@ func Do(globalConfiguration configuration.GlobalConfiguration) (*http.Response,
|
|||
client.Transport = tr
|
||||
}
|
||||
path := "/"
|
||||
if globalConfiguration.Web != nil {
|
||||
path = globalConfiguration.Web.Path
|
||||
}
|
||||
|
||||
return client.Head(protocol + "://" + pingEntryPoint.Address + path + "ping")
|
||||
}
|
||||
|
|
|
@ -158,9 +158,7 @@ func runCmd(globalConfiguration *configuration.GlobalConfiguration, configFile s
|
|||
|
||||
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
|
||||
|
||||
if globalConfiguration.AllowMinWeightZero {
|
||||
roundrobin.SetDefaultWeight(0)
|
||||
}
|
||||
|
||||
globalConfiguration.SetEffectiveConfiguration(configFile)
|
||||
globalConfiguration.ValidateConfiguration()
|
||||
|
@ -289,11 +287,7 @@ func configureLogging(globalConfiguration *configuration.GlobalConfiguration) {
|
|||
}
|
||||
log.SetLevel(level)
|
||||
|
||||
// configure log output file
|
||||
logFile := globalConfiguration.TraefikLogsFile
|
||||
if len(logFile) > 0 {
|
||||
log.Warn("top-level traefikLogsFile has been deprecated -- please use traefiklog.filepath")
|
||||
}
|
||||
var logFile string
|
||||
if globalConfiguration.TraefikLog != nil && len(globalConfiguration.TraefikLog.FilePath) > 0 {
|
||||
logFile = globalConfiguration.TraefikLog.FilePath
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik-extra-service-fabric"
|
||||
"github.com/containous/traefik/acme"
|
||||
"github.com/containous/traefik/api"
|
||||
|
@ -59,13 +59,10 @@ const (
|
|||
// It's populated from the traefik configuration file passed as an argument to the binary.
|
||||
type GlobalConfiguration struct {
|
||||
LifeCycle *LifeCycle `description:"Timeouts influencing the server life cycle" export:"true"`
|
||||
GraceTimeOut flaeg.Duration `short:"g" description:"(Deprecated) Duration to give active requests a chance to finish before Traefik stops" export:"true"` // Deprecated
|
||||
Debug bool `short:"d" description:"Enable debug mode" export:"true"`
|
||||
CheckNewVersion bool `description:"Periodically check if a new version has been released" export:"true"`
|
||||
SendAnonymousUsage bool `description:"send periodically anonymous usage statistics" export:"true"`
|
||||
AccessLogsFile string `description:"(Deprecated) Access logs file" export:"true"` // Deprecated
|
||||
AccessLog *types.AccessLog `description:"Access log settings" export:"true"`
|
||||
TraefikLogsFile string `description:"(Deprecated) Traefik logs file. Stdout is used when omitted or empty" export:"true"` // Deprecated
|
||||
TraefikLog *types.TraefikLog `description:"Traefik log settings" export:"true"`
|
||||
Tracing *tracing.Tracing `description:"OpenTracing configuration" export:"true"`
|
||||
LogLevel string `short:"l" description:"Log level" export:"true"`
|
||||
|
@ -74,17 +71,14 @@ type GlobalConfiguration struct {
|
|||
Constraints types.Constraints `description:"Filter services by constraint, matching with service tags" export:"true"`
|
||||
ACME *acme.ACME `description:"Enable ACME (Let's Encrypt): automatic SSL" export:"true"`
|
||||
DefaultEntryPoints DefaultEntryPoints `description:"Entrypoints to be used by frontends that do not specify any entrypoint" export:"true"`
|
||||
ProvidersThrottleDuration flaeg.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time." export:"true"`
|
||||
ProvidersThrottleDuration parse.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time." export:"true"`
|
||||
MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" export:"true"`
|
||||
IdleTimeout flaeg.Duration `description:"(Deprecated) maximum amount of time an idle (keep-alive) connection will remain idle before closing itself." export:"true"` // Deprecated
|
||||
InsecureSkipVerify bool `description:"Disable SSL certificate verification" export:"true"`
|
||||
RootCAs tls.RootCAs `description:"Add cert file for self-signed certificate"`
|
||||
Retry *Retry `description:"Enable retry sending request if network error" export:"true"`
|
||||
HealthCheck *HealthCheckConfig `description:"Health check parameters" export:"true"`
|
||||
RespondingTimeouts *RespondingTimeouts `description:"Timeouts for incoming requests to the Traefik instance" export:"true"`
|
||||
ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers" export:"true"`
|
||||
AllowMinWeightZero bool `description:"Allow weight to take 0 as minimum real value." export:"true"` // Deprecated
|
||||
Web *WebCompatibility `description:"(Deprecated) Enable Web backend with default settings" export:"true"` // Deprecated
|
||||
Docker *docker.Provider `description:"Enable Docker backend with default settings" export:"true"`
|
||||
File *file.Provider `description:"Enable File backend with default settings" export:"true"`
|
||||
Marathon *marathon.Provider `description:"Enable Marathon backend with default settings" export:"true"`
|
||||
|
@ -107,66 +101,6 @@ type GlobalConfiguration struct {
|
|||
HostResolver *HostResolverConfig `description:"Enable CNAME Flattening" export:"true"`
|
||||
}
|
||||
|
||||
// WebCompatibility is a configuration to handle compatibility with deprecated web provider options
|
||||
type WebCompatibility struct {
|
||||
Address string `description:"(Deprecated) Web administration port" export:"true"`
|
||||
CertFile string `description:"(Deprecated) SSL certificate" export:"true"`
|
||||
KeyFile string `description:"(Deprecated) SSL certificate" export:"true"`
|
||||
ReadOnly bool `description:"(Deprecated) Enable read only API" export:"true"`
|
||||
Statistics *types.Statistics `description:"(Deprecated) Enable more detailed statistics" export:"true"`
|
||||
Metrics *types.Metrics `description:"(Deprecated) Enable a metrics exporter" export:"true"`
|
||||
Path string `description:"(Deprecated) Root path for dashboard and API" export:"true"`
|
||||
Auth *types.Auth `export:"true"`
|
||||
Debug bool `export:"true"`
|
||||
}
|
||||
|
||||
func (gc *GlobalConfiguration) handleWebDeprecation() {
|
||||
if gc.Web != nil {
|
||||
log.Warn("web provider configuration is deprecated, you should use these options : api, rest provider, ping and metrics")
|
||||
|
||||
if gc.API != nil || gc.Metrics != nil || gc.Ping != nil || gc.Rest != nil {
|
||||
log.Warn("web option is ignored if you use it with one of these options : api, rest provider, ping or metrics")
|
||||
return
|
||||
}
|
||||
gc.EntryPoints[DefaultInternalEntryPointName] = &EntryPoint{
|
||||
Address: gc.Web.Address,
|
||||
Auth: gc.Web.Auth,
|
||||
}
|
||||
if gc.Web.CertFile != "" {
|
||||
gc.EntryPoints[DefaultInternalEntryPointName].TLS = &tls.TLS{
|
||||
Certificates: []tls.Certificate{
|
||||
{
|
||||
CertFile: tls.FileOrContent(gc.Web.CertFile),
|
||||
KeyFile: tls.FileOrContent(gc.Web.KeyFile),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
if gc.API == nil {
|
||||
gc.API = &api.Handler{
|
||||
EntryPoint: DefaultInternalEntryPointName,
|
||||
Statistics: gc.Web.Statistics,
|
||||
Dashboard: true,
|
||||
}
|
||||
}
|
||||
|
||||
if gc.Ping == nil {
|
||||
gc.Ping = &ping.Handler{
|
||||
EntryPoint: DefaultInternalEntryPointName,
|
||||
}
|
||||
}
|
||||
|
||||
if gc.Metrics == nil {
|
||||
gc.Metrics = gc.Web.Metrics
|
||||
}
|
||||
|
||||
if !gc.Debug {
|
||||
gc.Debug = gc.Web.Debug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SetEffectiveConfiguration adds missing configuration parameters derived from existing ones.
|
||||
// It also takes care of maintaining backwards compatibility.
|
||||
func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
|
||||
|
@ -178,8 +112,6 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
|
|||
gc.DefaultEntryPoints = []string{"http"}
|
||||
}
|
||||
|
||||
gc.handleWebDeprecation()
|
||||
|
||||
if (gc.API != nil && gc.API.EntryPoint == DefaultInternalEntryPointName) ||
|
||||
(gc.Ping != nil && gc.Ping.EntryPoint == DefaultInternalEntryPointName) ||
|
||||
(gc.Metrics != nil && gc.Metrics.Prometheus != nil && gc.Metrics.Prometheus.EntryPoint == DefaultInternalEntryPointName) ||
|
||||
|
@ -213,72 +145,7 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
|
|||
gc.LifeCycle = &LifeCycle{}
|
||||
}
|
||||
|
||||
// Prefer legacy grace timeout parameter for backwards compatibility reasons.
|
||||
if gc.GraceTimeOut > 0 {
|
||||
log.Warn("top-level grace period configuration has been deprecated -- please use lifecycle grace period")
|
||||
gc.LifeCycle.GraceTimeOut = gc.GraceTimeOut
|
||||
}
|
||||
|
||||
if gc.Docker != nil {
|
||||
if len(gc.Docker.Filename) != 0 && gc.Docker.TemplateVersion != 2 {
|
||||
log.Warn("Template version 1 is deprecated, please use version 2, see TemplateVersion.")
|
||||
gc.Docker.TemplateVersion = 1
|
||||
} else {
|
||||
gc.Docker.TemplateVersion = 2
|
||||
}
|
||||
}
|
||||
|
||||
if gc.Marathon != nil {
|
||||
if len(gc.Marathon.Filename) != 0 && gc.Marathon.TemplateVersion != 2 {
|
||||
log.Warn("Template version 1 is deprecated, please use version 2, see TemplateVersion.")
|
||||
gc.Marathon.TemplateVersion = 1
|
||||
} else {
|
||||
gc.Marathon.TemplateVersion = 2
|
||||
}
|
||||
}
|
||||
|
||||
if gc.Mesos != nil {
|
||||
if len(gc.Mesos.Filename) != 0 && gc.Mesos.TemplateVersion != 2 {
|
||||
log.Warn("Template version 1 is deprecated, please use version 2, see TemplateVersion.")
|
||||
gc.Mesos.TemplateVersion = 1
|
||||
} else {
|
||||
gc.Mesos.TemplateVersion = 2
|
||||
}
|
||||
}
|
||||
|
||||
if gc.Eureka != nil {
|
||||
if gc.Eureka.Delay != 0 {
|
||||
log.Warn("Delay has been deprecated -- please use RefreshSeconds")
|
||||
gc.Eureka.RefreshSeconds = gc.Eureka.Delay
|
||||
}
|
||||
}
|
||||
|
||||
if gc.ECS != nil {
|
||||
if len(gc.ECS.Filename) != 0 && gc.ECS.TemplateVersion != 2 {
|
||||
log.Warn("Template version 1 is deprecated, please use version 2, see TemplateVersion.")
|
||||
gc.ECS.TemplateVersion = 1
|
||||
} else {
|
||||
gc.ECS.TemplateVersion = 2
|
||||
}
|
||||
}
|
||||
|
||||
if gc.ConsulCatalog != nil {
|
||||
if len(gc.ConsulCatalog.Filename) != 0 && gc.ConsulCatalog.TemplateVersion != 2 {
|
||||
log.Warn("Template version 1 is deprecated, please use version 2, see TemplateVersion.")
|
||||
gc.ConsulCatalog.TemplateVersion = 1
|
||||
} else {
|
||||
gc.ConsulCatalog.TemplateVersion = 2
|
||||
}
|
||||
}
|
||||
|
||||
if gc.Rancher != nil {
|
||||
if len(gc.Rancher.Filename) != 0 && gc.Rancher.TemplateVersion != 2 {
|
||||
log.Warn("Template version 1 is deprecated, please use version 2, see TemplateVersion.")
|
||||
gc.Rancher.TemplateVersion = 1
|
||||
} else {
|
||||
gc.Rancher.TemplateVersion = 2
|
||||
}
|
||||
|
||||
// Ensure backwards compatibility for now
|
||||
if len(gc.Rancher.AccessKey) > 0 ||
|
||||
len(gc.Rancher.Endpoint) > 0 ||
|
||||
|
@ -304,10 +171,6 @@ func (gc *GlobalConfiguration) SetEffectiveConfiguration(configFile string) {
|
|||
gc.API.Debug = gc.Debug
|
||||
}
|
||||
|
||||
if gc.Web != nil && (gc.Web.Path == "" || !strings.HasSuffix(gc.Web.Path, "/")) {
|
||||
gc.Web.Path += "/"
|
||||
}
|
||||
|
||||
if gc.File != nil {
|
||||
gc.File.TraefikFile = configFile
|
||||
}
|
||||
|
@ -371,12 +234,6 @@ func (gc *GlobalConfiguration) initACMEProvider() {
|
|||
gc.ACME.HTTPChallenge = nil
|
||||
}
|
||||
|
||||
// TODO: to remove in the future
|
||||
if len(gc.ACME.StorageFile) > 0 && len(gc.ACME.Storage) == 0 {
|
||||
log.Warn("ACME.StorageFile is deprecated, use ACME.Storage instead")
|
||||
gc.ACME.Storage = gc.ACME.StorageFile
|
||||
}
|
||||
|
||||
if len(gc.ACME.DNSProvider) > 0 {
|
||||
log.Warn("ACME.DNSProvider is deprecated, use ACME.DNSChallenge instead")
|
||||
gc.ACME.DNSChallenge = &acmeprovider.DNSChallenge{Provider: gc.ACME.DNSProvider, DelayBeforeCheck: gc.ACME.DelayDontCheckDNS}
|
||||
|
@ -498,27 +355,27 @@ type Retry struct {
|
|||
|
||||
// HealthCheckConfig contains health check configuration parameters.
|
||||
type HealthCheckConfig struct {
|
||||
Interval flaeg.Duration `description:"Default periodicity of enabled health checks" export:"true"`
|
||||
Interval parse.Duration `description:"Default periodicity of enabled health checks" export:"true"`
|
||||
}
|
||||
|
||||
// RespondingTimeouts contains timeout configurations for incoming requests to the Traefik instance.
|
||||
type RespondingTimeouts struct {
|
||||
ReadTimeout flaeg.Duration `description:"ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set" export:"true"`
|
||||
WriteTimeout flaeg.Duration `description:"WriteTimeout is the maximum duration before timing out writes of the response. If zero, no timeout is set" export:"true"`
|
||||
IdleTimeout flaeg.Duration `description:"IdleTimeout is the maximum amount duration an idle (keep-alive) connection will remain idle before closing itself. Defaults to 180 seconds. If zero, no timeout is set" export:"true"`
|
||||
ReadTimeout parse.Duration `description:"ReadTimeout is the maximum duration for reading the entire request, including the body. If zero, no timeout is set" export:"true"`
|
||||
WriteTimeout parse.Duration `description:"WriteTimeout is the maximum duration before timing out writes of the response. If zero, no timeout is set" export:"true"`
|
||||
IdleTimeout parse.Duration `description:"IdleTimeout is the maximum amount duration an idle (keep-alive) connection will remain idle before closing itself. Defaults to 180 seconds. If zero, no timeout is set" export:"true"`
|
||||
}
|
||||
|
||||
// ForwardingTimeouts contains timeout configurations for forwarding requests to the backend servers.
|
||||
type ForwardingTimeouts struct {
|
||||
DialTimeout flaeg.Duration `description:"The amount of time to wait until a connection to a backend server can be established. Defaults to 30 seconds. If zero, no timeout exists" export:"true"`
|
||||
ResponseHeaderTimeout flaeg.Duration `description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists" export:"true"`
|
||||
DialTimeout parse.Duration `description:"The amount of time to wait until a connection to a backend server can be established. Defaults to 30 seconds. If zero, no timeout exists" export:"true"`
|
||||
ResponseHeaderTimeout parse.Duration `description:"The amount of time to wait for a server's response headers after fully writing the request (including its body, if any). If zero, no timeout exists" export:"true"`
|
||||
}
|
||||
|
||||
// LifeCycle contains configurations relevant to the lifecycle (such as the
|
||||
// shutdown phase) of Traefik.
|
||||
type LifeCycle struct {
|
||||
RequestAcceptGraceTimeout flaeg.Duration `description:"Duration to keep accepting requests before Traefik initiates the graceful shutdown procedure"`
|
||||
GraceTimeOut flaeg.Duration `description:"Duration to give active requests a chance to finish before Traefik stops"`
|
||||
RequestAcceptGraceTimeout parse.Duration `description:"Duration to keep accepting requests before Traefik initiates the graceful shutdown procedure"`
|
||||
GraceTimeOut parse.Duration `description:"Duration to give active requests a chance to finish before Traefik stops"`
|
||||
}
|
||||
|
||||
// HostResolverConfig contain configuration for CNAME Flattening
|
||||
|
|
|
@ -2,9 +2,7 @@ package configuration
|
|||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/traefik/middlewares/tracing"
|
||||
"github.com/containous/traefik/middlewares/tracing/jaeger"
|
||||
"github.com/containous/traefik/middlewares/tracing/zipkin"
|
||||
|
@ -15,53 +13,6 @@ import (
|
|||
|
||||
const defaultConfigFile = "traefik.toml"
|
||||
|
||||
func TestSetEffectiveConfigurationGraceTimeout(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
legacyGraceTimeout time.Duration
|
||||
lifeCycleGraceTimeout time.Duration
|
||||
wantGraceTimeout time.Duration
|
||||
}{
|
||||
{
|
||||
desc: "legacy grace timeout given only",
|
||||
legacyGraceTimeout: 5 * time.Second,
|
||||
wantGraceTimeout: 5 * time.Second,
|
||||
},
|
||||
{
|
||||
desc: "legacy and life cycle grace timeouts given",
|
||||
legacyGraceTimeout: 5 * time.Second,
|
||||
lifeCycleGraceTimeout: 12 * time.Second,
|
||||
wantGraceTimeout: 5 * time.Second,
|
||||
},
|
||||
{
|
||||
desc: "legacy grace timeout omitted",
|
||||
legacyGraceTimeout: 0,
|
||||
lifeCycleGraceTimeout: 12 * time.Second,
|
||||
wantGraceTimeout: 12 * time.Second,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
gc := &GlobalConfiguration{
|
||||
GraceTimeOut: flaeg.Duration(test.legacyGraceTimeout),
|
||||
}
|
||||
if test.lifeCycleGraceTimeout > 0 {
|
||||
gc.LifeCycle = &LifeCycle{
|
||||
GraceTimeOut: flaeg.Duration(test.lifeCycleGraceTimeout),
|
||||
}
|
||||
}
|
||||
|
||||
gc.SetEffectiveConfiguration(defaultConfigFile)
|
||||
|
||||
assert.Equal(t, test.wantGraceTimeout, time.Duration(gc.LifeCycle.GraceTimeOut))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetEffectiveConfigurationFileProviderFilename(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
|
|
|
@ -60,13 +60,8 @@ func NewInternalRouterAggregator(globalConfiguration configuration.GlobalConfigu
|
|||
}
|
||||
|
||||
realRouterWithMiddleware := WithMiddleware{router: &routerWithPrefixAndMiddleware, routerMiddlewares: serverMiddlewares}
|
||||
if globalConfiguration.Web != nil && globalConfiguration.Web.Path != "" {
|
||||
router.AddRouter(&WithPrefix{PathPrefix: globalConfiguration.Web.Path, Router: &routerWithPrefix})
|
||||
router.AddRouter(&WithPrefix{PathPrefix: globalConfiguration.Web.Path, Router: &realRouterWithMiddleware})
|
||||
} else {
|
||||
router.AddRouter(&routerWithPrefix)
|
||||
router.AddRouter(&realRouterWithMiddleware)
|
||||
}
|
||||
|
||||
return &router
|
||||
}
|
||||
|
|
|
@ -17,85 +17,6 @@ import (
|
|||
"github.com/urfave/negroni"
|
||||
)
|
||||
|
||||
func TestNewInternalRouterAggregatorWithWebPath(t *testing.T) {
|
||||
currentConfiguration := &safe.Safe{}
|
||||
currentConfiguration.Set(types.Configurations{})
|
||||
|
||||
globalConfiguration := configuration.GlobalConfiguration{
|
||||
Web: &configuration.WebCompatibility{
|
||||
Path: "/prefix",
|
||||
},
|
||||
API: &api.Handler{
|
||||
EntryPoint: "traefik",
|
||||
CurrentConfigurations: currentConfiguration,
|
||||
},
|
||||
Ping: &ping.Handler{
|
||||
EntryPoint: "traefik",
|
||||
},
|
||||
ACME: &acme.ACME{
|
||||
HTTPChallenge: &acmeprovider.HTTPChallenge{
|
||||
EntryPoint: "traefik",
|
||||
},
|
||||
},
|
||||
EntryPoints: configuration.EntryPoints{
|
||||
"traefik": &configuration.EntryPoint{},
|
||||
},
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
testedURL string
|
||||
expectedStatusCode int
|
||||
}{
|
||||
{
|
||||
desc: "Ping without prefix",
|
||||
testedURL: "/ping",
|
||||
expectedStatusCode: 502,
|
||||
},
|
||||
{
|
||||
desc: "Ping with prefix",
|
||||
testedURL: "/prefix/ping",
|
||||
expectedStatusCode: 200,
|
||||
},
|
||||
{
|
||||
desc: "acme without prefix",
|
||||
testedURL: "/.well-known/acme-challenge/token",
|
||||
expectedStatusCode: 404,
|
||||
},
|
||||
{
|
||||
desc: "api without prefix",
|
||||
testedURL: "/api",
|
||||
expectedStatusCode: 502,
|
||||
},
|
||||
{
|
||||
desc: "api with prefix",
|
||||
testedURL: "/prefix/api",
|
||||
expectedStatusCode: 200,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
router := NewInternalRouterAggregator(globalConfiguration, "traefik")
|
||||
|
||||
internalMuxRouter := mux.NewRouter()
|
||||
router.AddRoutes(internalMuxRouter)
|
||||
internalMuxRouter.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusBadGateway)
|
||||
})
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(http.MethodGet, test.testedURL, nil)
|
||||
internalMuxRouter.ServeHTTP(recorder, request)
|
||||
|
||||
assert.Equal(t, test.expectedStatusCode, recorder.Code)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewInternalRouterAggregatorWithAuth(t *testing.T) {
|
||||
currentConfiguration := &safe.Safe{}
|
||||
currentConfiguration.Set(types.Configurations{})
|
||||
|
@ -173,86 +94,6 @@ func TestNewInternalRouterAggregatorWithAuth(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestNewInternalRouterAggregatorWithAuthAndPrefix(t *testing.T) {
|
||||
currentConfiguration := &safe.Safe{}
|
||||
currentConfiguration.Set(types.Configurations{})
|
||||
|
||||
globalConfiguration := configuration.GlobalConfiguration{
|
||||
Web: &configuration.WebCompatibility{
|
||||
Path: "/prefix",
|
||||
},
|
||||
API: &api.Handler{
|
||||
EntryPoint: "traefik",
|
||||
CurrentConfigurations: currentConfiguration,
|
||||
},
|
||||
Ping: &ping.Handler{
|
||||
EntryPoint: "traefik",
|
||||
},
|
||||
ACME: &acme.ACME{
|
||||
HTTPChallenge: &acmeprovider.HTTPChallenge{
|
||||
EntryPoint: "traefik",
|
||||
},
|
||||
},
|
||||
EntryPoints: configuration.EntryPoints{
|
||||
"traefik": &configuration.EntryPoint{
|
||||
Auth: &types.Auth{
|
||||
Basic: &types.Basic{
|
||||
Users: types.Users{"test:test"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
testedURL string
|
||||
expectedStatusCode int
|
||||
}{
|
||||
{
|
||||
desc: "Ping without prefix",
|
||||
testedURL: "/ping",
|
||||
expectedStatusCode: 502,
|
||||
},
|
||||
{
|
||||
desc: "Ping without auth and with prefix",
|
||||
testedURL: "/prefix/ping",
|
||||
expectedStatusCode: 200,
|
||||
},
|
||||
{
|
||||
desc: "acme without auth and without prefix",
|
||||
testedURL: "/.well-known/acme-challenge/token",
|
||||
expectedStatusCode: 404,
|
||||
},
|
||||
{
|
||||
desc: "api with auth and prefix",
|
||||
testedURL: "/prefix/api",
|
||||
expectedStatusCode: 401,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
router := NewInternalRouterAggregator(globalConfiguration, "traefik")
|
||||
|
||||
internalMuxRouter := mux.NewRouter()
|
||||
router.AddRoutes(internalMuxRouter)
|
||||
internalMuxRouter.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusBadGateway)
|
||||
})
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(http.MethodGet, test.testedURL, nil)
|
||||
internalMuxRouter.ServeHTTP(recorder, request)
|
||||
|
||||
assert.Equal(t, test.expectedStatusCode, recorder.Code)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type MockInternalRouterFunc func(systemRouter *mux.Router)
|
||||
|
||||
func (m MockInternalRouterFunc) AddRoutes(systemRouter *mux.Router) {
|
||||
|
|
|
@ -449,15 +449,6 @@ If not, a new backend will be assigned.
|
|||
# cookieName = "my_cookie"
|
||||
```
|
||||
|
||||
The deprecated way:
|
||||
|
||||
```toml
|
||||
[backends]
|
||||
[backends.backend1]
|
||||
[backends.backend1.loadbalancer]
|
||||
sticky = true
|
||||
```
|
||||
|
||||
#### Health Check
|
||||
|
||||
A health check can be configured in order to remove a backend from LB rotation as long as it keeps returning HTTP status codes other than `2xx` or `3xx` to HTTP GET requests periodically carried out by Traefik.
|
||||
|
|
|
@ -114,7 +114,6 @@ Additional settings can be defined using Consul Catalog tags.
|
|||
| `<prefix>.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm. |
|
||||
| `<prefix>.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions. |
|
||||
| `<prefix>.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions. |
|
||||
| `<prefix>.backend.loadbalancer.sticky=true` | Enables backend sticky sessions. (DEPRECATED) |
|
||||
| `<prefix>.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
|
||||
| `<prefix>.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
|
||||
| `<prefix>.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
|
||||
|
|
|
@ -231,7 +231,6 @@ Labels can be used on containers to override default behavior.
|
|||
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
|
||||
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
|
||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
|
||||
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
|
||||
| `traefik.backend.loadbalancer.swarm=true` | Uses Swarm's inbuilt load balancer (only relevant under Swarm Mode). |
|
||||
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
|
||||
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
|
||||
|
|
|
@ -12,12 +12,6 @@ Træfik can be configured to use Amazon ECS as a provider.
|
|||
# Enable ECS Provider.
|
||||
[ecs]
|
||||
|
||||
# ECS Cluster Name.
|
||||
#
|
||||
# DEPRECATED - Please use `clusters`.
|
||||
#
|
||||
cluster = "default"
|
||||
|
||||
# ECS Clusters Name.
|
||||
#
|
||||
# Optional
|
||||
|
@ -159,7 +153,6 @@ Labels can be used on task containers to override default behaviour:
|
|||
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
|
||||
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
|
||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie manually name for sticky sessions |
|
||||
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
|
||||
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
|
||||
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
|
||||
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
|
||||
|
|
|
@ -250,7 +250,6 @@ The following annotations are applicable on the Service object associated with a
|
|||
|
||||
| Annotation | Description |
|
||||
|--------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `traefik.backend.loadbalancer.sticky: "true"` | Enable backend sticky sessions (DEPRECATED). |
|
||||
| `traefik.ingress.kubernetes.io/affinity: "true"` | Enable backend sticky sessions. |
|
||||
| `traefik.ingress.kubernetes.io/circuit-breaker-expression: <expression>` | Set the circuit breaker expression for the backend. |
|
||||
| `traefik.ingress.kubernetes.io/load-balancer-method: drr` | Override the default `wrr` load balancer algorithm. |
|
||||
|
|
|
@ -217,7 +217,6 @@ The following labels can be defined on Marathon applications. They adjust the be
|
|||
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
|
||||
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
|
||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
|
||||
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
|
||||
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
|
||||
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
|
||||
| `traefik.frontend.auth.basic=EXPR` | Sets basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
|
||||
|
|
|
@ -161,7 +161,6 @@ Labels can be used on task containers to override default behavior:
|
|||
| `traefik.backend.loadbalancer.method=drr` | Overrides the default `wrr` load balancer algorithm |
|
||||
| `traefik.backend.loadbalancer.stickiness=true` | Enables backend sticky sessions |
|
||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Sets the cookie name manually for sticky sessions |
|
||||
| `traefik.backend.loadbalancer.sticky=true` | Enables backend sticky sessions (DEPRECATED) |
|
||||
| `traefik.backend.maxconn.amount=10` | Sets a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
|
||||
| `traefik.backend.maxconn.extractorfunc=client.ip` | Sets the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
|
||||
| `traefik.frontend.auth.basic=EXPR` | Sets the basic authentication to this frontend in CSV format: `User:Hash,User:Hash` (DEPRECATED). |
|
||||
|
|
|
@ -109,7 +109,6 @@ Labels, set through extensions or the property manager, can be used on services
|
|||
| `traefik.backend.loadbalancer.method=drr` | Override the default `wrr` load balancer algorithm |
|
||||
| `traefik.backend.loadbalancer.stickiness=true` | Enable backend sticky sessions |
|
||||
| `traefik.backend.loadbalancer.stickiness.cookieName=NAME` | Manually set the cookie name for sticky sessions |
|
||||
| `traefik.backend.loadbalancer.sticky=true` | Enable backend sticky sessions (DEPRECATED) |
|
||||
| `traefik.backend.maxconn.amount=10` | Set a maximum number of connections to the backend.<br>Must be used in conjunction with the below label to take effect. |
|
||||
| `traefik.backend.maxconn.extractorfunc=client.ip` | Set the function to be used against the request to determine what to limit maximum connections to the backend by.<br>Must be used in conjunction with the above label to take effect. |
|
||||
| `traefik.backend.weight=10` | Assign this weight to the container |
|
||||
|
|
|
@ -1,503 +0,0 @@
|
|||
# Web Provider
|
||||
|
||||
!!! danger "DEPRECATED"
|
||||
The web provider is deprecated, please use the [api](/configuration/api.md), the [ping](/configuration/ping.md), the [metrics](/configuration/metrics) and the [rest](/configuration/backends/rest.md) provider.
|
||||
|
||||
Træfik can be configured:
|
||||
|
||||
- using a RESTful api.
|
||||
- to use a monitoring system (like Prometheus, DataDog or StatD, ...).
|
||||
- to expose a Web Dashboard.
|
||||
|
||||
## Configuration
|
||||
|
||||
```toml
|
||||
# Enable Web Provider.
|
||||
[web]
|
||||
|
||||
# Web administration port.
|
||||
#
|
||||
# Required
|
||||
# Default: ":8080"
|
||||
#
|
||||
address = ":8080"
|
||||
|
||||
# SSL certificate and key used.
|
||||
#
|
||||
# Optional
|
||||
#
|
||||
# certFile = "traefik.crt"
|
||||
# keyFile = "traefik.key"
|
||||
|
||||
# Set REST API to read-only mode.
|
||||
#
|
||||
# Optional
|
||||
# Default: false
|
||||
#
|
||||
readOnly = true
|
||||
|
||||
# Set the root path for webui and API
|
||||
#
|
||||
# Deprecated
|
||||
# Optional
|
||||
#
|
||||
# path = "/mypath"
|
||||
#
|
||||
```
|
||||
|
||||
## Web UI
|
||||
|
||||
![Web UI Providers](/img/web.frontend.png)
|
||||
|
||||
![Web UI Health](/img/traefik-health.png)
|
||||
|
||||
### Authentication
|
||||
|
||||
!!! note
|
||||
The `/ping` path of the API is excluded from authentication (since 1.4).
|
||||
|
||||
#### Basic Authentication
|
||||
|
||||
Passwords can be encoded in MD5, SHA1 and BCrypt: you can use `htpasswd` to generate those ones.
|
||||
|
||||
Users can be specified directly in the TOML file, or indirectly by referencing an external file;
|
||||
if both are provided, the two are merged, with external file contents having precedence.
|
||||
|
||||
```toml
|
||||
[web]
|
||||
# ...
|
||||
|
||||
# To enable basic auth on the webui with 2 user/pass: test:test and test2:test2
|
||||
[web.auth.basic]
|
||||
users = ["test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"]
|
||||
usersFile = "/path/to/.htpasswd"
|
||||
|
||||
# ...
|
||||
```
|
||||
|
||||
#### Digest Authentication
|
||||
|
||||
You can use `htdigest` to generate those ones.
|
||||
|
||||
Users can be specified directly in the TOML file, or indirectly by referencing an external file;
|
||||
if both are provided, the two are merged, with external file contents having precedence
|
||||
|
||||
```toml
|
||||
[web]
|
||||
# ...
|
||||
|
||||
# To enable digest auth on the webui with 2 user/realm/pass: test:traefik:test and test2:traefik:test2
|
||||
[web.auth.digest]
|
||||
users = ["test:traefik:a2688e031edb4be6a3797f3882655c05", "test2:traefik:518845800f9e2bfb1f1f740ec24f074e"]
|
||||
usersFile = "/path/to/.htdigest"
|
||||
|
||||
# ...
|
||||
```
|
||||
|
||||
|
||||
## Metrics
|
||||
|
||||
You can enable Træfik to export internal metrics to different monitoring systems.
|
||||
|
||||
### Prometheus
|
||||
|
||||
```toml
|
||||
[web]
|
||||
# ...
|
||||
|
||||
# To enable Traefik to export internal metrics to Prometheus
|
||||
[web.metrics.prometheus]
|
||||
|
||||
# Buckets for latency metrics
|
||||
#
|
||||
# Optional
|
||||
# Default: [0.1, 0.3, 1.2, 5]
|
||||
buckets=[0.1,0.3,1.2,5.0]
|
||||
|
||||
# ...
|
||||
```
|
||||
|
||||
### DataDog
|
||||
|
||||
```toml
|
||||
[web]
|
||||
# ...
|
||||
|
||||
# DataDog metrics exporter type
|
||||
[web.metrics.datadog]
|
||||
|
||||
# DataDog's address.
|
||||
#
|
||||
# Required
|
||||
# Default: "localhost:8125"
|
||||
#
|
||||
address = "localhost:8125"
|
||||
|
||||
# DataDog push interval
|
||||
#
|
||||
# Optional
|
||||
# Default: "10s"
|
||||
#
|
||||
pushinterval = "10s"
|
||||
|
||||
# ...
|
||||
```
|
||||
|
||||
### StatsD
|
||||
|
||||
```toml
|
||||
[web]
|
||||
# ...
|
||||
|
||||
# StatsD metrics exporter type
|
||||
[web.metrics.statsd]
|
||||
|
||||
# StatD's address.
|
||||
#
|
||||
# Required
|
||||
# Default: "localhost:8125"
|
||||
#
|
||||
address = "localhost:8125"
|
||||
|
||||
# StatD push interval
|
||||
#
|
||||
# Optional
|
||||
# Default: "10s"
|
||||
#
|
||||
pushinterval = "10s"
|
||||
|
||||
# ...
|
||||
```
|
||||
|
||||
### InfluxDB
|
||||
|
||||
```toml
|
||||
[web]
|
||||
# ...
|
||||
|
||||
# InfluxDB metrics exporter type
|
||||
[web.metrics.influxdb]
|
||||
|
||||
# InfluxDB's address.
|
||||
#
|
||||
# Required
|
||||
# Default: "localhost:8089"
|
||||
#
|
||||
address = "localhost:8089"
|
||||
|
||||
# InfluxDB's address protocol (udp or http)
|
||||
#
|
||||
# Required
|
||||
# Default: "udp"
|
||||
#
|
||||
protocol = "udp"
|
||||
|
||||
# InfluxDB push interval
|
||||
#
|
||||
# Optional
|
||||
# Default: "10s"
|
||||
#
|
||||
pushinterval = "10s"
|
||||
|
||||
# InfluxDB database used when protocol is http
|
||||
#
|
||||
# Optional
|
||||
# Default: ""
|
||||
#
|
||||
database = ""
|
||||
|
||||
# InfluxDB retention policy used when protocol is http
|
||||
#
|
||||
# Optional
|
||||
# Default: ""
|
||||
#
|
||||
retentionpolicy = ""
|
||||
|
||||
# ...
|
||||
```
|
||||
|
||||
## Statistics
|
||||
|
||||
```toml
|
||||
[web]
|
||||
# ...
|
||||
|
||||
# Enable more detailed statistics.
|
||||
[web.statistics]
|
||||
|
||||
# Number of recent errors logged.
|
||||
#
|
||||
# Default: 10
|
||||
#
|
||||
recentErrors = 10
|
||||
|
||||
# ...
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
| Path | Method | Description |
|
||||
|-----------------------------------------------------------------|:-------------:|----------------------------------------------------------------------------------------------------|
|
||||
| `/` | `GET` | Provides a simple HTML frontend of Træfik |
|
||||
| `/ping` | `GET`, `HEAD` | A simple endpoint to check for Træfik process liveness. Return a code `200` with the content: `OK` |
|
||||
| `/health` | `GET` | JSON health metrics |
|
||||
| `/api` | `GET` | Configuration for all providers |
|
||||
| `/api/providers` | `GET` | Providers |
|
||||
| `/api/providers/{provider}` | `GET`, `PUT` | Get or update provider |
|
||||
| `/api/providers/{provider}/backends` | `GET` | List backends |
|
||||
| `/api/providers/{provider}/backends/{backend}` | `GET` | Get backend |
|
||||
| `/api/providers/{provider}/backends/{backend}/servers` | `GET` | List servers in backend |
|
||||
| `/api/providers/{provider}/backends/{backend}/servers/{server}` | `GET` | Get a server in a backend |
|
||||
| `/api/providers/{provider}/frontends` | `GET` | List frontends |
|
||||
| `/api/providers/{provider}/frontends/{frontend}` | `GET` | Get a frontend |
|
||||
| `/api/providers/{provider}/frontends/{frontend}/routes` | `GET` | List routes in a frontend |
|
||||
| `/api/providers/{provider}/frontends/{frontend}/routes/{route}` | `GET` | Get a route in a frontend |
|
||||
| `/metrics` | `GET` | Export internal metrics |
|
||||
|
||||
### Example
|
||||
|
||||
#### Ping
|
||||
|
||||
```shell
|
||||
curl -sv "http://localhost:8080/ping"
|
||||
```
|
||||
```shell
|
||||
* Trying ::1...
|
||||
* Connected to localhost (::1) port 8080 (\#0)
|
||||
> GET /ping HTTP/1.1
|
||||
> Host: localhost:8080
|
||||
> User-Agent: curl/7.43.0
|
||||
> Accept: */*
|
||||
>
|
||||
< HTTP/1.1 200 OK
|
||||
< Date: Thu, 25 Aug 2016 01:35:36 GMT
|
||||
< Content-Length: 2
|
||||
< Content-Type: text/plain; charset=utf-8
|
||||
<
|
||||
* Connection \#0 to host localhost left intact
|
||||
OK
|
||||
```
|
||||
|
||||
#### Health
|
||||
|
||||
```shell
|
||||
curl -s "http://localhost:8080/health" | jq .
|
||||
```
|
||||
```json
|
||||
{
|
||||
// Træfik PID
|
||||
"pid": 2458,
|
||||
// Træfik server uptime (formated time)
|
||||
"uptime": "39m6.885931127s",
|
||||
// Træfik server uptime in seconds
|
||||
"uptime_sec": 2346.885931127,
|
||||
// current server date
|
||||
"time": "2015-10-07 18:32:24.362238909 +0200 CEST",
|
||||
// current server date in seconds
|
||||
"unixtime": 1444235544,
|
||||
// count HTTP response status code in realtime
|
||||
"status_code_count": {
|
||||
"502": 1
|
||||
},
|
||||
// count HTTP response status code since Træfik started
|
||||
"total_status_code_count": {
|
||||
"200": 7,
|
||||
"404": 21,
|
||||
"502": 13
|
||||
},
|
||||
// count HTTP response
|
||||
"count": 1,
|
||||
// count HTTP response
|
||||
"total_count": 41,
|
||||
// sum of all response time (formated time)
|
||||
"total_response_time": "35.456865605s",
|
||||
// sum of all response time in seconds
|
||||
"total_response_time_sec": 35.456865605,
|
||||
// average response time (formated time)
|
||||
"average_response_time": "864.8016ms",
|
||||
// average response time in seconds
|
||||
"average_response_time_sec": 0.8648016000000001,
|
||||
|
||||
// request statistics [requires --web.statistics to be set]
|
||||
// ten most recent requests with 4xx and 5xx status codes
|
||||
"recent_errors": [
|
||||
{
|
||||
// status code
|
||||
"status_code": 500,
|
||||
// description of status code
|
||||
"status": "Internal Server Error",
|
||||
// request HTTP method
|
||||
"method": "GET",
|
||||
// request host name
|
||||
"host": "localhost",
|
||||
// request path
|
||||
"path": "/path",
|
||||
// RFC 3339 formatted date/time
|
||||
"time": "2016-10-21T16:59:15.418495872-07:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Provider configurations
|
||||
|
||||
```shell
|
||||
curl -s "http://localhost:8080/api" | jq .
|
||||
```
|
||||
```json
|
||||
{
|
||||
"file": {
|
||||
"frontends": {
|
||||
"frontend2": {
|
||||
"routes": {
|
||||
"test_2": {
|
||||
"rule": "Path:/test"
|
||||
}
|
||||
},
|
||||
"backend": "backend1"
|
||||
},
|
||||
"frontend1": {
|
||||
"routes": {
|
||||
"test_1": {
|
||||
"rule": "Host:test.localhost"
|
||||
}
|
||||
},
|
||||
"backend": "backend2"
|
||||
}
|
||||
},
|
||||
"backends": {
|
||||
"backend2": {
|
||||
"loadBalancer": {
|
||||
"method": "drr"
|
||||
},
|
||||
"servers": {
|
||||
"server2": {
|
||||
"weight": 2,
|
||||
"URL": "http://172.17.0.5:80"
|
||||
},
|
||||
"server1": {
|
||||
"weight": 1,
|
||||
"url": "http://172.17.0.4:80"
|
||||
}
|
||||
}
|
||||
},
|
||||
"backend1": {
|
||||
"loadBalancer": {
|
||||
"method": "wrr"
|
||||
},
|
||||
"circuitBreaker": {
|
||||
"expression": "NetworkErrorRatio() > 0.5"
|
||||
},
|
||||
"servers": {
|
||||
"server2": {
|
||||
"weight": 1,
|
||||
"url": "http://172.17.0.3:80"
|
||||
},
|
||||
"server1": {
|
||||
"weight": 10,
|
||||
"url": "http://172.17.0.2:80"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Deprecation compatibility
|
||||
|
||||
#### Address
|
||||
|
||||
As the web provider is deprecated, you can handle the `Address` option like this:
|
||||
|
||||
```toml
|
||||
defaultEntryPoints = ["http"]
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.foo]
|
||||
address = ":8082"
|
||||
|
||||
[entryPoints.bar]
|
||||
address = ":8083"
|
||||
|
||||
[ping]
|
||||
entryPoint = "foo"
|
||||
|
||||
[api]
|
||||
entryPoint = "bar"
|
||||
```
|
||||
|
||||
In the above example, you would access a regular path, administration panel, and health-check as follows:
|
||||
|
||||
* Regular path: `http://hostname:80/path`
|
||||
* Admin Panel: `http://hostname:8083/`
|
||||
* Ping URL: `http://hostname:8082/ping`
|
||||
|
||||
In the above example, it is _very_ important to create a named dedicated entry point, and do **not** include it in `defaultEntryPoints`.
|
||||
Otherwise, you are likely to expose _all_ services via that entry point.
|
||||
|
||||
#### Path
|
||||
|
||||
As the web provider is deprecated, you can handle the `Path` option like this:
|
||||
|
||||
```toml
|
||||
defaultEntryPoints = ["http"]
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.foo]
|
||||
address = ":8080"
|
||||
|
||||
[entryPoints.bar]
|
||||
address = ":8081"
|
||||
|
||||
# Activate API and Dashboard
|
||||
[api]
|
||||
entryPoint = "bar"
|
||||
dashboard = true
|
||||
|
||||
[file]
|
||||
[backends]
|
||||
[backends.backend1]
|
||||
[backends.backend1.servers.server1]
|
||||
url = "http://127.0.0.1:8081"
|
||||
|
||||
[frontends]
|
||||
[frontends.frontend1]
|
||||
entryPoints = ["foo"]
|
||||
backend = "backend1"
|
||||
[frontends.frontend1.routes.test_1]
|
||||
rule = "PathPrefixStrip:/yourprefix;PathPrefix:/yourprefix"
|
||||
```
|
||||
|
||||
#### Authentication
|
||||
|
||||
As the web provider is deprecated, you can handle the `auth` option like this:
|
||||
|
||||
```toml
|
||||
defaultEntryPoints = ["http"]
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.http]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.foo]
|
||||
address=":8080"
|
||||
[entryPoints.foo.auth]
|
||||
[entryPoints.foo.auth.basic]
|
||||
users = [
|
||||
"test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/",
|
||||
"test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0",
|
||||
]
|
||||
|
||||
[api]
|
||||
entrypoint="foo"
|
||||
```
|
||||
|
||||
For more information, see [entry points](/configuration/entrypoints/) .
|
|
@ -3,19 +3,6 @@
|
|||
## Main Section
|
||||
|
||||
```toml
|
||||
# DEPRECATED - for general usage instruction see [lifeCycle.graceTimeOut].
|
||||
#
|
||||
# If both the deprecated option and the new one are given, the deprecated one
|
||||
# takes precedence.
|
||||
# A value of zero is equivalent to omitting the parameter, causing
|
||||
# [lifeCycle.graceTimeOut] to be effective. Pass zero to the new option in
|
||||
# order to disable the grace period.
|
||||
#
|
||||
# Optional
|
||||
# Default: "0s"
|
||||
#
|
||||
# graceTimeOut = "10s"
|
||||
|
||||
# Enable debug mode.
|
||||
# This will install HTTP handlers to expose Go expvars under /debug/vars and
|
||||
# pprof profiling data under /debug/pprof/.
|
||||
|
@ -69,22 +56,8 @@
|
|||
# Default: ["http"]
|
||||
#
|
||||
# defaultEntryPoints = ["http", "https"]
|
||||
|
||||
# Allow the use of 0 as server weight.
|
||||
# - false: a weight 0 means internally a weight of 1.
|
||||
# - true: a weight 0 means internally a weight of 0 (a server with a weight of 0 is removed from the available servers).
|
||||
#
|
||||
# Optional
|
||||
# Default: false
|
||||
#
|
||||
# AllowMinWeightZero = true
|
||||
```
|
||||
|
||||
- `graceTimeOut`: Duration to give active requests a chance to finish before Traefik stops.
|
||||
Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).
|
||||
If no units are provided, the value is parsed assuming seconds.
|
||||
**Note:** in this time frame no new requests are accepted.
|
||||
|
||||
- `providersThrottleDuration`: Providers throttle duration: minimum duration in seconds between 2 events from providers before applying a new configuration.
|
||||
It avoids unnecessary reloads if multiples events are sent in a short amount of time.
|
||||
Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).
|
||||
|
@ -393,29 +366,6 @@ If zero, no timeout exists.
|
|||
Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).
|
||||
If no units are provided, the value is parsed assuming seconds.
|
||||
|
||||
|
||||
### Idle Timeout (deprecated)
|
||||
|
||||
Use [respondingTimeouts](/configuration/commons/#responding-timeouts) instead of `idleTimeout`.
|
||||
In the case both settings are configured, the deprecated option will be overwritten.
|
||||
|
||||
`idleTimeout` is the maximum amount of time an idle (keep-alive) connection will remain idle before closing itself.
|
||||
This is set to enforce closing of stale client connections.
|
||||
|
||||
Can be provided in a format supported by [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration) or as raw values (digits).
|
||||
If no units are provided, the value is parsed assuming seconds.
|
||||
|
||||
```toml
|
||||
# idleTimeout
|
||||
#
|
||||
# DEPRECATED - see [respondingTimeouts] section.
|
||||
#
|
||||
# Optional
|
||||
# Default: "180s"
|
||||
#
|
||||
idleTimeout = "360s"
|
||||
```
|
||||
|
||||
## Host Resolver
|
||||
|
||||
`hostResolver` are used for request host matching process.
|
||||
|
@ -454,7 +404,7 @@ Refer to [ACME configuration](/configuration/acme) for more information.
|
|||
!!! warning
|
||||
For advanced users only.
|
||||
|
||||
Supported by all providers except: File Provider, Web Provider and DynamoDB Provider.
|
||||
Supported by all providers except: File Provider, Rest Provider and DynamoDB Provider.
|
||||
|
||||
```toml
|
||||
[provider_name]
|
||||
|
|
|
@ -237,10 +237,10 @@ If you need to add or remove TLS certificates while Traefik is started, Dynamic
|
|||
TLS Mutual Authentication can be `optional` or not.
|
||||
If it's `optional`, Træfik will authorize connection with certificates not signed by a specified Certificate Authority (CA).
|
||||
Otherwise, Træfik will only accept clients that present a certificate signed by a specified Certificate Authority (CA).
|
||||
`ClientCAFiles` can be configured with multiple `CA:s` in the same file or use multiple files containing one or several `CA:s`.
|
||||
`ClientCA.files` can be configured with multiple `CA:s` in the same file or use multiple files containing one or several `CA:s`.
|
||||
The `CA:s` has to be in PEM format.
|
||||
|
||||
By default, `ClientCAFiles` is not optional, all clients will be required to present a valid cert.
|
||||
By default, `ClientCA.files` is not optional, all clients will be required to present a valid cert.
|
||||
The requirement will apply to all server certs in the entrypoint.
|
||||
|
||||
In the example below both `snitest.com` and `snitest.org` will require client certs
|
||||
|
@ -261,10 +261,6 @@ In the example below both `snitest.com` and `snitest.org` will require client ce
|
|||
keyFile = "integration/fixtures/https/snitest.org.key"
|
||||
```
|
||||
|
||||
!!! note
|
||||
The deprecated argument `ClientCAFiles` allows adding Client CA files which are mandatory.
|
||||
If this parameter exists, the new ones are not checked.
|
||||
|
||||
## Authentication
|
||||
|
||||
### Basic Authentication
|
||||
|
|
|
@ -72,23 +72,6 @@ To write JSON format logs, specify `json` as the format:
|
|||
format = "json"
|
||||
```
|
||||
|
||||
|
||||
Deprecated way (before 1.4):
|
||||
|
||||
!!! danger "DEPRECATED"
|
||||
`traefikLogsFile` is deprecated, use [traefikLog](/configuration/logs/#traefik-logs) instead.
|
||||
|
||||
```toml
|
||||
# Traefik logs file
|
||||
# If not defined, logs to stdout
|
||||
#
|
||||
# DEPRECATED - see [traefikLog] lower down
|
||||
# In case both traefikLogsFile and traefikLog.filePath are specified, the latter will take precedence.
|
||||
# Optional
|
||||
#
|
||||
traefikLogsFile = "log/traefik.log"
|
||||
```
|
||||
|
||||
To customize the log level:
|
||||
```toml
|
||||
# Log level
|
||||
|
@ -253,19 +236,6 @@ Overhead
|
|||
RetryAttempts
|
||||
```
|
||||
|
||||
Deprecated way (before 1.4):
|
||||
|
||||
!!! danger "DEPRECATED"
|
||||
`accessLogsFile` is deprecated, use [accessLog](/configuration/logs/#access-logs) instead.
|
||||
|
||||
```toml
|
||||
# Access logs file
|
||||
#
|
||||
# DEPRECATED - see [accessLog]
|
||||
#
|
||||
accessLogsFile = "log/access.log"
|
||||
```
|
||||
|
||||
## Log Rotation
|
||||
|
||||
Traefik will close and reopen its log files, assuming they're configured, on receipt of a USR1 signal.
|
||||
|
|
|
@ -121,7 +121,6 @@ docker-machine ssh manager "docker service create \
|
|||
--name whoami1 \
|
||||
--label traefik.port=80 \
|
||||
--network traefik-net \
|
||||
--label traefik.backend.loadbalancer.sticky=true \
|
||||
emilevauge/whoami"
|
||||
```
|
||||
|
||||
|
|
|
@ -252,63 +252,6 @@ func (s *SimpleSuite) TestNoAuthOnPing(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestWebCompatibilityWithoutPath(c *check.C) {
|
||||
|
||||
s.createComposeProject(c, "base")
|
||||
s.composeProject.Start(c)
|
||||
|
||||
cmd, output := s.traefikCmd("--defaultEntryPoints=http", "--entryPoints=Name:http Address::8000", "--web", "--debug", "--docker")
|
||||
defer output(c)
|
||||
|
||||
err := cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
// TODO validate : run on 80
|
||||
// Expected a 404 as we did not configure anything
|
||||
err = try.GetRequest("http://127.0.0.1:8000/test", 1*time.Second, try.StatusCodeIs(http.StatusNotFound))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8080/api", 1*time.Second, try.StatusCodeIs(http.StatusOK))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8080/api/providers", 1*time.Second, try.BodyContains("PathPrefix"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK))
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestWebCompatibilityWithPath(c *check.C) {
|
||||
|
||||
s.createComposeProject(c, "base")
|
||||
s.composeProject.Start(c)
|
||||
|
||||
cmd, output := s.traefikCmd("--defaultEntryPoints=http", "--entryPoints=Name:http Address::8000", "--web.path=/test", "--debug", "--docker")
|
||||
defer output(c)
|
||||
|
||||
err := cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
// TODO validate : run on 80
|
||||
// Expected a 404 as we did not configure anything
|
||||
err = try.GetRequest("http://127.0.0.1:8000/notfound", 1*time.Second, try.StatusCodeIs(http.StatusNotFound))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8080/test/api", 1*time.Second, try.StatusCodeIs(http.StatusOK))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8080/test/ping", 1*time.Second, try.StatusCodeIs(http.StatusOK))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8080/test/api/providers", 1*time.Second, try.BodyContains("PathPrefix"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8000/whoami", 1*time.Second, try.StatusCodeIs(http.StatusOK))
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestDefaultEntrypointHTTP(c *check.C) {
|
||||
|
||||
s.createComposeProject(c, "base")
|
||||
|
@ -352,7 +295,7 @@ func (s *SimpleSuite) TestMetricsPrometheusDefaultEntrypoint(c *check.C) {
|
|||
s.createComposeProject(c, "base")
|
||||
s.composeProject.Start(c)
|
||||
|
||||
cmd, output := s.traefikCmd("--defaultEntryPoints=http", "--entryPoints=Name:http Address::8000", "--web", "--web.metrics.prometheus.buckets=0.1,0.3,1.2,5.0", "--docker", "--debug")
|
||||
cmd, output := s.traefikCmd("--defaultEntryPoints=http", "--entryPoints=Name:http Address::8000", "--api", "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0", "--docker", "--debug")
|
||||
defer output(c)
|
||||
|
||||
err := cmd.Start()
|
||||
|
|
|
@ -46,12 +46,9 @@ func (s *DynamoDBSuite) SetUpSuite(c *check.C) {
|
|||
}
|
||||
var sess *session.Session
|
||||
err := try.Do(60*time.Second, func() error {
|
||||
_, err := session.NewSession(config)
|
||||
if err != nil {
|
||||
var err error
|
||||
sess, err = session.NewSession(config)
|
||||
return err
|
||||
}
|
||||
sess = session.New(config)
|
||||
return nil
|
||||
})
|
||||
c.Assert(err, checker.IsNil)
|
||||
svc := dynamodb.New(sess)
|
||||
|
|
|
@ -61,9 +61,6 @@ func (s *HealthCheckSuite) TestSimpleConfiguration(c *check.C) {
|
|||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// Waiting for Traefik healthcheck
|
||||
try.Sleep(2 * time.Second)
|
||||
|
||||
// Verify no backend service is available due to failing health checks
|
||||
err = try.Request(frontendHealthReq, 3*time.Second, try.StatusCodeIs(http.StatusServiceUnavailable))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
@ -139,15 +136,25 @@ func (s *HealthCheckSuite) doTestMultipleEntrypoints(c *check.C, fixture string)
|
|||
err = try.Request(frontendHealthReq, 500*time.Millisecond, try.StatusCodeIs(http.StatusOK))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Set one whoami health to 500
|
||||
// Set the both whoami health to 500
|
||||
client := &http.Client{}
|
||||
statusInternalServerErrorReq, err := http.NewRequest(http.MethodPost, "http://"+s.whoami1IP+"/health", bytes.NewBuffer([]byte("500")))
|
||||
whoamiHosts := []string{s.whoami1IP, s.whoami2IP}
|
||||
for _, whoami := range whoamiHosts {
|
||||
statusInternalServerErrorReq, err := http.NewRequest(http.MethodPost, "http://"+whoami+"/health", bytes.NewBuffer([]byte("500")))
|
||||
c.Assert(err, checker.IsNil)
|
||||
_, err = client.Do(statusInternalServerErrorReq)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
// Waiting for Traefik healthcheck
|
||||
try.Sleep(2 * time.Second)
|
||||
// Verify no backend service is available due to failing health checks
|
||||
err = try.Request(frontendHealthReq, 3*time.Second, try.StatusCodeIs(http.StatusServiceUnavailable))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// reactivate the whoami2
|
||||
statusInternalServerOkReq, err := http.NewRequest(http.MethodPost, "http://"+s.whoami2IP+"/health", bytes.NewBuffer([]byte("200")))
|
||||
c.Assert(err, checker.IsNil)
|
||||
_, err = client.Do(statusInternalServerOkReq)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
frontend1Req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
@ -159,11 +166,11 @@ func (s *HealthCheckSuite) doTestMultipleEntrypoints(c *check.C, fixture string)
|
|||
|
||||
// Check if whoami1 never responds
|
||||
err = try.Request(frontend2Req, 2*time.Second, try.BodyContains(s.whoami1IP))
|
||||
c.Assert(err, checker.Not(checker.IsNil))
|
||||
c.Assert(err, checker.NotNil)
|
||||
|
||||
// Check if whoami1 never responds
|
||||
err = try.Request(frontend1Req, 2*time.Second, try.BodyContains(s.whoami1IP))
|
||||
c.Assert(err, checker.Not(checker.IsNil))
|
||||
c.Assert(err, checker.NotNil)
|
||||
}
|
||||
|
||||
func (s *HealthCheckSuite) TestPortOverload(c *check.C) {
|
||||
|
@ -204,9 +211,6 @@ func (s *HealthCheckSuite) TestPortOverload(c *check.C) {
|
|||
_, err = client.Do(statusInternalServerErrorReq)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Waiting for Traefik healthcheck
|
||||
try.Sleep(2 * time.Second)
|
||||
|
||||
// Verify no backend service is available due to failing health checks
|
||||
err = try.Request(frontendHealthReq, 3*time.Second, try.StatusCodeIs(http.StatusServiceUnavailable))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
|
|
@ -118,7 +118,7 @@ func (s *MarathonSuite15) TestConfigurationUpdate(c *check.C) {
|
|||
CPU(0.1).
|
||||
Memory(32).
|
||||
EmptyNetworks().
|
||||
AddLabel(label.GetServiceLabel(label.TraefikFrontendRule, "app"), "PathPrefix:/app")
|
||||
AddLabel(label.Prefix+"app"+label.TraefikFrontendRule, "PathPrefix:/app")
|
||||
app.Container.
|
||||
Expose(80).
|
||||
Docker.
|
||||
|
|
|
@ -126,7 +126,7 @@ func (s *MarathonSuite) TestConfigurationUpdate(c *check.C) {
|
|||
Name("/whoami").
|
||||
CPU(0.1).
|
||||
Memory(32).
|
||||
AddLabel(label.GetServiceLabel(label.TraefikFrontendRule, "app"), "PathPrefix:/app")
|
||||
AddLabel(label.Prefix+"app"+label.TraefikFrontendRule, "PathPrefix:/app")
|
||||
app.Container.Docker.Bridged().
|
||||
Expose(80).
|
||||
Container("emilevauge/whoami")
|
||||
|
|
|
@ -89,7 +89,6 @@ pages:
|
|||
- 'Ping': 'configuration/ping.md'
|
||||
- 'Metrics': 'configuration/metrics.md'
|
||||
- 'Tracing': 'configuration/tracing.md'
|
||||
- 'Web (Deprecated)': 'configuration/backends/web.md'
|
||||
- User Guides:
|
||||
- 'Configuration Examples': 'user-guide/examples.md'
|
||||
- 'Swarm Mode Cluster': 'user-guide/swarm-mode.md'
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/BurntSushi/ty/fun"
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/rules"
|
||||
"github.com/containous/traefik/safe"
|
||||
|
@ -72,7 +72,7 @@ type Certificate struct {
|
|||
// DNSChallenge contains DNS challenge Configuration
|
||||
type DNSChallenge struct {
|
||||
Provider string `description:"Use a DNS-01 based challenge provider rather than HTTPS."`
|
||||
DelayBeforeCheck flaeg.Duration `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."`
|
||||
DelayBeforeCheck parse.Duration `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers."`
|
||||
}
|
||||
|
||||
// HTTPChallenge contains HTTP challenge Configuration
|
||||
|
@ -368,7 +368,7 @@ func (p *Provider) resolveCertificate(domain types.Domain, domainFromConfigurati
|
|||
return certificate, nil
|
||||
}
|
||||
|
||||
func dnsOverrideDelay(delay flaeg.Duration) error {
|
||||
func dnsOverrideDelay(delay parse.Duration) error {
|
||||
if delay == 0 {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ func (p *Provider) buildConfiguration(catalog []catalogUpdate) *types.Configurat
|
|||
"getServiceBackendName": getServiceBackendName,
|
||||
"getBackendAddress": getBackendAddress,
|
||||
"getServerName": getServerName,
|
||||
"getCircuitBreaker": getCircuitBreaker,
|
||||
"getLoadBalancer": getLoadBalancer,
|
||||
"getCircuitBreaker": label.GetCircuitBreaker,
|
||||
"getLoadBalancer": label.GetLoadBalancer,
|
||||
"getMaxConn": label.GetMaxConn,
|
||||
"getHealthCheck": label.GetHealthCheck,
|
||||
"getBuffering": label.GetBuffering,
|
||||
|
@ -134,32 +134,6 @@ func (p *Provider) setupFrontEndRuleTemplate() {
|
|||
|
||||
// Specific functions
|
||||
|
||||
// Only for compatibility
|
||||
// Deprecated
|
||||
func getLoadBalancer(labels map[string]string) *types.LoadBalancer {
|
||||
if v, ok := labels[label.TraefikBackendLoadBalancer]; ok {
|
||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancer, label.TraefikBackendLoadBalancerMethod)
|
||||
if !label.Has(labels, label.TraefikBackendLoadBalancerMethod) {
|
||||
labels[label.TraefikBackendLoadBalancerMethod] = v
|
||||
}
|
||||
}
|
||||
|
||||
return label.GetLoadBalancer(labels)
|
||||
}
|
||||
|
||||
// Only for compatibility
|
||||
// Deprecated
|
||||
func getCircuitBreaker(labels map[string]string) *types.CircuitBreaker {
|
||||
if v, ok := labels[label.TraefikBackendCircuitBreaker]; ok {
|
||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendCircuitBreaker, label.TraefikBackendCircuitBreakerExpression)
|
||||
if !label.Has(labels, label.TraefikBackendCircuitBreakerExpression) {
|
||||
labels[label.TraefikBackendCircuitBreakerExpression] = v
|
||||
}
|
||||
}
|
||||
|
||||
return label.GetCircuitBreaker(labels)
|
||||
}
|
||||
|
||||
func getServiceBackendName(service *serviceUpdate) string {
|
||||
return strings.ToLower(service.ServiceName)
|
||||
}
|
||||
|
@ -195,18 +169,7 @@ func getServerName(node *api.ServiceEntry, index int) string {
|
|||
|
||||
func (p *Provider) getWeight(tags []string) int {
|
||||
labels := tagsToNeutralLabels(tags, p.Prefix)
|
||||
weight := label.GetIntValue(labels, p.getPrefixedName(label.SuffixWeight), label.DefaultWeight)
|
||||
|
||||
// Deprecated
|
||||
deprecatedWeightTag := "backend." + label.SuffixWeight
|
||||
if p.hasAttribute(deprecatedWeightTag, tags) {
|
||||
log.Warnf("Deprecated configuration found: %s. Please use %s.",
|
||||
p.getPrefixedName(deprecatedWeightTag), p.getPrefixedName(label.SuffixWeight))
|
||||
|
||||
weight = label.GetIntValue(labels, p.getPrefixedName(deprecatedWeightTag), label.DefaultWeight)
|
||||
}
|
||||
|
||||
return weight
|
||||
return label.GetIntValue(labels, p.getPrefixedName(label.SuffixWeight), label.DefaultWeight)
|
||||
}
|
||||
|
||||
// Base functions
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"text/template"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/hashicorp/consul/api"
|
||||
|
@ -68,7 +68,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
Port: 80,
|
||||
Tags: []string{
|
||||
"random.foo=bar",
|
||||
label.Prefix + "backend.weight=42", // Deprecated label
|
||||
label.TraefikWeight + "=42",
|
||||
label.TraefikFrontendPassHostHeader + "=true",
|
||||
label.TraefikProtocol + "=https",
|
||||
},
|
||||
|
@ -102,7 +102,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
expectedBackends: map[string]*types.Backend{
|
||||
"backend-test": {
|
||||
Servers: map[string]types.Server{
|
||||
"test-0-us4-27hAOu2ARV7nNrmv6GoKlcA": {
|
||||
"test-0-ecTTsmX1vPktQQrl53WhNDy-HEg": {
|
||||
URL: "https://127.0.0.1:80",
|
||||
Weight: 42,
|
||||
},
|
||||
|
@ -139,7 +139,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
Port: 80,
|
||||
Tags: []string{
|
||||
"random.foo=bar",
|
||||
label.Prefix + "backend.weight=42", // Deprecated label
|
||||
label.TraefikWeight + "=42",
|
||||
label.TraefikFrontendPassHostHeader + "=true",
|
||||
label.TraefikProtocol + "=https",
|
||||
},
|
||||
|
@ -173,14 +173,15 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
expectedBackends: map[string]*types.Backend{
|
||||
"backend-test": {
|
||||
Servers: map[string]types.Server{
|
||||
"test-0-us4-27hAOu2ARV7nNrmv6GoKlcA": {
|
||||
"test-0-ecTTsmX1vPktQQrl53WhNDy-HEg": {
|
||||
URL: "https://127.0.0.1:80",
|
||||
Weight: 42,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
},
|
||||
{
|
||||
desc: "Should build config with a digest auth",
|
||||
nodes: []catalogUpdate{
|
||||
{
|
||||
|
@ -201,7 +202,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
Port: 80,
|
||||
Tags: []string{
|
||||
"random.foo=bar",
|
||||
label.Prefix + "backend.weight=42", // Deprecated label
|
||||
label.TraefikWeight + "=42",
|
||||
label.TraefikFrontendPassHostHeader + "=true",
|
||||
label.TraefikProtocol + "=https",
|
||||
},
|
||||
|
@ -237,7 +238,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
expectedBackends: map[string]*types.Backend{
|
||||
"backend-test": {
|
||||
Servers: map[string]types.Server{
|
||||
"test-0-us4-27hAOu2ARV7nNrmv6GoKlcA": {
|
||||
"test-0-ecTTsmX1vPktQQrl53WhNDy-HEg": {
|
||||
URL: "https://127.0.0.1:80",
|
||||
Weight: 42,
|
||||
},
|
||||
|
@ -271,7 +272,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
Port: 80,
|
||||
Tags: []string{
|
||||
"random.foo=bar",
|
||||
label.Prefix + "backend.weight=42", // Deprecated label
|
||||
label.TraefikWeight + "=42",
|
||||
label.TraefikFrontendPassHostHeader + "=true",
|
||||
label.TraefikProtocol + "=https",
|
||||
},
|
||||
|
@ -313,7 +314,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
expectedBackends: map[string]*types.Backend{
|
||||
"backend-test": {
|
||||
Servers: map[string]types.Server{
|
||||
"test-0-us4-27hAOu2ARV7nNrmv6GoKlcA": {
|
||||
"test-0-ecTTsmX1vPktQQrl53WhNDy-HEg": {
|
||||
URL: "https://127.0.0.1:80",
|
||||
Weight: 42,
|
||||
},
|
||||
|
@ -338,7 +339,6 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendHealthCheckHostname + "=foo.com",
|
||||
label.TraefikBackendHealthCheckHeaders + "=Foo:bar || Bar:foo",
|
||||
label.TraefikBackendLoadBalancerMethod + "=drr",
|
||||
label.TraefikBackendLoadBalancerSticky + "=true",
|
||||
label.TraefikBackendLoadBalancerStickiness + "=true",
|
||||
label.TraefikBackendLoadBalancerStickinessCookieName + "=chocolate",
|
||||
label.TraefikBackendMaxConnAmount + "=666",
|
||||
|
@ -537,12 +537,12 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
ExtractorFunc: "client.ip",
|
||||
RateSet: map[string]*types.Rate{
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
|
@ -573,7 +573,6 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "chocolate",
|
||||
},
|
||||
|
@ -626,7 +625,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
Port: 80,
|
||||
Tags: []string{
|
||||
"random.foo=bar",
|
||||
label.Prefix + "backend.weight=42", // Deprecated label
|
||||
label.TraefikWeight + "=42",
|
||||
label.TraefikFrontendPassHostHeader + "=true",
|
||||
label.TraefikProtocol + "=https",
|
||||
},
|
||||
|
@ -643,7 +642,7 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
Port: 80,
|
||||
Tags: []string{
|
||||
"random.foo=bar",
|
||||
label.Prefix + "backend.weight=42", // Deprecated label
|
||||
label.TraefikWeight + "=42",
|
||||
label.TraefikFrontendPassHostHeader + "=true",
|
||||
label.TraefikProtocol + "=https",
|
||||
},
|
||||
|
@ -677,11 +676,11 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
expectedBackends: map[string]*types.Backend{
|
||||
"backend-test": {
|
||||
Servers: map[string]types.Server{
|
||||
"test-0-us4-27hAOu2ARV7nNrmv6GoKlcA": {
|
||||
"test-0-ecTTsmX1vPktQQrl53WhNDy-HEg": {
|
||||
URL: "https://127.0.0.1:80",
|
||||
Weight: 42,
|
||||
},
|
||||
"test-1-Gh4zrXo5flAAz1A8LAEHm1-TSnE": {
|
||||
"test-1-9tI2Ud3Vkl4T4B6bAIWV0vFjEIg": {
|
||||
URL: "https://[::1]:80",
|
||||
Weight: 42,
|
||||
},
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/types"
|
||||
docker "github.com/docker/docker/api/types"
|
||||
|
@ -377,7 +377,6 @@ func TestDockerBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendHealthCheckHostname: "foo.com",
|
||||
label.TraefikBackendHealthCheckHeaders: "Foo:bar || Bar:foo",
|
||||
label.TraefikBackendLoadBalancerMethod: "drr",
|
||||
label.TraefikBackendLoadBalancerSticky: "true",
|
||||
label.TraefikBackendLoadBalancerStickiness: "true",
|
||||
label.TraefikBackendLoadBalancerStickinessCookieName: "chocolate",
|
||||
label.TraefikBackendMaxConnAmount: "666",
|
||||
|
@ -545,12 +544,12 @@ func TestDockerBuildConfiguration(t *testing.T) {
|
|||
ExtractorFunc: "client.ip",
|
||||
RateSet: map[string]*types.Rate{
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
|
@ -577,7 +576,6 @@ func TestDockerBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "chocolate",
|
||||
},
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/types"
|
||||
docker "github.com/docker/docker/api/types"
|
||||
|
@ -322,7 +322,6 @@ func TestSwarmBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendHealthCheckHostname: "foo.com",
|
||||
label.TraefikBackendHealthCheckHeaders: "Foo:bar || Bar:foo",
|
||||
label.TraefikBackendLoadBalancerMethod: "drr",
|
||||
label.TraefikBackendLoadBalancerSticky: "true",
|
||||
label.TraefikBackendLoadBalancerStickiness: "true",
|
||||
label.TraefikBackendLoadBalancerStickinessCookieName: "chocolate",
|
||||
label.TraefikBackendMaxConnAmount: "666",
|
||||
|
@ -487,12 +486,12 @@ func TestSwarmBuildConfiguration(t *testing.T) {
|
|||
ExtractorFunc: "client.ip",
|
||||
RateSet: map[string]*types.Rate{
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
|
@ -518,7 +517,6 @@ func TestSwarmBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "chocolate",
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/types"
|
||||
docker "github.com/docker/docker/api/types"
|
||||
|
@ -437,12 +437,12 @@ func TestSegmentBuildConfiguration(t *testing.T) {
|
|||
ExtractorFunc: "client.ip",
|
||||
RateSet: map[string]*types.Rate{
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -342,7 +342,6 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendHealthCheckHostname: aws.String("foo.com"),
|
||||
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
|
||||
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
|
||||
label.TraefikBackendLoadBalancerSticky: aws.String("true"),
|
||||
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
|
||||
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
|
||||
label.TraefikBackendMaxConnAmount: aws.String("666"),
|
||||
|
@ -440,7 +439,6 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "chocolate",
|
||||
},
|
||||
|
@ -558,12 +556,12 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
RateLimit: &types.RateLimit{
|
||||
RateSet: map[string]*types.Rate{
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
|
@ -602,7 +600,6 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendHealthCheckHostname: aws.String("foo.com"),
|
||||
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
|
||||
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
|
||||
label.TraefikBackendLoadBalancerSticky: aws.String("true"),
|
||||
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
|
||||
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
|
||||
label.TraefikBackendMaxConnAmount: aws.String("666"),
|
||||
|
@ -689,7 +686,6 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendHealthCheckHostname: aws.String("bar.com"),
|
||||
label.TraefikBackendHealthCheckHeaders: aws.String("Foo:bar || Bar:foo"),
|
||||
label.TraefikBackendLoadBalancerMethod: aws.String("drr"),
|
||||
label.TraefikBackendLoadBalancerSticky: aws.String("true"),
|
||||
label.TraefikBackendLoadBalancerStickiness: aws.String("true"),
|
||||
label.TraefikBackendLoadBalancerStickinessCookieName: aws.String("chocolate"),
|
||||
label.TraefikBackendMaxConnAmount: aws.String("666"),
|
||||
|
@ -776,7 +772,6 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "chocolate",
|
||||
},
|
||||
|
@ -891,12 +886,12 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
RateLimit: &types.RateLimit{
|
||||
RateSet: map[string]*types.Rate{
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
|
|
|
@ -33,7 +33,6 @@ type Provider struct {
|
|||
|
||||
// Provider lookup parameters
|
||||
Clusters Clusters `description:"ECS Clusters name"`
|
||||
Cluster string `description:"deprecated - ECS Cluster name"` // deprecated
|
||||
AutoDiscoverClusters bool `description:"Auto discover cluster" export:"true"`
|
||||
Region string `description:"The AWS region to use for requests" export:"true"`
|
||||
AccessKeyID string `description:"The AWS credentials access key to use for making requests"`
|
||||
|
@ -209,10 +208,6 @@ func (p *Provider) listInstances(ctx context.Context, client *awsClient) ([]ecsI
|
|||
for _, cArn := range clustersArn {
|
||||
clusters = append(clusters, *cArn)
|
||||
}
|
||||
} else if p.Cluster != "" {
|
||||
// TODO: Deprecated configuration - Need to be removed in the future
|
||||
clusters = Clusters{p.Cluster}
|
||||
log.Warn("Deprecated configuration found: ecs.cluster. Please use ecs.clusters instead.")
|
||||
} else {
|
||||
clusters = p.Clusters
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
"github.com/ArthurHlt/go-eureka-client/eureka"
|
||||
"github.com/cenk/backoff"
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/job"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/provider"
|
||||
|
@ -18,8 +18,7 @@ import (
|
|||
type Provider struct {
|
||||
provider.BaseProvider `mapstructure:",squash" export:"true"`
|
||||
Endpoint string `description:"Eureka server endpoint"`
|
||||
Delay flaeg.Duration `description:"Override default configuration time between refresh (Deprecated)" export:"true"` // Deprecated
|
||||
RefreshSeconds flaeg.Duration `description:"Override default configuration time between refresh" export:"true"`
|
||||
RefreshSeconds parse.Duration `description:"Override default configuration time between refresh" export:"true"`
|
||||
}
|
||||
|
||||
// Init the provider
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/tls"
|
||||
"github.com/containous/traefik/types"
|
||||
|
@ -77,12 +77,12 @@ func lbMethod(method string) func(*types.Backend) {
|
|||
}
|
||||
}
|
||||
|
||||
func lbSticky() func(*types.Backend) {
|
||||
func lbStickiness() func(*types.Backend) {
|
||||
return func(b *types.Backend) {
|
||||
if b.LoadBalancer == nil {
|
||||
b.LoadBalancer = &types.LoadBalancer{}
|
||||
}
|
||||
b.LoadBalancer.Sticky = true
|
||||
b.LoadBalancer.Stickiness = &types.Stickiness{}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -378,7 +378,7 @@ func limitBurst(burst int64) func(*types.Rate) {
|
|||
|
||||
func limitPeriod(period time.Duration) func(*types.Rate) {
|
||||
return func(rate *types.Rate) {
|
||||
rate.Period = flaeg.Duration(period)
|
||||
rate.Period = parse.Duration(period)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -921,11 +921,6 @@ func getLoadBalancer(service *corev1.Service) *types.LoadBalancer {
|
|||
loadBalancer.Method = "drr"
|
||||
}
|
||||
|
||||
if sticky := service.Annotations[label.TraefikBackendLoadBalancerSticky]; len(sticky) > 0 {
|
||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", label.TraefikBackendLoadBalancerSticky, annotationKubernetesAffinity)
|
||||
loadBalancer.Sticky = strings.EqualFold(strings.TrimSpace(sticky), "true")
|
||||
}
|
||||
|
||||
if stickiness := getStickiness(service); stickiness != nil {
|
||||
loadBalancer.Stickiness = stickiness
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/tls"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -867,8 +866,7 @@ func TestServiceAnnotations(t *testing.T) {
|
|||
sName("service2"),
|
||||
sNamespace("testing"),
|
||||
sUID("2"),
|
||||
sAnnotation(annotationKubernetesCircuitBreakerExpression, ""),
|
||||
sAnnotation(label.TraefikBackendLoadBalancerSticky, "true"),
|
||||
sAnnotation(annotationKubernetesAffinity, "true"),
|
||||
sSpec(
|
||||
clusterIP("10.0.0.2"),
|
||||
sPorts(sPort(802, ""))),
|
||||
|
@ -972,7 +970,7 @@ retryexpression: IsNetworkError() && Attempts() <= 2
|
|||
servers(
|
||||
server("http://10.15.0.1:8080", weight(1)),
|
||||
server("http://10.15.0.2:8080", weight(1))),
|
||||
lbMethod("wrr"), lbSticky(),
|
||||
lbMethod("wrr"), lbStickiness(),
|
||||
),
|
||||
backend("baz",
|
||||
servers(
|
||||
|
|
|
@ -10,7 +10,6 @@ const (
|
|||
pathBackendHealthCheckHostname = "/healthcheck/hostname"
|
||||
pathBackendHealthCheckHeaders = "/healthcheck/headers/"
|
||||
pathBackendLoadBalancerMethod = "/loadbalancer/method"
|
||||
pathBackendLoadBalancerSticky = "/loadbalancer/sticky"
|
||||
pathBackendLoadBalancerStickiness = "/loadbalancer/stickiness"
|
||||
pathBackendLoadBalancerStickinessCookieName = "/loadbalancer/stickiness/cookiename"
|
||||
pathBackendMaxConnAmount = "/maxconn/amount"
|
||||
|
@ -28,7 +27,6 @@ const (
|
|||
pathFrontends = "/frontends/"
|
||||
pathFrontendBackend = "/backend"
|
||||
pathFrontendPriority = "/priority"
|
||||
pathFrontendPassHostHeaderDeprecated = "/passHostHeader" // Deprecated
|
||||
pathFrontendPassHostHeader = "/passhostheader"
|
||||
pathFrontendPassTLSCert = "/passtlscert"
|
||||
pathFrontendWhiteListSourceRange = "/whitelist/sourcerange"
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
"github.com/BurntSushi/ty/fun"
|
||||
"github.com/abronan/valkeyrie/store"
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/tls"
|
||||
|
@ -43,7 +43,7 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||
// Frontend functions
|
||||
"getBackendName": p.getFuncString(pathFrontendBackend, ""),
|
||||
"getPriority": p.getFuncInt(pathFrontendPriority, label.DefaultFrontendPriority),
|
||||
"getPassHostHeader": p.getPassHostHeader(),
|
||||
"getPassHostHeader": p.getFuncBool(pathFrontendPassHostHeader, label.DefaultPassHostHeader),
|
||||
"getPassTLSCert": p.getFuncBool(pathFrontendPassTLSCert, label.DefaultPassTLSCert),
|
||||
"getEntryPoints": p.getFuncList(pathFrontendEntryPoints),
|
||||
"getBasicAuth": p.getFuncList(pathFrontendBasicAuth), // Deprecated
|
||||
|
@ -62,9 +62,6 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||
"getMaxConn": p.getMaxConn,
|
||||
"getHealthCheck": p.getHealthCheck,
|
||||
"getBuffering": p.getBuffering,
|
||||
"getSticky": p.getSticky, // Deprecated [breaking]
|
||||
"hasStickinessLabel": p.hasStickinessLabel, // Deprecated [breaking]
|
||||
"getStickinessCookieName": p.getStickinessCookieName, // Deprecated [breaking]
|
||||
}
|
||||
|
||||
configuration, err := p.GetConfiguration("templates/kv.tmpl", KvFuncMap, templateObjects)
|
||||
|
@ -81,51 +78,6 @@ func (p *Provider) buildConfiguration() *types.Configuration {
|
|||
return configuration
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
func (p *Provider) getPassHostHeader() func(rootPath string) bool {
|
||||
return func(rootPath string) bool {
|
||||
rawValue := p.get("", rootPath, pathFrontendPassHostHeader)
|
||||
|
||||
if len(rawValue) > 0 {
|
||||
value, err := strconv.ParseBool(rawValue)
|
||||
if err != nil {
|
||||
log.Errorf("Invalid value for %s %s: %s", rootPath, pathFrontendPassHostHeader, rawValue)
|
||||
return label.DefaultPassHostHeader
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
return p.getBool(label.DefaultPassHostHeader, rootPath, pathFrontendPassHostHeaderDeprecated)
|
||||
}
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
func (p *Provider) getSticky(rootPath string) bool {
|
||||
stickyValue := p.get("", rootPath, pathBackendLoadBalancerSticky)
|
||||
if len(stickyValue) > 0 {
|
||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", pathBackendLoadBalancerSticky, pathBackendLoadBalancerStickiness)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
|
||||
sticky, err := strconv.ParseBool(stickyValue)
|
||||
if err != nil {
|
||||
log.Warnf("Invalid %s value: %s.", pathBackendLoadBalancerSticky, stickyValue)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func (p *Provider) getWhiteList(rootPath string) *types.WhiteList {
|
||||
ranges := p.getList(rootPath, pathFrontendWhiteListSourceRange)
|
||||
|
||||
|
@ -198,7 +150,7 @@ func (p *Provider) getRateLimit(rootPath string) *types.RateLimit {
|
|||
|
||||
rawPeriod := p.get("", pathLimits+pathFrontendRateLimitPeriod)
|
||||
|
||||
var period flaeg.Duration
|
||||
var period parse.Duration
|
||||
err := period.Set(rawPeriod)
|
||||
if err != nil {
|
||||
log.Errorf("Invalid %q value: %q", pathLimits+pathFrontendRateLimitPeriod, rawPeriod)
|
||||
|
@ -256,7 +208,6 @@ func (p *Provider) getHeaders(rootPath string) *types.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) {
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/abronan/valkeyrie/store"
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/tls"
|
||||
"github.com/containous/traefik/types"
|
||||
|
@ -253,7 +253,6 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
backend("backend1",
|
||||
withPair(pathBackendCircuitBreakerExpression, label.DefaultCircuitBreakerExpression),
|
||||
withPair(pathBackendLoadBalancerMethod, "drr"),
|
||||
withPair(pathBackendLoadBalancerSticky, "true"),
|
||||
withPair(pathBackendLoadBalancerStickiness, "true"),
|
||||
withPair(pathBackendLoadBalancerStickinessCookieName, "tomate"),
|
||||
withPair(pathBackendHealthCheckScheme, "http"),
|
||||
|
@ -362,7 +361,6 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "tomate",
|
||||
},
|
||||
|
@ -432,12 +430,12 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
"foo": {
|
||||
Average: 6,
|
||||
Burst: 12,
|
||||
Period: flaeg.Duration(18 * time.Second),
|
||||
Period: parse.Duration(18 * time.Second),
|
||||
},
|
||||
"bar": {
|
||||
Average: 3,
|
||||
Burst: 6,
|
||||
Period: flaeg.Duration(9 * time.Second),
|
||||
Period: parse.Duration(9 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1244,7 +1242,7 @@ func TestProviderHasStickinessLabel(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
actual := p.hasStickinessLabel(test.rootPath)
|
||||
actual := p.getLoadBalancer(test.rootPath).Stickiness != nil
|
||||
|
||||
if actual != test.expected {
|
||||
t.Fatalf("expected %v, got %v", test.expected, actual)
|
||||
|
@ -1474,12 +1472,12 @@ func TestProviderGetRateLimit(t *testing.T) {
|
|||
"foo": {
|
||||
Average: 6,
|
||||
Burst: 12,
|
||||
Period: flaeg.Duration(18 * time.Second),
|
||||
Period: parse.Duration(18 * time.Second),
|
||||
},
|
||||
"bar": {
|
||||
Average: 3,
|
||||
Burst: 6,
|
||||
Period: flaeg.Duration(9 * time.Second),
|
||||
Period: parse.Duration(9 * time.Second),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1794,12 +1792,10 @@ func TestProviderGetLoadBalancer(t *testing.T) {
|
|||
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",
|
||||
},
|
||||
|
@ -1823,17 +1819,6 @@ func TestProviderGetLoadBalancer(t *testing.T) {
|
|||
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",
|
||||
|
|
|
@ -23,7 +23,6 @@ const (
|
|||
SuffixBackendHealthCheckHeaders = "backend.healthcheck.headers"
|
||||
SuffixBackendLoadBalancer = "backend.loadbalancer"
|
||||
SuffixBackendLoadBalancerMethod = SuffixBackendLoadBalancer + ".method"
|
||||
SuffixBackendLoadBalancerSticky = SuffixBackendLoadBalancer + ".sticky"
|
||||
SuffixBackendLoadBalancerStickiness = SuffixBackendLoadBalancer + ".stickiness"
|
||||
SuffixBackendLoadBalancerStickinessCookieName = SuffixBackendLoadBalancer + ".stickiness.cookieName"
|
||||
SuffixBackendMaxConnAmount = "backend.maxconn.amount"
|
||||
|
@ -111,7 +110,6 @@ const (
|
|||
TraefikBackendHealthCheckHeaders = Prefix + SuffixBackendHealthCheckHeaders
|
||||
TraefikBackendLoadBalancer = Prefix + SuffixBackendLoadBalancer
|
||||
TraefikBackendLoadBalancerMethod = Prefix + SuffixBackendLoadBalancerMethod
|
||||
TraefikBackendLoadBalancerSticky = Prefix + SuffixBackendLoadBalancerSticky
|
||||
TraefikBackendLoadBalancerStickiness = Prefix + SuffixBackendLoadBalancerStickiness
|
||||
TraefikBackendLoadBalancerStickinessCookieName = Prefix + SuffixBackendLoadBalancerStickinessCookieName
|
||||
TraefikBackendMaxConnAmount = Prefix + SuffixBackendMaxConnAmount
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/types"
|
||||
)
|
||||
|
@ -218,7 +218,7 @@ func ParseRateSets(labels map[string]string, labelPrefix string, labelRegex *reg
|
|||
|
||||
switch submatch[2] {
|
||||
case "period":
|
||||
var d flaeg.Duration
|
||||
var d parse.Duration
|
||||
err := d.Set(rawValue)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to parse %q: %q. %v", lblName, rawValue, err)
|
||||
|
@ -354,7 +354,6 @@ func GetLoadBalancer(labels map[string]string) *types.LoadBalancer {
|
|||
|
||||
lb := &types.LoadBalancer{
|
||||
Method: method,
|
||||
Sticky: getSticky(labels),
|
||||
}
|
||||
|
||||
if GetBoolValue(labels, TraefikBackendLoadBalancerStickiness, false) {
|
||||
|
@ -364,14 +363,3 @@ func GetLoadBalancer(labels map[string]string) *types.LoadBalancer {
|
|||
|
||||
return lb
|
||||
}
|
||||
|
||||
// TODO: Deprecated
|
||||
// replaced by Stickiness
|
||||
// Deprecated
|
||||
func getSticky(labels map[string]string) bool {
|
||||
if Has(labels, TraefikBackendLoadBalancerSticky) {
|
||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", TraefikBackendLoadBalancerSticky, TraefikBackendLoadBalancerStickiness)
|
||||
}
|
||||
|
||||
return GetBoolValue(labels, TraefikBackendLoadBalancerSticky, false)
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
@ -93,12 +93,12 @@ func TestParseRateSets(t *testing.T) {
|
|||
},
|
||||
expected: map[string]*types.Rate{
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
|
@ -254,13 +254,11 @@ func TestGetLoadBalancer(t *testing.T) {
|
|||
desc: "should return a struct when labels are set",
|
||||
labels: map[string]string{
|
||||
TraefikBackendLoadBalancerMethod: "drr",
|
||||
TraefikBackendLoadBalancerSticky: "true",
|
||||
TraefikBackendLoadBalancerStickiness: "true",
|
||||
TraefikBackendLoadBalancerStickinessCookieName: "foo",
|
||||
},
|
||||
expected: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "foo",
|
||||
},
|
||||
|
@ -270,12 +268,10 @@ func TestGetLoadBalancer(t *testing.T) {
|
|||
desc: "should return a nil Stickiness when Stickiness is not set",
|
||||
labels: map[string]string{
|
||||
TraefikBackendLoadBalancerMethod: "drr",
|
||||
TraefikBackendLoadBalancerSticky: "true",
|
||||
TraefikBackendLoadBalancerStickinessCookieName: "foo",
|
||||
},
|
||||
expected: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: nil,
|
||||
},
|
||||
},
|
||||
|
@ -550,12 +546,12 @@ func TestGetRateLimit(t *testing.T) {
|
|||
ExtractorFunc: "client.ip",
|
||||
RateSet: map[string]*types.Rate{
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
|
|
|
@ -36,60 +36,6 @@ func FindSegmentSubmatch(name string) []string {
|
|||
return matches
|
||||
}
|
||||
|
||||
// ExtractServicePropertiesP Extract services labels
|
||||
// Deprecated
|
||||
func ExtractServicePropertiesP(labels *map[string]string) SegmentProperties {
|
||||
if labels == nil {
|
||||
return make(SegmentProperties)
|
||||
}
|
||||
return ExtractServiceProperties(*labels)
|
||||
}
|
||||
|
||||
// ExtractServiceProperties Extract services labels
|
||||
// Deprecated
|
||||
func ExtractServiceProperties(labels map[string]string) SegmentProperties {
|
||||
v := make(SegmentProperties)
|
||||
|
||||
for name, value := range labels {
|
||||
matches := FindSegmentSubmatch(name)
|
||||
if matches == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var segmentName string
|
||||
var propertyName string
|
||||
for i, name := range SegmentPropertiesRegexp.SubexpNames() {
|
||||
// the group 0 is anonymous because it's always the root expression
|
||||
if i != 0 {
|
||||
if name == "segment_name" {
|
||||
segmentName = matches[i]
|
||||
} else if name == "property_name" {
|
||||
propertyName = matches[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if _, ok := v[segmentName]; !ok {
|
||||
v[segmentName] = make(SegmentPropertyValues)
|
||||
}
|
||||
v[segmentName][propertyName] = value
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// GetServiceLabel converts a key value of Label*, given a serviceName,
|
||||
// into a pattern <LabelPrefix>.<serviceName>.<property>
|
||||
// i.e. For LabelFrontendRule and serviceName=app it will return "traefik.app.frontend.rule"
|
||||
// Deprecated
|
||||
func GetServiceLabel(labelName, serviceName string) string {
|
||||
if len(serviceName) > 0 {
|
||||
property := strings.TrimPrefix(labelName, Prefix)
|
||||
return Prefix + serviceName + "." + property
|
||||
}
|
||||
return labelName
|
||||
}
|
||||
|
||||
// ExtractTraefikLabels transform labels to segment labels
|
||||
func ExtractTraefikLabels(originLabels map[string]string) SegmentProperties {
|
||||
allLabels := make(SegmentProperties)
|
||||
|
|
|
@ -93,129 +93,3 @@ func TestExtractTraefikLabels(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractServiceProperties(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels map[string]string
|
||||
expected SegmentProperties
|
||||
}{
|
||||
{
|
||||
desc: "empty labels map",
|
||||
expected: SegmentProperties{},
|
||||
},
|
||||
{
|
||||
desc: "valid label names",
|
||||
labels: map[string]string{
|
||||
"traefik.foo.port": "bar",
|
||||
"traefik.foo.frontend.bar": "1bar",
|
||||
"traefik.foo.backend": "3bar",
|
||||
},
|
||||
expected: SegmentProperties{
|
||||
"foo": SegmentPropertyValues{
|
||||
"port": "bar",
|
||||
"frontend.bar": "1bar",
|
||||
"backend": "3bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "invalid label names",
|
||||
labels: map[string]string{
|
||||
"foo.frontend.bar": "1bar",
|
||||
"traefik.foo.frontend.": "2bar",
|
||||
"traefik.foo.port.bar": "barbar",
|
||||
"traefik.foo.frontend": "0bar",
|
||||
"traefik.frontend.foo.backend": "0bar",
|
||||
},
|
||||
expected: SegmentProperties{},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := ExtractServiceProperties(test.labels)
|
||||
assert.EqualValues(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractServicePropertiesP(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labels *map[string]string
|
||||
expected SegmentProperties
|
||||
}{
|
||||
{
|
||||
desc: "nil labels map",
|
||||
expected: SegmentProperties{},
|
||||
},
|
||||
{
|
||||
desc: "valid label names",
|
||||
labels: &map[string]string{
|
||||
"traefik.foo.port": "bar",
|
||||
"traefik.foo.frontend.bar": "1bar",
|
||||
"traefik.foo.backend": "3bar",
|
||||
},
|
||||
expected: SegmentProperties{
|
||||
"foo": SegmentPropertyValues{
|
||||
"port": "bar",
|
||||
"frontend.bar": "1bar",
|
||||
"backend": "3bar",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "invalid label names",
|
||||
labels: &map[string]string{
|
||||
"foo.frontend.bar": "1bar",
|
||||
"traefik.foo.frontend.": "2bar",
|
||||
"traefik.foo.port.bar": "barbar",
|
||||
"traefik.foo.frontend": "0bar",
|
||||
"traefik.frontend.foo.backend": "0bar",
|
||||
},
|
||||
expected: SegmentProperties{},
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := ExtractServicePropertiesP(test.labels)
|
||||
assert.EqualValues(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServiceLabel(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
labelName string
|
||||
serviceName string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
desc: "without service name",
|
||||
labelName: TraefikPort,
|
||||
expected: TraefikPort,
|
||||
},
|
||||
{
|
||||
desc: "with service name",
|
||||
labelName: TraefikPort,
|
||||
serviceName: "bar",
|
||||
expected: "traefik.bar.port",
|
||||
},
|
||||
}
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
got := GetServiceLabel(test.labelName, test.serviceName)
|
||||
assert.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/gambol99/go-marathon"
|
||||
|
@ -363,7 +363,6 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
withLabel(label.TraefikBackendHealthCheckHeaders, "Foo:bar || Bar:foo"),
|
||||
|
||||
withLabel(label.TraefikBackendLoadBalancerMethod, "drr"),
|
||||
withLabel(label.TraefikBackendLoadBalancerSticky, "true"),
|
||||
withLabel(label.TraefikBackendLoadBalancerStickiness, "true"),
|
||||
withLabel(label.TraefikBackendLoadBalancerStickinessCookieName, "chocolate"),
|
||||
withLabel(label.TraefikBackendMaxConnAmount, "666"),
|
||||
|
@ -529,12 +528,12 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
RateLimit: &types.RateLimit{
|
||||
RateSet: map[string]*types.Rate{
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
|
@ -560,7 +559,6 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "chocolate",
|
||||
},
|
||||
|
@ -751,7 +749,6 @@ func TestBuildConfigurationSegments(t *testing.T) {
|
|||
withLabel(label.TraefikBackendHealthCheckPort, "880"),
|
||||
withLabel(label.TraefikBackendHealthCheckInterval, "6"),
|
||||
withLabel(label.TraefikBackendLoadBalancerMethod, "drr"),
|
||||
withLabel(label.TraefikBackendLoadBalancerSticky, "true"),
|
||||
withLabel(label.TraefikBackendLoadBalancerStickiness, "true"),
|
||||
withLabel(label.TraefikBackendLoadBalancerStickinessCookieName, "chocolate"),
|
||||
withLabel(label.TraefikBackendMaxConnAmount, "666"),
|
||||
|
@ -921,12 +918,12 @@ func TestBuildConfigurationSegments(t *testing.T) {
|
|||
RateLimit: &types.RateLimit{
|
||||
RateSet: map[string]*types.Rate{
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
|
@ -952,7 +949,6 @@ func TestBuildConfigurationSegments(t *testing.T) {
|
|||
},
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "chocolate",
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/cenk/backoff"
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/job"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/provider"
|
||||
|
@ -55,10 +55,10 @@ type Provider struct {
|
|||
MarathonLBCompatibility bool `description:"Add compatibility with marathon-lb labels" export:"true"`
|
||||
FilterMarathonConstraints bool `description:"Enable use of Marathon constraints in constraint filtering" export:"true"`
|
||||
TLS *types.ClientTLS `description:"Enable TLS support" export:"true"`
|
||||
DialerTimeout flaeg.Duration `description:"Set a dialer timeout for Marathon" export:"true"`
|
||||
ResponseHeaderTimeout flaeg.Duration `description:"Set a response header timeout for Marathon" export:"true"`
|
||||
TLSHandshakeTimeout flaeg.Duration `description:"Set a TLS handhsake timeout for Marathon" export:"true"`
|
||||
KeepAlive flaeg.Duration `description:"Set a TCP Keep Alive time in seconds" export:"true"`
|
||||
DialerTimeout parse.Duration `description:"Set a dialer timeout for Marathon" export:"true"`
|
||||
ResponseHeaderTimeout parse.Duration `description:"Set a response header timeout for Marathon" export:"true"`
|
||||
TLSHandshakeTimeout parse.Duration `description:"Set a TLS handhsake timeout for Marathon" export:"true"`
|
||||
KeepAlive parse.Duration `description:"Set a TCP Keep Alive time in seconds" export:"true"`
|
||||
ForceTaskHostname bool `description:"Force to use the task's hostname." export:"true"`
|
||||
Basic *Basic `description:"Enable basic authentication" export:"true"`
|
||||
RespectReadinessChecks bool `description:"Filter out tasks with non-successful readiness checks during deployments" export:"true"`
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/mesosphere/mesos-dns/records/state"
|
||||
|
@ -487,12 +487,12 @@ func TestBuildConfiguration(t *testing.T) {
|
|||
ExtractorFunc: "client.ip",
|
||||
RateSet: map[string]*types.Rate{
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
|
@ -668,7 +668,6 @@ func TestBuildConfigurationSegments(t *testing.T) {
|
|||
withLabel(label.TraefikBackendHealthCheckHostname, "foo.com"),
|
||||
withLabel(label.TraefikBackendHealthCheckHeaders, "Foo:bar || Bar:foo"),
|
||||
withLabel(label.TraefikBackendLoadBalancerMethod, "drr"),
|
||||
withLabel(label.TraefikBackendLoadBalancerSticky, "true"),
|
||||
withLabel(label.TraefikBackendLoadBalancerStickiness, "true"),
|
||||
withLabel(label.TraefikBackendLoadBalancerStickinessCookieName, "chocolate"),
|
||||
withLabel(label.TraefikBackendMaxConnAmount, "666"),
|
||||
|
@ -841,12 +840,12 @@ func TestBuildConfigurationSegments(t *testing.T) {
|
|||
RateLimit: &types.RateLimit{
|
||||
RateSet: map[string]*types.Rate{
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
|
@ -872,7 +871,6 @@ func TestBuildConfigurationSegments(t *testing.T) {
|
|||
},
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "chocolate",
|
||||
},
|
||||
|
|
|
@ -29,7 +29,6 @@ type BaseProvider struct {
|
|||
Filename string `description:"Override default configuration template. For advanced users :)" export:"true"`
|
||||
Constraints types.Constraints `description:"Filter services by constraint, matching with Traefik tags." export:"true"`
|
||||
Trace bool `description:"Display additional provider logs (if available)." export:"true"`
|
||||
TemplateVersion int `description:"Template version." export:"true"`
|
||||
DebugLogGeneratedTemplate bool `description:"Enable debug logging of generated configuration template." export:"true"`
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/traefik/provider/label"
|
||||
"github.com/containous/traefik/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
@ -48,7 +48,6 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
label.TraefikBackendHealthCheckHostname: "foo.com",
|
||||
label.TraefikBackendHealthCheckHeaders: "Foo:bar || Bar:foo",
|
||||
label.TraefikBackendLoadBalancerMethod: "drr",
|
||||
label.TraefikBackendLoadBalancerSticky: "true",
|
||||
label.TraefikBackendLoadBalancerStickiness: "true",
|
||||
label.TraefikBackendLoadBalancerStickinessCookieName: "chocolate",
|
||||
label.TraefikBackendMaxConnAmount: "666",
|
||||
|
@ -216,12 +215,12 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
ExtractorFunc: "client.ip",
|
||||
RateSet: map[string]*types.Rate{
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
|
@ -252,7 +251,6 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
},
|
||||
LoadBalancer: &types.LoadBalancer{
|
||||
Method: "drr",
|
||||
Sticky: true,
|
||||
Stickiness: &types.Stickiness{
|
||||
CookieName: "chocolate",
|
||||
},
|
||||
|
@ -436,12 +434,12 @@ func TestProviderBuildConfiguration(t *testing.T) {
|
|||
ExtractorFunc: "client.ip",
|
||||
RateSet: map[string]*types.Rate{
|
||||
"foo": {
|
||||
Period: flaeg.Duration(6 * time.Second),
|
||||
Period: parse.Duration(6 * time.Second),
|
||||
Average: 12,
|
||||
Burst: 18,
|
||||
},
|
||||
"bar": {
|
||||
Period: flaeg.Duration(3 * time.Second),
|
||||
Period: parse.Duration(3 * time.Second),
|
||||
Average: 6,
|
||||
Burst: 9,
|
||||
},
|
||||
|
|
|
@ -21,7 +21,6 @@ import (
|
|||
"github.com/containous/mux"
|
||||
"github.com/containous/traefik/cluster"
|
||||
"github.com/containous/traefik/configuration"
|
||||
"github.com/containous/traefik/configuration/router"
|
||||
"github.com/containous/traefik/h2c"
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/metrics"
|
||||
|
@ -208,10 +207,6 @@ func NewServer(globalConfiguration configuration.GlobalConfiguration, provider p
|
|||
server.leadership = cluster.NewLeadership(server.routinesPool.Ctx(), globalConfiguration.Cluster)
|
||||
}
|
||||
|
||||
if globalConfiguration.AccessLogsFile != "" {
|
||||
globalConfiguration.AccessLog = &types.AccessLog{FilePath: globalConfiguration.AccessLogsFile, Format: accesslog.CommonFormat}
|
||||
}
|
||||
|
||||
if globalConfiguration.AccessLog != nil {
|
||||
var err error
|
||||
server.accessLoggerMiddleware, err = accesslog.NewLogHandler(globalConfiguration.AccessLog)
|
||||
|
@ -413,12 +408,6 @@ func (s *Server) createTLSConfig(entryPointName string, tlsOption *traefiktls.TL
|
|||
// ensure http2 enabled
|
||||
config.NextProtos = []string{"h2", "http/1.1", acme.ACMETLS1Protocol}
|
||||
|
||||
if len(tlsOption.ClientCAFiles) > 0 {
|
||||
log.Warnf("Deprecated configuration found during TLS configuration creation: %s. Please use %s (which allows to make the CA Files optional).", "tls.ClientCAFiles", "tls.ClientCA.files")
|
||||
tlsOption.ClientCA.Files = tlsOption.ClientCAFiles
|
||||
tlsOption.ClientCA.Optional = false
|
||||
}
|
||||
|
||||
if len(tlsOption.ClientCA.Files) > 0 {
|
||||
pool := x509.NewCertPool()
|
||||
for _, caFile := range tlsOption.ClientCA.Files {
|
||||
|
@ -612,12 +601,8 @@ func (s *Server) buildInternalRouter(entryPointName string) *mux.Router {
|
|||
entryPoint.InternalRouter.AddRoutes(internalMuxRouter)
|
||||
|
||||
if s.globalConfiguration.API != nil && s.globalConfiguration.API.EntryPoint == entryPointName && s.leadership != nil {
|
||||
if s.globalConfiguration.Web != nil && s.globalConfiguration.Web.Path != "" {
|
||||
rt := router.WithPrefix{Router: s.leadership, PathPrefix: s.globalConfiguration.Web.Path}
|
||||
rt.AddRoutes(internalMuxRouter)
|
||||
} else {
|
||||
s.leadership.AddRoutes(internalMuxRouter)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,11 +617,7 @@ func buildServerTimeouts(globalConfig configuration.GlobalConfiguration) (readTi
|
|||
writeTimeout = time.Duration(globalConfig.RespondingTimeouts.WriteTimeout)
|
||||
}
|
||||
|
||||
// Prefer legacy idle timeout parameter for backwards compatibility reasons
|
||||
if globalConfig.IdleTimeout > 0 {
|
||||
idleTimeout = time.Duration(globalConfig.IdleTimeout)
|
||||
log.Warn("top-level idle timeout configuration has been deprecated -- please use responding timeouts")
|
||||
} else if globalConfig.RespondingTimeouts != nil {
|
||||
if globalConfig.RespondingTimeouts != nil {
|
||||
idleTimeout = time.Duration(globalConfig.RespondingTimeouts.IdleTimeout)
|
||||
} else {
|
||||
idleTimeout = configuration.DefaultIdleTimeout
|
||||
|
|
|
@ -385,32 +385,15 @@ func (s *Server) filterEntryPoints(entryPoints []string) ([]string, []string) {
|
|||
func configureBackends(backends map[string]*types.Backend) {
|
||||
for backendName := range backends {
|
||||
backend := backends[backendName]
|
||||
if backend.LoadBalancer != nil && backend.LoadBalancer.Sticky {
|
||||
log.Warnf("Deprecated configuration found: %s. Please use %s.", "backend.LoadBalancer.Sticky", "backend.LoadBalancer.Stickiness")
|
||||
}
|
||||
|
||||
_, err := types.NewLoadBalancerMethod(backend.LoadBalancer)
|
||||
if err == nil {
|
||||
if backend.LoadBalancer != nil && backend.LoadBalancer.Stickiness == nil && backend.LoadBalancer.Sticky {
|
||||
backend.LoadBalancer.Stickiness = &types.Stickiness{
|
||||
CookieName: "_TRAEFIK_BACKEND",
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
log.Debugf("Backend %s: %v", backendName, err)
|
||||
|
||||
var stickiness *types.Stickiness
|
||||
if backend.LoadBalancer != nil {
|
||||
if backend.LoadBalancer.Stickiness == nil {
|
||||
if backend.LoadBalancer.Sticky {
|
||||
stickiness = &types.Stickiness{
|
||||
CookieName: "_TRAEFIK_BACKEND",
|
||||
}
|
||||
}
|
||||
} else {
|
||||
stickiness = backend.LoadBalancer.Stickiness
|
||||
}
|
||||
}
|
||||
backend.LoadBalancer = &types.LoadBalancer{
|
||||
Method: "wrr",
|
||||
Stickiness: stickiness,
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/mux"
|
||||
"github.com/containous/traefik/configuration"
|
||||
"github.com/containous/traefik/healthcheck"
|
||||
|
@ -90,7 +90,7 @@ func TestServerLoadConfigHealthCheckOptions(t *testing.T) {
|
|||
for _, healthCheck := range healthChecks {
|
||||
t.Run(fmt.Sprintf("%s/hc=%t", lbMethod, healthCheck != nil), func(t *testing.T) {
|
||||
globalConfig := configuration.GlobalConfiguration{
|
||||
HealthCheck: &configuration.HealthCheckConfig{Interval: flaeg.Duration(5 * time.Second)},
|
||||
HealthCheck: &configuration.HealthCheckConfig{Interval: parse.Duration(5 * time.Second)},
|
||||
}
|
||||
entryPoints := map[string]EntryPoint{
|
||||
"http": {
|
||||
|
@ -482,7 +482,7 @@ func TestServerBuildHealthCheckOptions(t *testing.T) {
|
|||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
opts := buildHealthCheckOptions(lb, "backend", test.hc, &configuration.HealthCheckConfig{Interval: flaeg.Duration(globalInterval)})
|
||||
opts := buildHealthCheckOptions(lb, "backend", test.hc, &configuration.HealthCheckConfig{Interval: parse.Duration(globalInterval)})
|
||||
assert.Equal(t, test.expectedOpts, opts, "health check options")
|
||||
})
|
||||
}
|
||||
|
|
|
@ -305,12 +305,6 @@ func createClientTLSConfig(entryPointName string, tlsOption *traefiktls.TLS) (*t
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if len(tlsOption.ClientCAFiles) > 0 {
|
||||
log.Warnf("Deprecated configuration found during client TLS configuration creation: %s. Please use %s (which allows to make the CA Files optional).", "tls.ClientCAFiles", "tls.ClientCA.files")
|
||||
tlsOption.ClientCA.Files = tlsOption.ClientCAFiles
|
||||
tlsOption.ClientCA.Optional = false
|
||||
}
|
||||
|
||||
if len(tlsOption.ClientCA.Files) > 0 {
|
||||
pool := x509.NewCertPool()
|
||||
for _, caFile := range tlsOption.ClientCA.Files {
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/mux"
|
||||
"github.com/containous/traefik/configuration"
|
||||
"github.com/containous/traefik/middlewares"
|
||||
|
@ -30,9 +30,9 @@ func TestPrepareServerTimeouts(t *testing.T) {
|
|||
desc: "full configuration",
|
||||
globalConfig: configuration.GlobalConfiguration{
|
||||
RespondingTimeouts: &configuration.RespondingTimeouts{
|
||||
IdleTimeout: flaeg.Duration(10 * time.Second),
|
||||
ReadTimeout: flaeg.Duration(12 * time.Second),
|
||||
WriteTimeout: flaeg.Duration(14 * time.Second),
|
||||
IdleTimeout: parse.Duration(10 * time.Second),
|
||||
ReadTimeout: parse.Duration(12 * time.Second),
|
||||
WriteTimeout: parse.Duration(14 * time.Second),
|
||||
},
|
||||
},
|
||||
expectedIdleTimeout: time.Duration(10 * time.Second),
|
||||
|
@ -46,27 +46,6 @@ func TestPrepareServerTimeouts(t *testing.T) {
|
|||
expectedReadTimeout: time.Duration(0 * time.Second),
|
||||
expectedWriteTimeout: time.Duration(0 * time.Second),
|
||||
},
|
||||
{
|
||||
desc: "deprecated IdleTimeout configured",
|
||||
globalConfig: configuration.GlobalConfiguration{
|
||||
IdleTimeout: flaeg.Duration(45 * time.Second),
|
||||
},
|
||||
expectedIdleTimeout: time.Duration(45 * time.Second),
|
||||
expectedReadTimeout: time.Duration(0 * time.Second),
|
||||
expectedWriteTimeout: time.Duration(0 * time.Second),
|
||||
},
|
||||
{
|
||||
desc: "deprecated and new IdleTimeout configured",
|
||||
globalConfig: configuration.GlobalConfiguration{
|
||||
IdleTimeout: flaeg.Duration(45 * time.Second),
|
||||
RespondingTimeouts: &configuration.RespondingTimeouts{
|
||||
IdleTimeout: flaeg.Duration(80 * time.Second),
|
||||
},
|
||||
},
|
||||
expectedIdleTimeout: time.Duration(45 * time.Second),
|
||||
expectedReadTimeout: time.Duration(0 * time.Second),
|
||||
expectedWriteTimeout: time.Duration(0 * time.Second),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
@ -212,7 +191,7 @@ func setupListenProvider(throttleDuration time.Duration) (server *Server, stop c
|
|||
EntryPoints: configuration.EntryPoints{
|
||||
"http": &configuration.EntryPoint{},
|
||||
},
|
||||
ProvidersThrottleDuration: flaeg.Duration(throttleDuration),
|
||||
ProvidersThrottleDuration: parse.Duration(throttleDuration),
|
||||
}
|
||||
|
||||
server = NewServer(globalConfig, nil, nil)
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
{{if $loadBalancer }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
{{if $loadBalancer }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
{{if $loadBalancer }}
|
||||
[backends."backend-{{ $serviceName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."backend-{{ $serviceName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
[backends."{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $backend.LoadBalancer.Method }}"
|
||||
sticky = {{ $backend.LoadBalancer.Sticky }}
|
||||
{{if $backend.LoadBalancer.Stickiness }}
|
||||
[backends."{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $backend.LoadBalancer.Stickiness.CookieName }}"
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
{{if $loadBalancer }}
|
||||
[backends."{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
{{if $loadBalancer }}
|
||||
[backends."{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
{{if $loadBalancer }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
{{if $loadBalancer }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer]
|
||||
method = "{{ $loadBalancer.Method }}"
|
||||
sticky = {{ $loadBalancer.Sticky }}
|
||||
{{if $loadBalancer.Stickiness }}
|
||||
[backends."backend-{{ $backendName }}".loadBalancer.stickiness]
|
||||
cookieName = "{{ $loadBalancer.Stickiness.CookieName }}"
|
||||
|
|
|
@ -25,7 +25,6 @@ type TLS struct {
|
|||
MinVersion string `export:"true"`
|
||||
CipherSuites []string
|
||||
Certificates Certificates
|
||||
ClientCAFiles []string // Deprecated
|
||||
ClientCA ClientCA
|
||||
DefaultCertificate *Certificate
|
||||
SniStrict bool `export:"true"`
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/abronan/valkeyrie/store"
|
||||
"github.com/containous/flaeg"
|
||||
"github.com/containous/flaeg/parse"
|
||||
"github.com/containous/mux"
|
||||
"github.com/containous/traefik/log"
|
||||
traefiktls "github.com/containous/traefik/tls"
|
||||
|
@ -39,7 +39,6 @@ type MaxConn struct {
|
|||
// LoadBalancer holds load balancing configuration.
|
||||
type LoadBalancer struct {
|
||||
Method string `json:"method,omitempty"`
|
||||
Sticky bool `json:"sticky,omitempty"` // Deprecated: use Stickiness instead
|
||||
Stickiness *Stickiness `json:"stickiness,omitempty"`
|
||||
}
|
||||
|
||||
|
@ -108,7 +107,7 @@ type ErrorPage struct {
|
|||
|
||||
// Rate holds a rate limiting configuration for a specific time period
|
||||
type Rate struct {
|
||||
Period flaeg.Duration `json:"period,omitempty"`
|
||||
Period parse.Duration `json:"period,omitempty"`
|
||||
Average int64 `json:"average,omitempty"`
|
||||
Burst int64 `json:"burst,omitempty"`
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue