Merge branch v2.3 into master.

This commit is contained in:
Fernandez Ludovic 2020-11-08 23:46:49 +01:00
commit 520fcf82ae
53 changed files with 1203 additions and 412 deletions

View file

@ -54,7 +54,10 @@
"nestif", # Too many false-positive. "nestif", # Too many false-positive.
"noctx", # Too strict "noctx", # Too strict
"exhaustive", # Too strict "exhaustive", # Too strict
"nlreturn", # Too strict "nlreturn", # Not relevant
"wrapcheck", # Too strict
"tparallel", # Not relevant
"exhaustivestruct", # Not relevant
] ]
[issues] [issues]

View file

@ -19,7 +19,7 @@ RUN mkdir -p /usr/local/bin \
&& chmod +x /usr/local/bin/go-bindata && chmod +x /usr/local/bin/go-bindata
# Download golangci-lint binary to bin folder in $GOPATH # Download golangci-lint binary to bin folder in $GOPATH
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.31.0 RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.32.2
# Download misspell binary to bin folder in $GOPATH # Download misspell binary to bin folder in $GOPATH
RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4 RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4

View file

@ -322,8 +322,9 @@ For complete details, refer to your provider's _Additional configuration_ link.
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) | | HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) |
| [HyperOne](https://www.hyperone.com) | `hyperone` | `HYPERONE_PASSPORT_LOCATION`, `HYPERONE_LOCATION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/hyperone) | | [HyperOne](https://www.hyperone.com) | `hyperone` | `HYPERONE_PASSPORT_LOCATION`, `HYPERONE_LOCATION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/hyperone) |
| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) | | [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) |
| [Infomaniak](https://www.infomaniak.com) | `infomaniak` | `INFOMANIAK_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/infomaniak) |
| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) | | [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) |
| [Joker.com](https://joker.com) | `joker` | `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) | | [Joker.com](https://joker.com) | `joker` | `JOKER_API_MODE` with `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) |
| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) | | [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) |
| [Linode v4](https://www.linode.com) | `linode` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) | | [Linode v4](https://www.linode.com) | `linode` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) |
| [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) | | [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) |

View file

@ -10,7 +10,7 @@ Attach labels to your containers and let Traefik do the rest!
!!! info "labels" !!! info "labels"
- labels are case insensitive. - labels are case insensitive.
- The complete list of labels can be found [the reference page](../../reference/dynamic-configuration/ecs.md) - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/ecs.md).
### General ### General

View file

@ -191,6 +191,7 @@ nav:
- 'Docker': 'reference/dynamic-configuration/docker.md' - 'Docker': 'reference/dynamic-configuration/docker.md'
- 'Kubernetes CRD': 'reference/dynamic-configuration/kubernetes-crd.md' - 'Kubernetes CRD': 'reference/dynamic-configuration/kubernetes-crd.md'
- 'Consul Catalog': 'reference/dynamic-configuration/consul-catalog.md' - 'Consul Catalog': 'reference/dynamic-configuration/consul-catalog.md'
- 'ECS': 'reference/dynamic-configuration/ecs.md'
- 'KV': 'reference/dynamic-configuration/kv.md'
- 'Marathon': 'reference/dynamic-configuration/marathon.md' - 'Marathon': 'reference/dynamic-configuration/marathon.md'
- 'Rancher': 'reference/dynamic-configuration/rancher.md' - 'Rancher': 'reference/dynamic-configuration/rancher.md'
- 'KV': 'reference/dynamic-configuration/kv.md'

View file

@ -37,7 +37,7 @@
<div class="dmi-image proxy"> <div class="dmi-image proxy">
<img src="{{ 'assets/images/traefik-proxy-logo.svg' | url }}" alt="Traefik Proxy" /> <img src="{{ 'assets/images/traefik-proxy-logo.svg' | url }}" alt="Traefik Proxy" />
</div> </div>
<a class="dmi-details" href="https://doc.traefik.io/traefik/"> <a class="dmi-details" href="https://traefik.io/traefik/">
<div class="dmi-title">Traefik Proxy</div> <div class="dmi-title">Traefik Proxy</div>
<div class="dmi-description"> <div class="dmi-description">
Expose, Secure and Monitor your modern applications Expose, Secure and Monitor your modern applications

4
go.mod
View file

@ -34,7 +34,7 @@ require (
github.com/fatih/structs v1.1.0 github.com/fatih/structs v1.1.0
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2
github.com/go-acme/lego/v4 v4.0.1 github.com/go-acme/lego/v4 v4.1.0
github.com/go-check/check v0.0.0-00010101000000-000000000000 github.com/go-check/check v0.0.0-00010101000000-000000000000
github.com/go-kit/kit v0.10.1-0.20200915143503-439c4d2ed3ea github.com/go-kit/kit v0.10.1-0.20200915143503-439c4d2ed3ea
github.com/golang/protobuf v1.4.2 github.com/golang/protobuf v1.4.2
@ -72,7 +72,7 @@ require (
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154
github.com/tinylib/msgp v1.0.2 // indirect github.com/tinylib/msgp v1.0.2 // indirect
github.com/traefik/paerser v0.1.0 github.com/traefik/paerser v0.1.0
github.com/traefik/yaegi v0.9.4 github.com/traefik/yaegi v0.9.5
github.com/uber/jaeger-client-go v2.25.0+incompatible github.com/uber/jaeger-client-go v2.25.0+incompatible
github.com/uber/jaeger-lib v2.2.0+incompatible github.com/uber/jaeger-lib v2.2.0+incompatible
github.com/unrolled/render v1.0.2 github.com/unrolled/render v1.0.2

9
go.sum
View file

@ -286,8 +286,8 @@ github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLy
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-acme/lego/v4 v4.0.1 h1:vPwbTYfw5+fOaON9rWCN43iNrPw5cdJBhNMnA8oxBTM= github.com/go-acme/lego/v4 v4.1.0 h1:/9pMjaeaLq6m0n+io+kv2ySs2ZfrmH6eazuMoN18GHo=
github.com/go-acme/lego/v4 v4.0.1/go.mod h1:pIFm5tWkXSgiAEfJ/XQCQIvX1cEvHFwbgLZyx8OVSUE= github.com/go-acme/lego/v4 v4.1.0/go.mod h1:pIFm5tWkXSgiAEfJ/XQCQIvX1cEvHFwbgLZyx8OVSUE=
github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s= github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
@ -788,8 +788,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/traefik/paerser v0.1.0 h1:B4v1tbvd8YnHsA7spwHKEWJoGrRP+2jYpIozsCMHhl0= github.com/traefik/paerser v0.1.0 h1:B4v1tbvd8YnHsA7spwHKEWJoGrRP+2jYpIozsCMHhl0=
github.com/traefik/paerser v0.1.0/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE= github.com/traefik/paerser v0.1.0/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE=
github.com/traefik/yaegi v0.9.4 h1:ZyxSsvpzZTTTbvE2ODjRkOvq6kYT3dIZDqUfCZJYDtw= github.com/traefik/yaegi v0.9.5 h1:mRJtmV6t/wecIq6Gfs0DpdSC2AjFpPRjoiBXP03OIz0=
github.com/traefik/yaegi v0.9.4/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk= github.com/traefik/yaegi v0.9.5/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk=
github.com/transip/gotransip/v6 v6.2.0 h1:0Z+qVsyeiQdWfcAUeJyF0IEKAPvhJwwpwPi2WGtBIiE= github.com/transip/gotransip/v6 v6.2.0 h1:0Z+qVsyeiQdWfcAUeJyF0IEKAPvhJwwpwPi2WGtBIiE=
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
@ -1146,6 +1146,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=

View file

@ -1,5 +1,5 @@
pebble: pebble:
image: letsencrypt/pebble:2018-11-02 image: letsencrypt/pebble:v2.3.1
command: pebble --dnsserver ${DOCKER_HOST_IP}:5053 command: pebble --dnsserver ${DOCKER_HOST_IP}:5053
ports: ports:
- 14000:14000 - 14000:14000

View file

@ -1,5 +1,5 @@
haproxy: haproxy:
image: haproxy image: haproxy:2.2
volumes: volumes:
- ../haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg - ../haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg

View file

@ -80,6 +80,7 @@ func doOnStruct(field reflect.Value) error {
} }
} }
} }
return nil return nil
} }
@ -107,8 +108,17 @@ func reset(field reflect.Value, name string) error {
} }
case reflect.Slice: case reflect.Slice:
if field.Len() > 0 { if field.Len() > 0 {
switch field.Type().Elem().Kind() {
case reflect.String:
slice := reflect.MakeSlice(field.Type(), field.Len(), field.Len())
for j := 0; j < field.Len(); j++ {
slice.Index(j).SetString(maskShort)
}
field.Set(slice)
default:
field.Set(reflect.MakeSlice(field.Type(), 0, 0)) field.Set(reflect.MakeSlice(field.Type(), 0, 0))
} }
}
case reflect.Interface: case reflect.Interface:
if !field.IsNil() { if !field.IsNil() {
return reset(field.Elem(), "") return reset(field.Elem(), "")

View file

@ -1,21 +1,39 @@
package anonymize package anonymize
import ( import (
"flag"
"io/ioutil"
"os" "os"
"strings"
"testing" "testing"
"time" "time"
assetfs "github.com/elazarl/go-bindata-assetfs" assetfs "github.com/elazarl/go-bindata-assetfs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
ptypes "github.com/traefik/paerser/types" ptypes "github.com/traefik/paerser/types"
"github.com/traefik/traefik/v2/pkg/config/static" "github.com/traefik/traefik/v2/pkg/config/static"
"github.com/traefik/traefik/v2/pkg/ping" "github.com/traefik/traefik/v2/pkg/ping"
"github.com/traefik/traefik/v2/pkg/plugins"
"github.com/traefik/traefik/v2/pkg/provider/acme" "github.com/traefik/traefik/v2/pkg/provider/acme"
"github.com/traefik/traefik/v2/pkg/provider/consulcatalog"
"github.com/traefik/traefik/v2/pkg/provider/docker" "github.com/traefik/traefik/v2/pkg/provider/docker"
"github.com/traefik/traefik/v2/pkg/provider/ecs"
"github.com/traefik/traefik/v2/pkg/provider/file" "github.com/traefik/traefik/v2/pkg/provider/file"
"github.com/traefik/traefik/v2/pkg/provider/http"
"github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd"
"github.com/traefik/traefik/v2/pkg/provider/kubernetes/ingress" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/ingress"
"github.com/traefik/traefik/v2/pkg/provider/kv"
"github.com/traefik/traefik/v2/pkg/provider/kv/consul"
"github.com/traefik/traefik/v2/pkg/provider/kv/etcd"
"github.com/traefik/traefik/v2/pkg/provider/kv/redis"
"github.com/traefik/traefik/v2/pkg/provider/kv/zk"
"github.com/traefik/traefik/v2/pkg/provider/marathon"
"github.com/traefik/traefik/v2/pkg/provider/rancher"
"github.com/traefik/traefik/v2/pkg/provider/rest"
traefiktls "github.com/traefik/traefik/v2/pkg/tls" traefiktls "github.com/traefik/traefik/v2/pkg/tls"
"github.com/traefik/traefik/v2/pkg/tracing/datadog" "github.com/traefik/traefik/v2/pkg/tracing/datadog"
"github.com/traefik/traefik/v2/pkg/tracing/elastic"
"github.com/traefik/traefik/v2/pkg/tracing/haystack" "github.com/traefik/traefik/v2/pkg/tracing/haystack"
"github.com/traefik/traefik/v2/pkg/tracing/instana" "github.com/traefik/traefik/v2/pkg/tracing/instana"
"github.com/traefik/traefik/v2/pkg/tracing/jaeger" "github.com/traefik/traefik/v2/pkg/tracing/jaeger"
@ -23,6 +41,8 @@ import (
"github.com/traefik/traefik/v2/pkg/types" "github.com/traefik/traefik/v2/pkg/types"
) )
var updateExpected = flag.Bool("update_expected", false, "Update expected files in fixtures")
func TestDo_globalConfiguration(t *testing.T) { func TestDo_globalConfiguration(t *testing.T) {
config := &static.Configuration{} config := &static.Configuration{}
@ -31,39 +51,25 @@ func TestDo_globalConfiguration(t *testing.T) {
SendAnonymousUsage: true, SendAnonymousUsage: true,
} }
config.AccessLog = &types.AccessLog{ config.ServersTransport = &static.ServersTransport{
FilePath: "AccessLog FilePath", InsecureSkipVerify: true,
Format: "AccessLog Format", RootCAs: []traefiktls.FileOrContent{"root.ca"},
Filters: &types.AccessLogFilters{ MaxIdleConnsPerHost: 42,
StatusCodes: []string{"200", "500"}, ForwardingTimeouts: &static.ForwardingTimeouts{
RetryAttempts: true, DialTimeout: 42,
MinDuration: 10, ResponseHeaderTimeout: 42,
IdleConnTimeout: 42,
}, },
Fields: &types.AccessLogFields{
DefaultMode: "drop",
Names: map[string]string{
"RequestHost": "keep",
},
Headers: &types.FieldHeaders{
DefaultMode: "drop",
Names: map[string]string{
"Referer": "keep",
},
},
},
BufferingSize: 4,
}
config.Log = &types.TraefikLog{
Level: "Level",
FilePath: "/foo/path",
Format: "json",
} }
config.EntryPoints = static.EntryPoints{ config.EntryPoints = static.EntryPoints{
"foo": { "foobar": {
Address: "foo Address", Address: "foo Address",
Transport: &static.EntryPointsTransport{ Transport: &static.EntryPointsTransport{
LifeCycle: &static.LifeCycle{
RequestAcceptGraceTimeout: ptypes.Duration(111 * time.Second),
GraceTimeOut: ptypes.Duration(111 * time.Second),
},
RespondingTimeouts: &static.RespondingTimeouts{ RespondingTimeouts: &static.RespondingTimeouts{
ReadTimeout: ptypes.Duration(111 * time.Second), ReadTimeout: ptypes.Duration(111 * time.Second),
WriteTimeout: ptypes.Duration(111 * time.Second), WriteTimeout: ptypes.Duration(111 * time.Second),
@ -71,38 +77,34 @@ func TestDo_globalConfiguration(t *testing.T) {
}, },
}, },
ProxyProtocol: &static.ProxyProtocol{ ProxyProtocol: &static.ProxyProtocol{
Insecure: true,
TrustedIPs: []string{"127.0.0.1/32", "192.168.0.1"}, TrustedIPs: []string{"127.0.0.1/32", "192.168.0.1"},
}, },
}, ForwardedHeaders: &static.ForwardedHeaders{
"fii": { Insecure: true,
Address: "fii Address",
Transport: &static.EntryPointsTransport{
RespondingTimeouts: &static.RespondingTimeouts{
ReadTimeout: ptypes.Duration(111 * time.Second),
WriteTimeout: ptypes.Duration(111 * time.Second),
IdleTimeout: ptypes.Duration(111 * time.Second),
},
},
ProxyProtocol: &static.ProxyProtocol{
TrustedIPs: []string{"127.0.0.1/32", "192.168.0.1"}, TrustedIPs: []string{"127.0.0.1/32", "192.168.0.1"},
}, },
HTTP: static.HTTPConfig{
Redirections: &static.Redirections{
EntryPoint: &static.RedirectEntryPoint{
To: "foobar",
Scheme: "foobar",
Permanent: true,
Priority: 42,
},
},
Middlewares: []string{"foobar", "foobar"},
TLS: &static.TLSConfig{
Options: "foobar",
CertResolver: "foobar",
Domains: []types.Domain{
{Main: "foobar", SANs: []string{"foobar", "foobar"}},
},
},
},
}, },
} }
config.CertificatesResolvers = map[string]static.CertificateResolver{
"default": {
ACME: &acme.Configuration{
Email: "acme Email",
CAServer: "CAServer",
Storage: "Storage",
KeyType: "MyKeyType",
DNSChallenge: &acme.DNSChallenge{Provider: "DNSProvider"},
HTTPChallenge: &acme.HTTPChallenge{
EntryPoint: "MyEntryPoint",
},
TLSChallenge: &acme.TLSChallenge{},
},
},
}
config.Providers = &static.Providers{ config.Providers = &static.Providers{
ProvidersThrottleDuration: ptypes.Duration(111 * time.Second), ProvidersThrottleDuration: ptypes.Duration(111 * time.Second),
} }
@ -114,22 +116,7 @@ func TestDo_globalConfiguration(t *testing.T) {
ForwardingTimeouts: &static.ForwardingTimeouts{ ForwardingTimeouts: &static.ForwardingTimeouts{
DialTimeout: ptypes.Duration(111 * time.Second), DialTimeout: ptypes.Duration(111 * time.Second),
ResponseHeaderTimeout: ptypes.Duration(111 * time.Second), ResponseHeaderTimeout: ptypes.Duration(111 * time.Second),
}, IdleConnTimeout: ptypes.Duration(111 * time.Second),
}
config.API = &static.API{
Dashboard: true,
DashboardAssets: &assetfs.AssetFS{
Asset: func(path string) ([]byte, error) {
return nil, nil
},
AssetDir: func(path string) ([]string, error) {
return nil, nil
},
AssetInfo: func(path string) (os.FileInfo, error) {
return nil, nil
},
Prefix: "fii",
}, },
} }
@ -160,6 +147,33 @@ func TestDo_globalConfiguration(t *testing.T) {
HTTPClientTimeout: 42, HTTPClientTimeout: 42,
} }
config.Providers.Marathon = &marathon.Provider{
Constraints: `Label("foo", "bar")`,
Trace: true,
Watch: true,
Endpoint: "foobar",
DefaultRule: "PathPrefix(`/`)",
ExposedByDefault: true,
DCOSToken: "foobar",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
Cert: "mycert.pem",
Key: "mycert.key",
InsecureSkipVerify: true,
},
DialerTimeout: 42,
ResponseHeaderTimeout: 42,
TLSHandshakeTimeout: 42,
KeepAlive: 42,
ForceTaskHostname: true,
Basic: &marathon.Basic{
HTTPBasicAuthUser: "user",
HTTPBasicPassword: "password",
},
RespectReadinessChecks: true,
}
config.Providers.KubernetesIngress = &ingress.Provider{ config.Providers.KubernetesIngress = &ingress.Provider{
Endpoint: "MyEndpoint", Endpoint: "MyEndpoint",
Token: "MyToken", Token: "MyToken",
@ -168,6 +182,12 @@ func TestDo_globalConfiguration(t *testing.T) {
Namespaces: []string{"a", "b"}, Namespaces: []string{"a", "b"},
LabelSelector: "myLabelSelector", LabelSelector: "myLabelSelector",
IngressClass: "MyIngressClass", IngressClass: "MyIngressClass",
IngressEndpoint: &ingress.EndpointIngress{
IP: "IP",
Hostname: "Hostname",
PublishedService: "PublishedService",
},
ThrottleDuration: ptypes.Duration(111 * time.Second),
} }
config.Providers.KubernetesCRD = &crd.Provider{ config.Providers.KubernetesCRD = &crd.Provider{
@ -178,83 +198,343 @@ func TestDo_globalConfiguration(t *testing.T) {
Namespaces: []string{"a", "b"}, Namespaces: []string{"a", "b"},
LabelSelector: "myLabelSelector", LabelSelector: "myLabelSelector",
IngressClass: "MyIngressClass", IngressClass: "MyIngressClass",
ThrottleDuration: ptypes.Duration(111 * time.Second),
} }
// FIXME Test the other providers once they are migrated config.Providers.Rest = &rest.Provider{
Insecure: true,
}
config.Providers.Rancher = &rancher.Provider{
Constraints: `Label("foo", "bar")`,
Watch: true,
DefaultRule: "PathPrefix(`/`)",
ExposedByDefault: true,
EnableServiceHealthFilter: true,
RefreshSeconds: 42,
IntervalPoll: true,
Prefix: "MyPrefix",
}
config.Providers.ConsulCatalog = &consulcatalog.Provider{
Constraints: `Label("foo", "bar")`,
Endpoint: &consulcatalog.EndpointConfig{
Address: "MyAddress",
Scheme: "MyScheme",
DataCenter: "MyDatacenter",
Token: "MyToken",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
Cert: "mycert.pem",
Key: "mycert.key",
InsecureSkipVerify: true,
},
HTTPAuth: &consulcatalog.EndpointHTTPAuthConfig{
Username: "MyUsername",
Password: "MyPassword",
},
EndpointWaitTime: 42,
},
Prefix: "MyPrefix",
RefreshInterval: 42,
RequireConsistent: true,
Stale: true,
Cache: true,
ExposedByDefault: true,
DefaultRule: "PathPrefix(`/`)",
}
config.Providers.Ecs = &ecs.Provider{
Constraints: `Label("foo", "bar")`,
ExposedByDefault: true,
RefreshSeconds: 42,
DefaultRule: "PathPrefix(`/`)",
Clusters: []string{"Cluster1", "Cluster2"},
AutoDiscoverClusters: true,
Region: "Awsregion",
AccessKeyID: "AwsAccessKeyID",
SecretAccessKey: "AwsSecretAccessKey",
}
config.Providers.Consul = &consul.Provider{
Provider: kv.Provider{
RootKey: "RootKey",
Endpoints: nil,
Username: "username",
Password: "password",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
Cert: "mycert.pem",
Key: "mycert.key",
InsecureSkipVerify: true,
},
},
}
config.Providers.Etcd = &etcd.Provider{
Provider: kv.Provider{
RootKey: "RootKey",
Endpoints: nil,
Username: "username",
Password: "password",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
Cert: "mycert.pem",
Key: "mycert.key",
InsecureSkipVerify: true,
},
},
}
config.Providers.ZooKeeper = &zk.Provider{
Provider: kv.Provider{
RootKey: "RootKey",
Endpoints: nil,
Username: "username",
Password: "password",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
Cert: "mycert.pem",
Key: "mycert.key",
InsecureSkipVerify: true,
},
},
}
config.Providers.Redis = &redis.Provider{
Provider: kv.Provider{
RootKey: "RootKey",
Endpoints: nil,
Username: "username",
Password: "password",
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
Cert: "mycert.pem",
Key: "mycert.key",
InsecureSkipVerify: true,
},
},
}
config.Providers.HTTP = &http.Provider{
Endpoint: "Myenpoint",
PollInterval: 42,
PollTimeout: 42,
TLS: &types.ClientTLS{
CA: "myCa",
CAOptional: true,
Cert: "mycert.pem",
Key: "mycert.key",
InsecureSkipVerify: true,
},
}
config.API = &static.API{
Insecure: true,
Dashboard: true,
Debug: true,
DashboardAssets: &assetfs.AssetFS{
Asset: func(path string) ([]byte, error) {
return nil, nil
},
AssetDir: func(path string) ([]string, error) {
return nil, nil
},
AssetInfo: func(path string) (os.FileInfo, error) {
return nil, nil
},
Prefix: "fii",
},
}
config.Metrics = &types.Metrics{ config.Metrics = &types.Metrics{
Prometheus: &types.Prometheus{ Prometheus: &types.Prometheus{
Buckets: []float64{0.1, 0.3, 1.2, 5}, Buckets: []float64{0.1, 0.3, 1.2, 5},
AddEntryPointsLabels: true,
AddServicesLabels: true,
EntryPoint: "MyEntryPoint",
ManualRouting: true,
}, },
Datadog: &types.Datadog{ Datadog: &types.Datadog{
Address: "localhost:8181", Address: "localhost:8181",
PushInterval: 12, PushInterval: 42,
AddEntryPointsLabels: true,
AddServicesLabels: true,
}, },
StatsD: &types.Statsd{ StatsD: &types.Statsd{
Address: "localhost:8182", Address: "localhost:8182",
PushInterval: 42, PushInterval: 42,
AddEntryPointsLabels: true,
AddServicesLabels: true,
Prefix: "MyPrefix",
}, },
InfluxDB: &types.InfluxDB{ InfluxDB: &types.InfluxDB{
Address: "localhost:8183", Address: "localhost:8183",
Protocol: "http", Protocol: "http",
PushInterval: 22, PushInterval: 42,
Database: "myDB", Database: "myDB",
RetentionPolicy: "12", RetentionPolicy: "12",
Username: "a", Username: "a",
Password: "aaaa", Password: "aaaa",
AddEntryPointsLabels: true,
AddServicesLabels: true,
}, },
} }
config.Ping = &ping.Handler{} config.Ping = &ping.Handler{
EntryPoint: "MyEntryPoint",
ManualRouting: true,
TerminatingStatusCode: 42,
}
config.Log = &types.TraefikLog{
Level: "Level",
FilePath: "/foo/path",
Format: "json",
}
config.AccessLog = &types.AccessLog{
FilePath: "AccessLog FilePath",
Format: "AccessLog Format",
Filters: &types.AccessLogFilters{
StatusCodes: []string{"200", "500"},
RetryAttempts: true,
MinDuration: 42,
},
Fields: &types.AccessLogFields{
DefaultMode: "drop",
Names: map[string]string{
"RequestHost": "keep",
},
Headers: &types.FieldHeaders{
DefaultMode: "drop",
Names: map[string]string{
"Referer": "keep",
},
},
},
BufferingSize: 42,
}
config.Tracing = &static.Tracing{ config.Tracing = &static.Tracing{
ServiceName: "myServiceName", ServiceName: "myServiceName",
SpanNameLimit: 3, SpanNameLimit: 42,
Jaeger: &jaeger.Config{ Jaeger: &jaeger.Config{
SamplingServerURL: "aaa", SamplingServerURL: "foobar",
SamplingType: "bbb", SamplingType: "foobar",
SamplingParam: 43, SamplingParam: 42,
LocalAgentHostPort: "ccc", LocalAgentHostPort: "foobar",
Gen128Bit: true, Gen128Bit: true,
Propagation: "ddd", Propagation: "foobar",
TraceContextHeaderName: "eee", TraceContextHeaderName: "foobar",
Collector: &jaeger.Collector{
Endpoint: "foobar",
User: "foobar",
Password: "foobar",
},
DisableAttemptReconnecting: true,
}, },
Zipkin: &zipkin.Config{ Zipkin: &zipkin.Config{
HTTPEndpoint: "fff", HTTPEndpoint: "foobar",
SameSpan: true, SameSpan: true,
ID128Bit: true, ID128Bit: true,
SampleRate: 53, SampleRate: 42,
}, },
Datadog: &datadog.Config{ Datadog: &datadog.Config{
LocalAgentHostPort: "ggg", LocalAgentHostPort: "foobar",
GlobalTag: "eee", GlobalTag: "foobar",
Debug: true, Debug: true,
PrioritySampling: true, PrioritySampling: true,
TraceIDHeaderName: "foobar",
ParentIDHeaderName: "foobar",
SamplingPriorityHeaderName: "foobar",
BagagePrefixHeaderName: "foobar",
}, },
Instana: &instana.Config{ Instana: &instana.Config{
LocalAgentHost: "fff", LocalAgentHost: "foobar",
LocalAgentPort: 32, LocalAgentPort: 4242,
LogLevel: "ggg", LogLevel: "foobar",
}, },
Haystack: &haystack.Config{ Haystack: &haystack.Config{
LocalAgentHost: "fff", LocalAgentHost: "foobar",
LocalAgentPort: 32, LocalAgentPort: 42,
GlobalTag: "eee", GlobalTag: "foobar",
TraceIDHeaderName: "fff", TraceIDHeaderName: "foobar",
ParentIDHeaderName: "ggg", ParentIDHeaderName: "foobar",
SpanIDHeaderName: "hhh", SpanIDHeaderName: "foobar",
BaggagePrefixHeaderName: "iii", BaggagePrefixHeaderName: "foobar",
},
Elastic: &elastic.Config{
ServerURL: "foobar",
SecretToken: "foobar",
ServiceEnvironment: "foobar",
}, },
} }
config.HostResolver = &types.HostResolverConfig{ config.HostResolver = &types.HostResolverConfig{
CnameFlattening: true, CnameFlattening: true,
ResolvConfig: "aaa", ResolvConfig: "foobar",
ResolvDepth: 3, ResolvDepth: 42,
} }
config.CertificatesResolvers = map[string]static.CertificateResolver{
"CertificateResolver0": {
ACME: &acme.Configuration{
Email: "acme Email",
CAServer: "CAServer",
PreferredChain: "foobar",
Storage: "Storage",
KeyType: "MyKeyType",
DNSChallenge: &acme.DNSChallenge{
Provider: "DNSProvider",
DelayBeforeCheck: 42,
Resolvers: []string{"resolver1", "resolver2"},
DisablePropagationCheck: true,
},
HTTPChallenge: &acme.HTTPChallenge{
EntryPoint: "MyEntryPoint",
},
TLSChallenge: &acme.TLSChallenge{},
},
},
}
config.Pilot = &static.Pilot{
Token: "token",
}
config.Experimental = &static.Experimental{
Plugins: map[string]plugins.Descriptor{
"Descriptor0": {
ModuleName: "foobar",
Version: "foobar",
},
"Descriptor1": {
ModuleName: "foobar",
Version: "foobar",
},
},
DevPlugin: &plugins.DevPlugin{
GoPath: "foobar",
ModuleName: "foobar",
},
}
expectedConfiguration, err := ioutil.ReadFile("./testdata/anonymized-static-config.json")
require.NoError(t, err)
cleanJSON, err := Do(config, true) cleanJSON, err := Do(config, true)
if err != nil { require.NoError(t, err)
t.Fatal(err, cleanJSON)
if *updateExpected {
require.NoError(t, ioutil.WriteFile("testdata/anonymized-static-config.json", []byte(cleanJSON), 0666))
} }
expected := strings.TrimSuffix(string(expectedConfiguration), "\n")
assert.Equal(t, expected, cleanJSON)
} }

View file

@ -1,185 +1,23 @@
package anonymize package anonymize
import ( import (
"io/ioutil"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func Test_doOnJSON(t *testing.T) { func Test_doOnJSON(t *testing.T) {
baseConfiguration := ` baseConfiguration, err := ioutil.ReadFile("./testdata/example.json")
{ require.NoError(t, err)
"GraceTimeOut": 10000000000,
"Debug": false,
"CheckNewVersion": true,
"AccessLogsFile": "",
"TraefikLogsFile": "",
"Level": "ERROR",
"EntryPoints": {
"http": {
"Network": "",
"Address": ":80",
"TLS": null,
"Auth": null,
"Compress": false
},
"https": {
"Address": ":443",
"TLS": {
"MinVersion": "",
"CipherSuites": null,
"Certificates": null,
"ClientCAFiles": null
},
"Auth": null,
"Compress": false
}
},
"Cluster": null,
"Constraints": [],
"ACME": {
"Email": "foo@bar.com",
"Domains": [
{
"Main": "foo@bar.com",
"SANs": null
},
{
"Main": "foo@bar.com",
"SANs": null
}
],
"Storage": "",
"StorageFile": "/acme/acme.json",
"OnDemand": true,
"OnHostRule": true,
"CAServer": "",
"EntryPoint": "https",
"DNSProvider": "",
"DelayDontCheckDNS": 0,
"ACMELogging": false,
"Options": null
},
"DefaultEntryPoints": [
"https",
"http"
],
"ProvidersThrottleDuration": 2000000000,
"MaxIdleConnsPerHost": 200,
"IdleTimeout": 180000000000,
"InsecureSkipVerify": false,
"Retry": null,
"HealthCheck": {
"Interval": 30000000000
},
"Docker": null,
"File": null,
"Web": null,
"Marathon": null,
"Consul": null,
"ConsulCatalog": null,
"Etcd": null,
"Zookeeper": null,
"Boltdb": null,
"KubernetesIngress": null,
"KubernetesCRD": null,
"Mesos": null,
"Eureka": null,
"ECS": null,
"Rancher": null,
"DynamoDB": null,
"ConfigFile": "/etc/traefik/traefik.toml"
}
`
expectedConfiguration := `
{
"GraceTimeOut": 10000000000,
"Debug": false,
"CheckNewVersion": true,
"AccessLogsFile": "",
"TraefikLogsFile": "",
"Level": "ERROR",
"EntryPoints": {
"http": {
"Network": "",
"Address": ":80",
"TLS": null,
"Auth": null,
"Compress": false
},
"https": {
"Address": ":443",
"TLS": {
"MinVersion": "",
"CipherSuites": null,
"Certificates": null,
"ClientCAFiles": null
},
"Auth": null,
"Compress": false
}
},
"Cluster": null,
"Constraints": [],
"ACME": {
"Email": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"Domains": [
{
"Main": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"SANs": null
},
{
"Main": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"SANs": null
}
],
"Storage": "",
"StorageFile": "/acme/acme.json",
"OnDemand": true,
"OnHostRule": true,
"CAServer": "",
"EntryPoint": "https",
"DNSProvider": "",
"DelayDontCheckDNS": 0,
"ACMELogging": false,
"Options": null
},
"DefaultEntryPoints": [
"https",
"http"
],
"ProvidersThrottleDuration": 2000000000,
"MaxIdleConnsPerHost": 200,
"IdleTimeout": 180000000000,
"InsecureSkipVerify": false,
"Retry": null,
"HealthCheck": {
"Interval": 30000000000
},
"Docker": null,
"File": null,
"Web": null,
"Marathon": null,
"Consul": null,
"ConsulCatalog": null,
"Etcd": null,
"Zookeeper": null,
"Boltdb": null,
"KubernetesIngress": null,
"KubernetesCRD": null,
"Mesos": null,
"Eureka": null,
"ECS": null,
"Rancher": null,
"DynamoDB": null,
"ConfigFile": "/etc/traefik/traefik.toml"
}
`
anomConfiguration := doOnJSON(baseConfiguration)
if anomConfiguration != expectedConfiguration { anomConfiguration := doOnJSON(string(baseConfiguration))
t.Errorf("Got %s, want %s.", anomConfiguration, expectedConfiguration)
} expectedConfiguration, err := ioutil.ReadFile("./testdata/expected.json")
require.NoError(t, err)
assert.JSONEq(t, string(expectedConfiguration), anomConfiguration)
} }
func Test_doOnJSON_simple(t *testing.T) { func Test_doOnJSON_simple(t *testing.T) {

View file

@ -20,6 +20,8 @@ type Tomate struct {
type Carotte struct { type Carotte struct {
Name string Name string
Value int Value int
List []string
EList []string `export:"true"`
Courgette Courgette Courgette Courgette
ECourgette Courgette `export:"true"` ECourgette Courgette `export:"true"`
Pourgette *Courgette Pourgette *Courgette
@ -44,9 +46,13 @@ func Test_doOnStruct(t *testing.T) {
base: &Carotte{ base: &Carotte{
Name: "koko", Name: "koko",
Value: 666, Value: 666,
List: []string{"test"},
EList: []string{"test"},
}, },
expected: &Carotte{ expected: &Carotte{
Name: "xxxx", Name: "xxxx",
List: []string{"xxxx"},
EList: []string{"test"},
}, },
}, },
{ {

View file

@ -0,0 +1,455 @@
{
"global": {
"checkNewVersion": true,
"sendAnonymousUsage": true
},
"serversTransport": {
"insecureSkipVerify": true,
"rootCAs": [
"xxxx",
"xxxx",
"xxxx"
],
"maxIdleConnsPerHost": 111,
"forwardingTimeouts": {
"dialTimeout": 111000000000,
"responseHeaderTimeout": 111000000000,
"idleConnTimeout": 111000000000
}
},
"entryPoints": {
"foobar": {
"address": "xxxx",
"transport": {
"lifeCycle": {
"requestAcceptGraceTimeout": 111000000000,
"graceTimeOut": 111000000000
},
"respondingTimeouts": {
"readTimeout": 111000000000,
"writeTimeout": 111000000000,
"idleTimeout": 111000000000
}
},
"proxyProtocol": {
"insecure": true,
"trustedIPs": [
"xxxx",
"xxxx"
]
},
"forwardedHeaders": {
"insecure": true,
"trustedIPs": [
"xxxx",
"xxxx"
]
},
"http": {
"redirections": {
"entryPoint": {
"to": "foobar",
"scheme": "foobar",
"permanent": true,
"priority": 42
}
},
"middlewares": [
"foobar",
"foobar"
],
"tls": {
"options": "foobar",
"certResolver": "foobar",
"domains": [
{
"main": "xxxx",
"sans": [
"xxxx",
"xxxx"
]
}
]
}
}
}
},
"providers": {
"providersThrottleDuration": 111000000000,
"docker": {
"constraints": "Label(\"foo\", \"bar\")",
"watch": true,
"endpoint": "xxxx",
"defaultRule": "xxxx",
"tls": {
"ca": "xxxx",
"caOptional": true,
"cert": "xxxx",
"key": "xxxx",
"insecureSkipVerify": true
},
"exposedByDefault": true,
"useBindPortIP": true,
"swarmMode": true,
"network": "MyNetwork",
"swarmModeRefreshSeconds": 42,
"httpClientTimeout": 42
},
"file": {
"directory": "file Directory",
"watch": true,
"filename": "file Filename",
"debugLogGeneratedTemplate": true
},
"marathon": {
"constraints": "Label(\"foo\", \"bar\")",
"trace": true,
"watch": true,
"endpoint": "xxxx",
"defaultRule": "xxxx",
"exposedByDefault": true,
"dcosToken": "xxxx",
"tls": {
"ca": "xxxx",
"caOptional": true,
"cert": "xxxx",
"key": "xxxx",
"insecureSkipVerify": true
},
"dialerTimeout": 42,
"responseHeaderTimeout": 42,
"tlsHandshakeTimeout": 42,
"keepAlive": 42,
"forceTaskHostname": true,
"basic": {
"httpBasicAuthUser": "xxxx",
"httpBasicPassword": "xxxx"
},
"respectReadinessChecks": true
},
"kubernetesIngress": {
"endpoint": "xxxx",
"token": "xxxx",
"certAuthFilePath": "xxxx",
"disablePassHostHeaders": true,
"namespaces": [
"a",
"b"
],
"labelSelector": "myLabelSelector",
"ingressClass": "MyIngressClass",
"ingressEndpoint": {
"ip": "xxxx",
"hostname": "xxxx",
"publishedService": "xxxx"
},
"throttleDuration": 111000000000
},
"kubernetesCRD": {
"endpoint": "xxxx",
"token": "xxxx",
"certAuthFilePath": "xxxx",
"disablePassHostHeaders": true,
"namespaces": [
"a",
"b"
],
"labelSelector": "myLabelSelector",
"ingressClass": "MyIngressClass",
"throttleDuration": 111000000000
},
"rest": {
"insecure": true
},
"rancher": {
"constraints": "Label(\"foo\", \"bar\")",
"watch": true,
"defaultRule": "xxxx",
"exposedByDefault": true,
"enableServiceHealthFilter": true,
"refreshSeconds": 42,
"intervalPoll": true,
"prefix": "xxxx"
},
"consulCatalog": {
"constraints": "Label(\"foo\", \"bar\")",
"endpoint": {
"address": "xxxx",
"scheme": "xxxx",
"datacenter": "xxxx",
"token": "xxxx",
"tls": {
"ca": "xxxx",
"caOptional": true,
"cert": "xxxx",
"key": "xxxx",
"insecureSkipVerify": true
},
"httpAuth": {
"username": "xxxx",
"password": "xxxx"
},
"endpointWaitTime": 42
},
"prefix": "MyPrefix",
"refreshInterval": 42,
"requireConsistent": true,
"stale": true,
"cache": true,
"exposedByDefault": true,
"defaultRule": "xxxx"
},
"ecs": {
"constraints": "Label(\"foo\", \"bar\")",
"exposedByDefault": true,
"refreshSeconds": 42,
"defaultRule": "xxxx",
"clusters": [
"Cluster1",
"Cluster2"
],
"autoDiscoverClusters": true,
"region": "Awsregion",
"accessKeyID": "xxxx",
"secretAccessKey": "xxxx"
},
"consul": {
"rootKey": "RootKey",
"username": "xxxx",
"password": "xxxx",
"tls": {
"ca": "xxxx",
"caOptional": true,
"cert": "xxxx",
"key": "xxxx",
"insecureSkipVerify": true
}
},
"etcd": {
"rootKey": "RootKey",
"username": "xxxx",
"password": "xxxx",
"tls": {
"ca": "xxxx",
"caOptional": true,
"cert": "xxxx",
"key": "xxxx",
"insecureSkipVerify": true
}
},
"zooKeeper": {
"rootKey": "RootKey",
"username": "xxxx",
"password": "xxxx",
"tls": {
"ca": "xxxx",
"caOptional": true,
"cert": "xxxx",
"key": "xxxx",
"insecureSkipVerify": true
}
},
"redis": {
"rootKey": "RootKey",
"username": "xxxx",
"password": "xxxx",
"tls": {
"ca": "xxxx",
"caOptional": true,
"cert": "xxxx",
"key": "xxxx",
"insecureSkipVerify": true
}
},
"http": {
"endpoint": "xxxx",
"pollInterval": 42,
"pollTimeout": 42,
"tls": {
"ca": "xxxx",
"caOptional": true,
"cert": "xxxx",
"key": "xxxx",
"insecureSkipVerify": true
}
}
},
"api": {
"insecure": true,
"dashboard": true,
"debug": true
},
"metrics": {
"prometheus": {
"buckets": [
0.1,
0.3,
1.2,
5
],
"addEntryPointsLabels": true,
"addServicesLabels": true,
"entryPoint": "MyEntryPoint",
"manualRouting": true
},
"datadog": {
"address": "xxxx",
"pushInterval": 42,
"addEntryPointsLabels": true,
"addServicesLabels": true
},
"statsD": {
"address": "xxxx",
"pushInterval": 42,
"addEntryPointsLabels": true,
"addServicesLabels": true,
"prefix": "MyPrefix"
},
"influxDB": {
"address": "xxxx",
"protocol": "xxxx",
"pushInterval": 42,
"database": "myDB",
"retentionPolicy": "12",
"username": "xxxx",
"password": "xxxx",
"addEntryPointsLabels": true,
"addServicesLabels": true
}
},
"ping": {
"entryPoint": "MyEntryPoint",
"manualRouting": true,
"terminatingStatusCode": 42
},
"log": {
"level": "Level",
"filePath": "xxxx",
"format": "json"
},
"accessLog": {
"filePath": "xxxx",
"format": "AccessLog Format",
"filters": {
"statusCodes": [
"200",
"500"
],
"retryAttempts": true,
"minDuration": 42
},
"fields": {
"defaultMode": "drop",
"names": {
"RequestHost": "keep"
},
"headers": {
"defaultMode": "drop",
"names": {
"Referer": "keep"
}
}
},
"bufferingSize": 42
},
"tracing": {
"serviceName": "myServiceName",
"spanNameLimit": 42,
"jaeger": {
"samplingServerURL": "xxxx",
"samplingType": "foobar",
"samplingParam": 42,
"localAgentHostPort": "xxxx",
"gen128Bit": true,
"propagation": "foobar",
"traceContextHeaderName": "foobar",
"collector": {
"endpoint": "xxxx",
"user": "xxxx",
"password": "xxxx"
},
"disableAttemptReconnecting": true
},
"zipkin": {
"httpEndpoint": "xxxx",
"sameSpan": true,
"id128Bit": true,
"sampleRate": 42
},
"datadog": {
"localAgentHostPort": "xxxx",
"globalTag": "foobar",
"debug": true,
"prioritySampling": true,
"traceIDHeaderName": "foobar",
"parentIDHeaderName": "foobar",
"samplingPriorityHeaderName": "foobar",
"bagagePrefixHeaderName": "foobar"
},
"instana": {
"localAgentHost": "xxxx",
"logLevel": "foobar"
},
"haystack": {
"localAgentHost": "xxxx",
"globalTag": "foobar",
"traceIDHeaderName": "foobar",
"parentIDHeaderName": "foobar",
"spanIDHeaderName": "foobar",
"baggagePrefixHeaderName": "foobar"
},
"elastic": {
"serverURL": "xxxx",
"secretToken": "xxxx",
"serviceEnvironment": "foobar"
}
},
"hostResolver": {
"cnameFlattening": true,
"resolvConfig": "foobar",
"resolvDepth": 42
},
"certificatesResolvers": {
"CertificateResolver0": {
"acme": {
"email": "xxxx",
"caServer": "xxxx",
"preferredChain": "foobar",
"storage": "Storage",
"keyType": "MyKeyType",
"dnsChallenge": {
"provider": "DNSProvider",
"delayBeforeCheck": 42,
"resolvers": [
"xxxx",
"xxxx"
],
"disablePropagationCheck": true
},
"httpChallenge": {
"entryPoint": "MyEntryPoint"
},
"tlsChallenge": {}
}
}
},
"pilot": {
"token": "xxxx"
},
"experimental": {
"plugins": {
"Descriptor0": {
"moduleName": "foobar",
"version": "foobar"
},
"Descriptor1": {
"moduleName": "foobar",
"version": "foobar"
}
},
"devPlugin": {
"goPath": "foobar",
"moduleName": "foobar"
}
}
}

82
pkg/anonymize/testdata/example.json vendored Normal file
View file

@ -0,0 +1,82 @@
{
"GraceTimeOut": 10000000000,
"Debug": false,
"CheckNewVersion": true,
"AccessLogsFile": "",
"TraefikLogsFile": "",
"Level": "ERROR",
"EntryPoints": {
"http": {
"Network": "",
"Address": ":80",
"TLS": null,
"Auth": null,
"Compress": false
},
"https": {
"Address": ":443",
"TLS": {
"MinVersion": "",
"CipherSuites": null,
"Certificates": null,
"ClientCAFiles": null
},
"Auth": null,
"Compress": false
}
},
"Cluster": null,
"Constraints": [],
"ACME": {
"Email": "foo@bar.com",
"Domains": [
{
"Main": "foo@bar.com",
"SANs": null
},
{
"Main": "foo@bar.com",
"SANs": null
}
],
"Storage": "",
"StorageFile": "/acme/acme.json",
"OnDemand": true,
"OnHostRule": true,
"CAServer": "",
"EntryPoint": "https",
"DNSProvider": "",
"DelayDontCheckDNS": 0,
"ACMELogging": false,
"Options": null
},
"DefaultEntryPoints": [
"https",
"http"
],
"ProvidersThrottleDuration": 2000000000,
"MaxIdleConnsPerHost": 200,
"IdleTimeout": 180000000000,
"InsecureSkipVerify": false,
"Retry": null,
"HealthCheck": {
"Interval": 30000000000
},
"Docker": null,
"File": null,
"Web": null,
"Marathon": null,
"Consul": null,
"ConsulCatalog": null,
"Etcd": null,
"Zookeeper": null,
"Boltdb": null,
"KubernetesIngress": null,
"KubernetesCRD": null,
"Mesos": null,
"Eureka": null,
"ECS": null,
"Rancher": null,
"DynamoDB": null,
"ConfigFile": "/etc/traefik/traefik.toml"
}

82
pkg/anonymize/testdata/expected.json vendored Normal file
View file

@ -0,0 +1,82 @@
{
"GraceTimeOut": 10000000000,
"Debug": false,
"CheckNewVersion": true,
"AccessLogsFile": "",
"TraefikLogsFile": "",
"Level": "ERROR",
"EntryPoints": {
"http": {
"Network": "",
"Address": ":80",
"TLS": null,
"Auth": null,
"Compress": false
},
"https": {
"Address": ":443",
"TLS": {
"MinVersion": "",
"CipherSuites": null,
"Certificates": null,
"ClientCAFiles": null
},
"Auth": null,
"Compress": false
}
},
"Cluster": null,
"Constraints": [],
"ACME": {
"Email": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"Domains": [
{
"Main": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"SANs": null
},
{
"Main": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"SANs": null
}
],
"Storage": "",
"StorageFile": "/acme/acme.json",
"OnDemand": true,
"OnHostRule": true,
"CAServer": "",
"EntryPoint": "https",
"DNSProvider": "",
"DelayDontCheckDNS": 0,
"ACMELogging": false,
"Options": null
},
"DefaultEntryPoints": [
"https",
"http"
],
"ProvidersThrottleDuration": 2000000000,
"MaxIdleConnsPerHost": 200,
"IdleTimeout": 180000000000,
"InsecureSkipVerify": false,
"Retry": null,
"HealthCheck": {
"Interval": 30000000000
},
"Docker": null,
"File": null,
"Web": null,
"Marathon": null,
"Consul": null,
"ConsulCatalog": null,
"Etcd": null,
"Zookeeper": null,
"Boltdb": null,
"KubernetesIngress": null,
"KubernetesCRD": null,
"Mesos": null,
"Eureka": null,
"ECS": null,
"Rancher": null,
"DynamoDB": null,
"ConfigFile": "/etc/traefik/traefik.toml"
}

View file

@ -11,10 +11,10 @@ import (
// EntryPoint holds the entry point configuration. // EntryPoint holds the entry point configuration.
type EntryPoint struct { type EntryPoint struct {
Address string `description:"Entry point address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` Address string `description:"Entry point address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"`
Transport *EntryPointsTransport `description:"Configures communication between clients and Traefik." json:"transport,omitempty" toml:"transport,omitempty" yaml:"transport,omitempty"` Transport *EntryPointsTransport `description:"Configures communication between clients and Traefik." json:"transport,omitempty" toml:"transport,omitempty" yaml:"transport,omitempty" export:"true"`
ProxyProtocol *ProxyProtocol `description:"Proxy-Protocol configuration." json:"proxyProtocol,omitempty" toml:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty" label:"allowEmpty" file:"allowEmpty"` ProxyProtocol *ProxyProtocol `description:"Proxy-Protocol configuration." json:"proxyProtocol,omitempty" toml:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
ForwardedHeaders *ForwardedHeaders `description:"Trust client forwarding headers." json:"forwardedHeaders,omitempty" toml:"forwardedHeaders,omitempty" yaml:"forwardedHeaders,omitempty"` ForwardedHeaders *ForwardedHeaders `description:"Trust client forwarding headers." json:"forwardedHeaders,omitempty" toml:"forwardedHeaders,omitempty" yaml:"forwardedHeaders,omitempty" export:"true"`
HTTP HTTPConfig `description:"HTTP configuration." json:"http,omitempty" toml:"http,omitempty" yaml:"http,omitempty"` HTTP HTTPConfig `description:"HTTP configuration." json:"http,omitempty" toml:"http,omitempty" yaml:"http,omitempty" export:"true"`
} }
// GetAddress strips any potential protocol part of the address field of the // GetAddress strips any potential protocol part of the address field of the
@ -49,22 +49,22 @@ func (ep *EntryPoint) SetDefaults() {
// HTTPConfig is the HTTP configuration of an entry point. // HTTPConfig is the HTTP configuration of an entry point.
type HTTPConfig struct { type HTTPConfig struct {
Redirections *Redirections `description:"Set of redirection" json:"redirections,omitempty" toml:"redirections,omitempty" yaml:"redirections,omitempty"` Redirections *Redirections `description:"Set of redirection" json:"redirections,omitempty" toml:"redirections,omitempty" yaml:"redirections,omitempty" export:"true"`
Middlewares []string `description:"Default middlewares for the routers linked to the entry point." json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty"` Middlewares []string `description:"Default middlewares for the routers linked to the entry point." json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"`
TLS *TLSConfig `description:"Default TLS configuration for the routers linked to the entry point." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty" file:"allowEmpty"` TLS *TLSConfig `description:"Default TLS configuration for the routers linked to the entry point." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
} }
// Redirections is a set of redirection for an entry point. // Redirections is a set of redirection for an entry point.
type Redirections struct { type Redirections struct {
EntryPoint *RedirectEntryPoint `description:"Set of redirection for an entry point." json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"` EntryPoint *RedirectEntryPoint `description:"Set of redirection for an entry point." json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty" export:"true"`
} }
// RedirectEntryPoint is the definition of an entry point redirection. // RedirectEntryPoint is the definition of an entry point redirection.
type RedirectEntryPoint struct { type RedirectEntryPoint struct {
To string `description:"Targeted entry point of the redirection." json:"to,omitempty" toml:"to,omitempty" yaml:"to,omitempty"` To string `description:"Targeted entry point of the redirection." json:"to,omitempty" toml:"to,omitempty" yaml:"to,omitempty" export:"true"`
Scheme string `description:"Scheme used for the redirection." json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty"` Scheme string `description:"Scheme used for the redirection." json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty" export:"true"`
Permanent bool `description:"Applies a permanent redirection." json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty"` Permanent bool `description:"Applies a permanent redirection." json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty" export:"true"`
Priority int `description:"Priority of the generated router." json:"priority,omitempty" toml:"priority,omitempty" yaml:"priority,omitempty"` Priority int `description:"Priority of the generated router." json:"priority,omitempty" toml:"priority,omitempty" yaml:"priority,omitempty" export:"true"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.
@ -76,9 +76,9 @@ func (r *RedirectEntryPoint) SetDefaults() {
// TLSConfig is the default TLS configuration for all the routers associated to the concerned entry point. // TLSConfig is the default TLS configuration for all the routers associated to the concerned entry point.
type TLSConfig struct { type TLSConfig struct {
Options string `description:"Default TLS options for the routers linked to the entry point." json:"options,omitempty" toml:"options,omitempty" yaml:"options,omitempty"` Options string `description:"Default TLS options for the routers linked to the entry point." json:"options,omitempty" toml:"options,omitempty" yaml:"options,omitempty" export:"true"`
CertResolver string `description:"Default certificate resolver for the routers linked to the entry point." json:"certResolver,omitempty" toml:"certResolver,omitempty" yaml:"certResolver,omitempty"` CertResolver string `description:"Default certificate resolver for the routers linked to the entry point." json:"certResolver,omitempty" toml:"certResolver,omitempty" yaml:"certResolver,omitempty" export:"true"`
Domains []types.Domain `description:"Default TLS domains for the routers linked to the entry point." json:"domains,omitempty" toml:"domains,omitempty" yaml:"domains,omitempty"` Domains []types.Domain `description:"Default TLS domains for the routers linked to the entry point." json:"domains,omitempty" toml:"domains,omitempty" yaml:"domains,omitempty" export:"true"`
} }
// ForwardedHeaders Trust client forwarding headers. // ForwardedHeaders Trust client forwarding headers.

View file

@ -4,6 +4,6 @@ import "github.com/traefik/traefik/v2/pkg/plugins"
// Experimental experimental Traefik features. // Experimental experimental Traefik features.
type Experimental struct { type Experimental struct {
Plugins map[string]plugins.Descriptor `description:"Plugins configuration." json:"plugins,omitempty" toml:"plugins,omitempty" yaml:"plugins,omitempty"` Plugins map[string]plugins.Descriptor `description:"Plugins configuration." json:"plugins,omitempty" toml:"plugins,omitempty" yaml:"plugins,omitempty" export:"true"`
DevPlugin *plugins.DevPlugin `description:"Dev plugin configuration." json:"devPlugin,omitempty" toml:"devPlugin,omitempty" yaml:"devPlugin,omitempty"` DevPlugin *plugins.DevPlugin `description:"Dev plugin configuration." json:"devPlugin,omitempty" toml:"devPlugin,omitempty" yaml:"devPlugin,omitempty" export:"true"`
} }

View file

@ -72,9 +72,9 @@ type Configuration struct {
CertificatesResolvers map[string]CertificateResolver `description:"Certificates resolvers configuration." json:"certificatesResolvers,omitempty" toml:"certificatesResolvers,omitempty" yaml:"certificatesResolvers,omitempty" export:"true"` CertificatesResolvers map[string]CertificateResolver `description:"Certificates resolvers configuration." json:"certificatesResolvers,omitempty" toml:"certificatesResolvers,omitempty" yaml:"certificatesResolvers,omitempty" export:"true"`
Pilot *Pilot `description:"Traefik Pilot configuration." json:"pilot,omitempty" toml:"pilot,omitempty" yaml:"pilot,omitempty"` Pilot *Pilot `description:"Traefik Pilot configuration." json:"pilot,omitempty" toml:"pilot,omitempty" yaml:"pilot,omitempty" export:"true"`
Experimental *Experimental `description:"experimental features." json:"experimental,omitempty" toml:"experimental,omitempty" yaml:"experimental,omitempty"` Experimental *Experimental `description:"experimental features." json:"experimental,omitempty" toml:"experimental,omitempty" yaml:"experimental,omitempty" export:"true"`
} }
// CertificateResolver contains the configuration for the different types of certificates resolver. // CertificateResolver contains the configuration for the different types of certificates resolver.
@ -176,14 +176,14 @@ type Providers struct {
KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesCRD,omitempty" toml:"kubernetesCRD,omitempty" yaml:"kubernetesCRD,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesCRD,omitempty" toml:"kubernetesCRD,omitempty" yaml:"kubernetesCRD,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"`
Rest *rest.Provider `description:"Enable Rest backend with default settings." json:"rest,omitempty" toml:"rest,omitempty" yaml:"rest,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Rest *rest.Provider `description:"Enable Rest backend with default settings." json:"rest,omitempty" toml:"rest,omitempty" yaml:"rest,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"`
Rancher *rancher.Provider `description:"Enable Rancher backend with default settings." json:"rancher,omitempty" toml:"rancher,omitempty" yaml:"rancher,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Rancher *rancher.Provider `description:"Enable Rancher backend with default settings." json:"rancher,omitempty" toml:"rancher,omitempty" yaml:"rancher,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"`
ConsulCatalog *consulcatalog.Provider `description:"Enable ConsulCatalog backend with default settings." json:"consulCatalog,omitempty" toml:"consulCatalog,omitempty" yaml:"consulCatalog,omitempty"` ConsulCatalog *consulcatalog.Provider `description:"Enable ConsulCatalog backend with default settings." json:"consulCatalog,omitempty" toml:"consulCatalog,omitempty" yaml:"consulCatalog,omitempty" export:"true"`
Ecs *ecs.Provider `description:"Enable AWS ECS backend with default settings." json:"ecs,omitempty" toml:"ecs,omitempty" yaml:"ecs,omitempty"` Ecs *ecs.Provider `description:"Enable AWS ECS backend with default settings." json:"ecs,omitempty" toml:"ecs,omitempty" yaml:"ecs,omitempty" export:"true"`
Consul *consul.Provider `description:"Enable Consul backend with default settings." json:"consul,omitempty" toml:"consul,omitempty" yaml:"consul,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Consul *consul.Provider `description:"Enable Consul backend with default settings." json:"consul,omitempty" toml:"consul,omitempty" yaml:"consul,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
Etcd *etcd.Provider `description:"Enable Etcd backend with default settings." json:"etcd,omitempty" toml:"etcd,omitempty" yaml:"etcd,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Etcd *etcd.Provider `description:"Enable Etcd backend with default settings." json:"etcd,omitempty" toml:"etcd,omitempty" yaml:"etcd,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
ZooKeeper *zk.Provider `description:"Enable ZooKeeper backend with default settings." json:"zooKeeper,omitempty" toml:"zooKeeper,omitempty" yaml:"zooKeeper,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` ZooKeeper *zk.Provider `description:"Enable ZooKeeper backend with default settings." json:"zooKeeper,omitempty" toml:"zooKeeper,omitempty" yaml:"zooKeeper,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
Redis *redis.Provider `description:"Enable Redis backend with default settings." json:"redis,omitempty" toml:"redis,omitempty" yaml:"redis,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Redis *redis.Provider `description:"Enable Redis backend with default settings." json:"redis,omitempty" toml:"redis,omitempty" yaml:"redis,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
HTTP *http.Provider `description:"Enable HTTP backend with default settings." json:"http,omitempty" toml:"http,omitempty" yaml:"http,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` HTTP *http.Provider `description:"Enable HTTP backend with default settings." json:"http,omitempty" toml:"http,omitempty" yaml:"http,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
} }
// SetEffectiveConfiguration adds missing configuration parameters derived from existing ones. // SetEffectiveConfiguration adds missing configuration parameters derived from existing ones.

View file

@ -137,7 +137,7 @@ func RotateFile() error {
} }
if err := OpenFile(logFilePath); err != nil { if err := OpenFile(logFilePath); err != nil {
return fmt.Errorf("error opening log file: %s", err) return fmt.Errorf("error opening log file: %w", err)
} }
return nil return nil

View file

@ -2,6 +2,7 @@ package metrics
import ( import (
"context" "context"
"errors"
"net/http" "net/http"
"sort" "sort"
"strings" "strings"
@ -74,12 +75,15 @@ func RegisterPrometheus(ctx context.Context, config *types.Prometheus) Registry
standardRegistry := initStandardRegistry(config) standardRegistry := initStandardRegistry(config)
if err := promRegistry.Register(stdprometheus.NewProcessCollector(stdprometheus.ProcessCollectorOpts{})); err != nil { if err := promRegistry.Register(stdprometheus.NewProcessCollector(stdprometheus.ProcessCollectorOpts{})); err != nil {
if _, ok := err.(stdprometheus.AlreadyRegisteredError); !ok { var arErr stdprometheus.AlreadyRegisteredError
if !errors.As(err, &arErr) {
log.FromContext(ctx).Warn("ProcessCollector is already registered") log.FromContext(ctx).Warn("ProcessCollector is already registered")
} }
} }
if err := promRegistry.Register(stdprometheus.NewGoCollector()); err != nil { if err := promRegistry.Register(stdprometheus.NewGoCollector()); err != nil {
if _, ok := err.(stdprometheus.AlreadyRegisteredError); !ok { var arErr stdprometheus.AlreadyRegisteredError
if !errors.As(err, &arErr) {
log.FromContext(ctx).Warn("GoCollector is already registered") log.FromContext(ctx).Warn("GoCollector is already registered")
} }
} }
@ -212,16 +216,22 @@ func initStandardRegistry(config *types.Prometheus) Registry {
} }
func registerPromState(ctx context.Context) bool { func registerPromState(ctx context.Context) bool {
if err := promRegistry.Register(promState); err != nil { err := promRegistry.Register(promState)
if err == nil {
return true
}
logger := log.FromContext(ctx) logger := log.FromContext(ctx)
if _, ok := err.(stdprometheus.AlreadyRegisteredError); !ok {
var arErr stdprometheus.AlreadyRegisteredError
if errors.As(err, &arErr) {
logger.Debug("Prometheus collector already registered.")
return true
}
logger.Errorf("Unable to register Traefik to Prometheus: %v", err) logger.Errorf("Unable to register Traefik to Prometheus: %v", err)
return false return false
} }
logger.Debug("Prometheus collector already registered.")
}
return true
}
// OnConfigurationUpdate receives the current configuration from Traefik. // OnConfigurationUpdate receives the current configuration from Traefik.
// It then converts the configuration to the optimized package internal format // It then converts the configuration to the optimized package internal format

View file

@ -2,6 +2,7 @@ package auth
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net" "net"
@ -136,7 +137,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
redirectURL, err := forwardResponse.Location() redirectURL, err := forwardResponse.Location()
if err != nil { if err != nil {
if err != http.ErrNoLocation { if !errors.Is(err, http.ErrNoLocation) {
logMessage := fmt.Sprintf("Error reading response location header %s. Cause: %s", fa.address, err) logMessage := fmt.Sprintf("Error reading response location header %s. Cause: %s", fa.address, err)
logger.Debug(logMessage) logger.Debug(logMessage)
tracing.SetErrorWithEvent(req, logMessage) tracing.SetErrorWithEvent(req, logMessage)

View file

@ -54,5 +54,6 @@ func recoverFunc(ctx context.Context, rw http.ResponseWriter, r *http.Request) {
// https://github.com/golang/go/blob/a0d6420d8be2ae7164797051ec74fa2a2df466a1/src/net/http/server.go#L1761-L1775 // https://github.com/golang/go/blob/a0d6420d8be2ae7164797051ec74fa2a2df466a1/src/net/http/server.go#L1761-L1775
// https://github.com/golang/go/blob/c33153f7b416c03983324b3e8f869ce1116d84bc/src/net/http/httputil/reverseproxy.go#L284 // https://github.com/golang/go/blob/c33153f7b416c03983324b3e8f869ce1116d84bc/src/net/http/httputil/reverseproxy.go#L284
func shouldLogPanic(panicValue interface{}) bool { func shouldLogPanic(panicValue interface{}) bool {
//nolint:errorlint // false-positive because panicValue is an interface.
return panicValue != nil && panicValue != http.ErrAbortHandler return panicValue != nil && panicValue != http.ErrAbortHandler
} }

View file

@ -9,8 +9,8 @@ import (
// Handler expose ping routes. // Handler expose ping routes.
type Handler struct { type Handler struct {
EntryPoint string `description:"EntryPoint" export:"true" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"` EntryPoint string `description:"EntryPoint" export:"true" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"`
ManualRouting bool `description:"Manual routing" json:"manualRouting,omitempty" toml:"manualRouting,omitempty" yaml:"manualRouting,omitempty"` ManualRouting bool `description:"Manual routing" json:"manualRouting,omitempty" toml:"manualRouting,omitempty" yaml:"manualRouting,omitempty" export:"true"`
TerminatingStatusCode int `description:"Terminating status code" json:"terminatingStatusCode,omitempty" toml:"terminatingStatusCode,omitempty" yaml:"terminatingStatusCode,omitempty"` TerminatingStatusCode int `description:"Terminating status code" json:"terminatingStatusCode,omitempty" toml:"terminatingStatusCode,omitempty" yaml:"terminatingStatusCode,omitempty" export:"true"`
terminating bool terminating bool
} }

View file

@ -3,19 +3,19 @@ package plugins
// Descriptor The static part of a plugin configuration (prod). // Descriptor The static part of a plugin configuration (prod).
type Descriptor struct { type Descriptor struct {
// ModuleName (required) // ModuleName (required)
ModuleName string `description:"plugin's module name." json:"moduleName,omitempty" toml:"moduleName,omitempty" yaml:"moduleName,omitempty"` ModuleName string `description:"plugin's module name." json:"moduleName,omitempty" toml:"moduleName,omitempty" yaml:"moduleName,omitempty" export:"true"`
// Version (required) // Version (required)
Version string `description:"plugin's version." json:"version,omitempty" toml:"version,omitempty" yaml:"version,omitempty"` Version string `description:"plugin's version." json:"version,omitempty" toml:"version,omitempty" yaml:"version,omitempty" export:"true"`
} }
// DevPlugin The static part of a plugin configuration (only for dev). // DevPlugin The static part of a plugin configuration (only for dev).
type DevPlugin struct { type DevPlugin struct {
// GoPath plugin's GOPATH. (required) // GoPath plugin's GOPATH. (required)
GoPath string `description:"plugin's GOPATH." json:"goPath,omitempty" toml:"goPath,omitempty" yaml:"goPath,omitempty"` GoPath string `description:"plugin's GOPATH." json:"goPath,omitempty" toml:"goPath,omitempty" yaml:"goPath,omitempty" export:"true"`
// ModuleName (required) // ModuleName (required)
ModuleName string `description:"plugin's module name." json:"moduleName,omitempty" toml:"moduleName,omitempty" yaml:"moduleName,omitempty"` ModuleName string `description:"plugin's module name." json:"moduleName,omitempty" toml:"moduleName,omitempty" yaml:"moduleName,omitempty" export:"true"`
} }
// Manifest The plugin manifest. // Manifest The plugin manifest.

View file

@ -35,12 +35,12 @@ var oscpMustStaple = false
type Configuration struct { type Configuration struct {
Email string `description:"Email address used for registration." json:"email,omitempty" toml:"email,omitempty" yaml:"email,omitempty"` Email string `description:"Email address used for registration." json:"email,omitempty" toml:"email,omitempty" yaml:"email,omitempty"`
CAServer string `description:"CA server to use." json:"caServer,omitempty" toml:"caServer,omitempty" yaml:"caServer,omitempty"` CAServer string `description:"CA server to use." json:"caServer,omitempty" toml:"caServer,omitempty" yaml:"caServer,omitempty"`
PreferredChain string `description:"Preferred chain to use." json:"preferredChain,omitempty" toml:"preferredChain,omitempty" yaml:"preferredChain,omitempty"` PreferredChain string `description:"Preferred chain to use." json:"preferredChain,omitempty" toml:"preferredChain,omitempty" yaml:"preferredChain,omitempty" export:"true"`
Storage string `description:"Storage to use." json:"storage,omitempty" toml:"storage,omitempty" yaml:"storage,omitempty"` Storage string `description:"Storage to use." json:"storage,omitempty" toml:"storage,omitempty" yaml:"storage,omitempty" export:"true"`
KeyType string `description:"KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'." json:"keyType,omitempty" toml:"keyType,omitempty" yaml:"keyType,omitempty"` KeyType string `description:"KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'." json:"keyType,omitempty" toml:"keyType,omitempty" yaml:"keyType,omitempty" export:"true"`
DNSChallenge *DNSChallenge `description:"Activate DNS-01 Challenge." json:"dnsChallenge,omitempty" toml:"dnsChallenge,omitempty" yaml:"dnsChallenge,omitempty" label:"allowEmpty" file:"allowEmpty"` DNSChallenge *DNSChallenge `description:"Activate DNS-01 Challenge." json:"dnsChallenge,omitempty" toml:"dnsChallenge,omitempty" yaml:"dnsChallenge,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
HTTPChallenge *HTTPChallenge `description:"Activate HTTP-01 Challenge." json:"httpChallenge,omitempty" toml:"httpChallenge,omitempty" yaml:"httpChallenge,omitempty" label:"allowEmpty" file:"allowEmpty"` HTTPChallenge *HTTPChallenge `description:"Activate HTTP-01 Challenge." json:"httpChallenge,omitempty" toml:"httpChallenge,omitempty" yaml:"httpChallenge,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
TLSChallenge *TLSChallenge `description:"Activate TLS-ALPN-01 Challenge." json:"tlsChallenge,omitempty" toml:"tlsChallenge,omitempty" yaml:"tlsChallenge,omitempty" label:"allowEmpty" file:"allowEmpty"` TLSChallenge *TLSChallenge `description:"Activate TLS-ALPN-01 Challenge." json:"tlsChallenge,omitempty" toml:"tlsChallenge,omitempty" yaml:"tlsChallenge,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.
@ -65,15 +65,15 @@ type Certificate struct {
// DNSChallenge contains DNS challenge Configuration. // DNSChallenge contains DNS challenge Configuration.
type DNSChallenge struct { type DNSChallenge struct {
Provider string `description:"Use a DNS-01 based challenge provider rather than HTTPS." json:"provider,omitempty" toml:"provider,omitempty" yaml:"provider,omitempty"` Provider string `description:"Use a DNS-01 based challenge provider rather than HTTPS." json:"provider,omitempty" toml:"provider,omitempty" yaml:"provider,omitempty" export:"true"`
DelayBeforeCheck ptypes.Duration `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers." json:"delayBeforeCheck,omitempty" toml:"delayBeforeCheck,omitempty" yaml:"delayBeforeCheck,omitempty"` DelayBeforeCheck ptypes.Duration `description:"Assume DNS propagates after a delay in seconds rather than finding and querying nameservers." json:"delayBeforeCheck,omitempty" toml:"delayBeforeCheck,omitempty" yaml:"delayBeforeCheck,omitempty" export:"true"`
Resolvers []string `description:"Use following DNS servers to resolve the FQDN authority." json:"resolvers,omitempty" toml:"resolvers,omitempty" yaml:"resolvers,omitempty"` Resolvers []string `description:"Use following DNS servers to resolve the FQDN authority." json:"resolvers,omitempty" toml:"resolvers,omitempty" yaml:"resolvers,omitempty"`
DisablePropagationCheck bool `description:"Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready. [not recommended]" json:"disablePropagationCheck,omitempty" toml:"disablePropagationCheck,omitempty" yaml:"disablePropagationCheck,omitempty"` DisablePropagationCheck bool `description:"Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready. [not recommended]" json:"disablePropagationCheck,omitempty" toml:"disablePropagationCheck,omitempty" yaml:"disablePropagationCheck,omitempty" export:"true"`
} }
// HTTPChallenge contains HTTP challenge Configuration. // HTTPChallenge contains HTTP challenge Configuration.
type HTTPChallenge struct { type HTTPChallenge struct {
EntryPoint string `description:"HTTP challenge EntryPoint" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"` EntryPoint string `description:"HTTP challenge EntryPoint" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty" export:"true"`
} }
// TLSChallenge contains TLS challenge Configuration. // TLSChallenge contains TLS challenge Configuration.

View file

@ -55,10 +55,10 @@ type Provider struct {
// EndpointConfig holds configurations of the endpoint. // EndpointConfig holds configurations of the endpoint.
type EndpointConfig struct { type EndpointConfig struct {
Address string `description:"The address of the Consul server" json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty" export:"true"` Address string `description:"The address of the Consul server" json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"`
Scheme string `description:"The URI scheme for the Consul server" json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty" export:"true"` Scheme string `description:"The URI scheme for the Consul server" json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty"`
DataCenter string `description:"Data center to use. If not provided, the default agent data center is used" json:"datacenter,omitempty" toml:"datacenter,omitempty" yaml:"datacenter,omitempty" export:"true"` DataCenter string `description:"Data center to use. If not provided, the default agent data center is used" json:"datacenter,omitempty" toml:"datacenter,omitempty" yaml:"datacenter,omitempty"`
Token string `description:"Token is used to provide a per-request ACL token which overrides the agent's default token" json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" export:"true"` Token string `description:"Token is used to provide a per-request ACL token which overrides the agent's default token" json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty"`
TLS *types.ClientTLS `description:"Enable TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"` TLS *types.ClientTLS `description:"Enable TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"`
HTTPAuth *EndpointHTTPAuthConfig `description:"Auth info to use for http access" json:"httpAuth,omitempty" toml:"httpAuth,omitempty" yaml:"httpAuth,omitempty" export:"true"` HTTPAuth *EndpointHTTPAuthConfig `description:"Auth info to use for http access" json:"httpAuth,omitempty" toml:"httpAuth,omitempty" yaml:"httpAuth,omitempty" export:"true"`
EndpointWaitTime ptypes.Duration `description:"WaitTime limits how long a Watch will block. If not provided, the agent default values will be used" json:"endpointWaitTime,omitempty" toml:"endpointWaitTime,omitempty" yaml:"endpointWaitTime,omitempty" export:"true"` EndpointWaitTime ptypes.Duration `description:"WaitTime limits how long a Watch will block. If not provided, the agent default values will be used" json:"endpointWaitTime,omitempty" toml:"endpointWaitTime,omitempty" yaml:"endpointWaitTime,omitempty" export:"true"`
@ -71,8 +71,8 @@ func (c *EndpointConfig) SetDefaults() {
// EndpointHTTPAuthConfig holds configurations of the authentication. // EndpointHTTPAuthConfig holds configurations of the authentication.
type EndpointHTTPAuthConfig struct { type EndpointHTTPAuthConfig struct {
Username string `description:"Basic Auth username" json:"username,omitempty" toml:"username,omitempty" yaml:"username,omitempty" export:"true"` Username string `description:"Basic Auth username" json:"username,omitempty" toml:"username,omitempty" yaml:"username,omitempty"`
Password string `description:"Basic Auth password" json:"password,omitempty" toml:"password,omitempty" yaml:"password,omitempty" export:"true"` Password string `description:"Basic Auth password" json:"password,omitempty" toml:"password,omitempty" yaml:"password,omitempty"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.

View file

@ -2,6 +2,7 @@ package docker
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"io" "io"
"net" "net"
@ -310,7 +311,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
startStopHandle(event) startStopHandle(event)
} }
case err := <-errc: case err := <-errc:
if err == io.EOF { if errors.Is(err, io.EOF) {
logger.Debug("Provider event stream closed") logger.Debug("Provider event stream closed")
} }
return err return err

View file

@ -24,9 +24,9 @@ var _ provider.Provider = (*Provider)(nil)
// Provider is a provider.Provider implementation that queries an HTTP(s) endpoint for a configuration. // Provider is a provider.Provider implementation that queries an HTTP(s) endpoint for a configuration.
type Provider struct { type Provider struct {
Endpoint string `description:"Load configuration from this endpoint." json:"endpoint" toml:"endpoint" yaml:"endpoint" export:"true"` Endpoint string `description:"Load configuration from this endpoint." json:"endpoint" toml:"endpoint" yaml:"endpoint"`
PollInterval ptypes.Duration `description:"Polling interval for endpoint." json:"pollInterval,omitempty" toml:"pollInterval,omitempty" yaml:"pollInterval,omitempty"` PollInterval ptypes.Duration `description:"Polling interval for endpoint." json:"pollInterval,omitempty" toml:"pollInterval,omitempty" yaml:"pollInterval,omitempty" export:"true"`
PollTimeout ptypes.Duration `description:"Polling timeout for endpoint." json:"pollTimeout,omitempty" toml:"pollTimeout,omitempty" yaml:"pollTimeout,omitempty"` PollTimeout ptypes.Duration `description:"Polling timeout for endpoint." json:"pollTimeout,omitempty" toml:"pollTimeout,omitempty" yaml:"pollTimeout,omitempty" export:"true"`
TLS *types.ClientTLS `description:"Enable TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"` TLS *types.ClientTLS `description:"Enable TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"`
httpClient *http.Client httpClient *http.Client
lastConfigurationHash uint64 lastConfigurationHash uint64

View file

@ -45,7 +45,7 @@ type Provider struct {
Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"` Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"`
LabelSelector string `description:"Kubernetes label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"` LabelSelector string `description:"Kubernetes label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"`
IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"` IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"`
ThrottleDuration ptypes.Duration `description:"Ingress refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty"` ThrottleDuration ptypes.Duration `description:"Ingress refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty" export:"true"`
lastConfiguration safe.Safe lastConfiguration safe.Safe
} }

View file

@ -41,8 +41,8 @@ type Provider struct {
Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"` Namespaces []string `description:"Kubernetes namespaces." json:"namespaces,omitempty" toml:"namespaces,omitempty" yaml:"namespaces,omitempty" export:"true"`
LabelSelector string `description:"Kubernetes Ingress label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"` LabelSelector string `description:"Kubernetes Ingress label selector to use." json:"labelSelector,omitempty" toml:"labelSelector,omitempty" yaml:"labelSelector,omitempty" export:"true"`
IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"` IngressClass string `description:"Value of kubernetes.io/ingress.class annotation to watch for." json:"ingressClass,omitempty" toml:"ingressClass,omitempty" yaml:"ingressClass,omitempty" export:"true"`
IngressEndpoint *EndpointIngress `description:"Kubernetes Ingress Endpoint." json:"ingressEndpoint,omitempty" toml:"ingressEndpoint,omitempty" yaml:"ingressEndpoint,omitempty"` IngressEndpoint *EndpointIngress `description:"Kubernetes Ingress Endpoint." json:"ingressEndpoint,omitempty" toml:"ingressEndpoint,omitempty" yaml:"ingressEndpoint,omitempty" export:"true"`
ThrottleDuration ptypes.Duration `description:"Ingress refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty"` ThrottleDuration ptypes.Duration `description:"Ingress refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty" export:"true"`
lastConfiguration safe.Safe lastConfiguration safe.Safe
} }

View file

@ -10,7 +10,7 @@ var _ provider.Provider = (*Provider)(nil)
// Provider holds configurations of the provider. // Provider holds configurations of the provider.
type Provider struct { type Provider struct {
kv.Provider kv.Provider `export:"true"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.

View file

@ -10,7 +10,7 @@ var _ provider.Provider = (*Provider)(nil)
// Provider holds configurations of the provider. // Provider holds configurations of the provider.
type Provider struct { type Provider struct {
kv.Provider kv.Provider `export:"true"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.

View file

@ -10,7 +10,7 @@ var _ provider.Provider = (*Provider)(nil)
// Provider holds configurations of the provider. // Provider holds configurations of the provider.
type Provider struct { type Provider struct {
kv.Provider kv.Provider `export:"true"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.

View file

@ -10,7 +10,7 @@ var _ provider.Provider = (*Provider)(nil)
// Provider holds configurations of the provider. // Provider holds configurations of the provider.
type Provider struct { type Provider struct {
kv.Provider kv.Provider `export:"true"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.

View file

@ -49,10 +49,10 @@ type Provider struct {
Constraints string `description:"Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` Constraints string `description:"Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"`
Trace bool `description:"Display additional provider logs." json:"trace,omitempty" toml:"trace,omitempty" yaml:"trace,omitempty" export:"true"` Trace bool `description:"Display additional provider logs." json:"trace,omitempty" toml:"trace,omitempty" yaml:"trace,omitempty" export:"true"`
Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"` Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"`
Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty" export:"true"` Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"`
DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"`
ExposedByDefault bool `description:"Expose Marathon apps by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` ExposedByDefault bool `description:"Expose Marathon apps by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"`
DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header." json:"dcosToken,omitempty" toml:"dcosToken,omitempty" yaml:"dcosToken,omitempty" export:"true"` DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header." json:"dcosToken,omitempty" toml:"dcosToken,omitempty" yaml:"dcosToken,omitempty"`
TLS *types.ClientTLS `description:"Enable TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"` TLS *types.ClientTLS `description:"Enable TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"`
DialerTimeout ptypes.Duration `description:"Set a dialer timeout for Marathon." json:"dialerTimeout,omitempty" toml:"dialerTimeout,omitempty" yaml:"dialerTimeout,omitempty" export:"true"` DialerTimeout ptypes.Duration `description:"Set a dialer timeout for Marathon." json:"dialerTimeout,omitempty" toml:"dialerTimeout,omitempty" yaml:"dialerTimeout,omitempty" export:"true"`
ResponseHeaderTimeout ptypes.Duration `description:"Set a response header timeout for Marathon." json:"responseHeaderTimeout,omitempty" toml:"responseHeaderTimeout,omitempty" yaml:"responseHeaderTimeout,omitempty" export:"true"` ResponseHeaderTimeout ptypes.Duration `description:"Set a response header timeout for Marathon." json:"responseHeaderTimeout,omitempty" toml:"responseHeaderTimeout,omitempty" yaml:"responseHeaderTimeout,omitempty" export:"true"`

View file

@ -46,7 +46,7 @@ type Provider struct {
ExposedByDefault bool `description:"Expose containers by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` ExposedByDefault bool `description:"Expose containers by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"`
EnableServiceHealthFilter bool `description:"Filter services with unhealthy states and inactive states." json:"enableServiceHealthFilter,omitempty" toml:"enableServiceHealthFilter,omitempty" yaml:"enableServiceHealthFilter,omitempty" export:"true"` EnableServiceHealthFilter bool `description:"Filter services with unhealthy states and inactive states." json:"enableServiceHealthFilter,omitempty" toml:"enableServiceHealthFilter,omitempty" yaml:"enableServiceHealthFilter,omitempty" export:"true"`
RefreshSeconds int `description:"Defines the polling interval in seconds." json:"refreshSeconds,omitempty" toml:"refreshSeconds,omitempty" yaml:"refreshSeconds,omitempty" export:"true"` RefreshSeconds int `description:"Defines the polling interval in seconds." json:"refreshSeconds,omitempty" toml:"refreshSeconds,omitempty" yaml:"refreshSeconds,omitempty" export:"true"`
IntervalPoll bool `description:"Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate)." json:"intervalPoll,omitempty" toml:"intervalPoll,omitempty" yaml:"intervalPoll,omitempty"` IntervalPoll bool `description:"Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate)." json:"intervalPoll,omitempty" toml:"intervalPoll,omitempty" yaml:"intervalPoll,omitempty" export:"true"`
Prefix string `description:"Prefix used for accessing the Rancher metadata service." json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty"` Prefix string `description:"Prefix used for accessing the Rancher metadata service." json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty"`
defaultRuleTpl *template.Template defaultRuleTpl *template.Template
} }

View file

@ -2,6 +2,7 @@ package server
import ( import (
"context" "context"
"errors"
"os" "os"
"os/signal" "os/signal"
"time" "time"
@ -85,9 +86,9 @@ func (s *Server) Close() {
go func(ctx context.Context) { go func(ctx context.Context) {
<-ctx.Done() <-ctx.Done()
if ctx.Err() == context.Canceled { if errors.Is(ctx.Err(), context.Canceled) {
return return
} else if ctx.Err() == context.DeadlineExceeded { } else if errors.Is(ctx.Err(), context.DeadlineExceeded) {
panic("Timeout while stopping traefik, killing instance ✝") panic("Timeout while stopping traefik, killing instance ✝")
} }
}(ctx) }(ctx)

View file

@ -2,11 +2,13 @@ package server
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
stdlog "log" stdlog "log"
"net" "net"
"net/http" "net/http"
"sync" "sync"
"syscall"
"time" "time"
proxyprotocol "github.com/c0va23/go-proxyprotocol" proxyprotocol "github.com/c0va23/go-proxyprotocol"
@ -172,11 +174,15 @@ func (e *TCPEntryPoint) Start(ctx context.Context) {
conn, err := e.listener.Accept() conn, err := e.listener.Accept()
if err != nil { if err != nil {
logger.Error(err) logger.Error(err)
if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
var netErr net.Error
if errors.As(err, &netErr) && netErr.Temporary() {
continue continue
} }
e.httpServer.Forwarder.errChan <- err e.httpServer.Forwarder.errChan <- err
e.httpsServer.Forwarder.errChan <- err e.httpsServer.Forwarder.errChan <- err
return return
} }
@ -230,7 +236,7 @@ func (e *TCPEntryPoint) Shutdown(ctx context.Context) {
if err == nil { if err == nil {
return return
} }
if ctx.Err() == context.DeadlineExceeded { if errors.Is(ctx.Err(), context.DeadlineExceeded) {
logger.Debugf("Server failed to shutdown within deadline because: %s", err) logger.Debugf("Server failed to shutdown within deadline because: %s", err)
if err = server.Close(); err != nil { if err = server.Close(); err != nil {
logger.Error(err) logger.Error(err)
@ -261,7 +267,7 @@ func (e *TCPEntryPoint) Shutdown(ctx context.Context) {
if err == nil { if err == nil {
return return
} }
if ctx.Err() == context.DeadlineExceeded { if errors.Is(ctx.Err(), context.DeadlineExceeded) {
logger.Debugf("Server failed to shutdown before deadline because: %s", err) logger.Debugf("Server failed to shutdown before deadline because: %s", err)
} }
e.tracker.Close() e.tracker.Close()
@ -340,8 +346,12 @@ func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
} }
if err = tc.SetKeepAlivePeriod(3 * time.Minute); err != nil { if err = tc.SetKeepAlivePeriod(3 * time.Minute); err != nil {
// Some systems, such as OpenBSD, have no user-settable per-socket TCP
// keepalive options.
if !errors.Is(err, syscall.ENOPROTOOPT) {
return nil, err return nil, err
} }
}
return tc, nil return tc, nil
} }

View file

@ -46,7 +46,7 @@ func TestShutdownTCP(t *testing.T) {
for { for {
_, err := http.ReadRequest(bufio.NewReader(conn)) _, err := http.ReadRequest(bufio.NewReader(conn))
if err == io.EOF || (err != nil && strings.HasSuffix(err.Error(), "use of closed network connection")) { if errors.Is(err, io.EOF) || (err != nil && strings.HasSuffix(err.Error(), "use of closed network connection")) {
return return
} }
require.NoError(t, err) require.NoError(t, err)

View file

@ -81,13 +81,13 @@ func (m *Mirroring) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
logger := log.FromContext(req.Context()) logger := log.FromContext(req.Context())
rr, bytesRead, err := newReusableRequest(req, m.maxBodySize) rr, bytesRead, err := newReusableRequest(req, m.maxBodySize)
if err != nil && err != errBodyTooLarge { if err != nil && !errors.Is(err, errBodyTooLarge) {
http.Error(rw, http.StatusText(http.StatusInternalServerError)+ http.Error(rw, http.StatusText(http.StatusInternalServerError)+
fmt.Sprintf("error creating reusable request: %v", err), http.StatusInternalServerError) fmt.Sprintf("error creating reusable request: %v", err), http.StatusInternalServerError)
return return
} }
if err == errBodyTooLarge { if errors.Is(err, errBodyTooLarge) {
req.Body = ioutil.NopCloser(io.MultiReader(bytes.NewReader(bytesRead), req.Body)) req.Body = ioutil.NopCloser(io.MultiReader(bytes.NewReader(bytesRead), req.Body))
m.handler.ServeHTTP(rw, req) m.handler.ServeHTTP(rw, req)
logger.Debugf("no mirroring, request body larger than allowed size") logger.Debugf("no mirroring, request body larger than allowed size")
@ -196,13 +196,13 @@ func newReusableRequest(req *http.Request, maxBodySize int64) (*reusableRequest,
// the request body is larger than what we allow for the mirrors. // the request body is larger than what we allow for the mirrors.
body := make([]byte, maxBodySize+1) body := make([]byte, maxBodySize+1)
n, err := io.ReadFull(req.Body, body) n, err := io.ReadFull(req.Body, body)
if err != nil && err != io.ErrUnexpectedEOF { if err != nil && !errors.Is(err, io.ErrUnexpectedEOF) {
return nil, nil, err return nil, nil, err
} }
// we got an ErrUnexpectedEOF, which means there was less than maxBodySize data to read, // we got an ErrUnexpectedEOF, which means there was less than maxBodySize data to read,
// which permits us sending also to all the mirrors later. // which permits us sending also to all the mirrors later.
if err == io.ErrUnexpectedEOF { if errors.Is(err, io.ErrUnexpectedEOF) {
return &reusableRequest{ return &reusableRequest{
req: req, req: req,
body: body[:n], body: body[:n],

View file

@ -2,6 +2,7 @@ package wrr
import ( import (
"container/heap" "container/heap"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"sync" "sync"
@ -105,7 +106,7 @@ func (b *Balancer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if b.stickyCookie != nil { if b.stickyCookie != nil {
cookie, err := req.Cookie(b.stickyCookie.name) cookie, err := req.Cookie(b.stickyCookie.name)
if err != nil && err != http.ErrNoCookie { if err != nil && !errors.Is(err, http.ErrNoCookie) {
log.WithoutContext().Warnf("Error while reading cookie: %v", err) log.WithoutContext().Warnf("Error while reading cookie: %v", err)
} }

View file

@ -2,6 +2,7 @@ package service
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"io" "io"
"net" "net"
@ -83,13 +84,14 @@ func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwar
statusCode := http.StatusInternalServerError statusCode := http.StatusInternalServerError
switch { switch {
case err == io.EOF: case errors.Is(err, io.EOF):
statusCode = http.StatusBadGateway statusCode = http.StatusBadGateway
case err == context.Canceled: case errors.Is(err, context.Canceled):
statusCode = StatusClientClosedRequest statusCode = StatusClientClosedRequest
default: default:
if e, ok := err.(net.Error); ok { var netErr net.Error
if e.Timeout() { if errors.As(err, &netErr) {
if netErr.Timeout() {
statusCode = http.StatusGatewayTimeout statusCode = http.StatusGatewayTimeout
} else { } else {
statusCode = http.StatusBadGateway statusCode = http.StatusBadGateway

View file

@ -3,6 +3,7 @@ package service
import ( import (
"bufio" "bufio"
"crypto/tls" "crypto/tls"
"errors"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
@ -49,12 +50,13 @@ func TestWebSocketTCPClose(t *testing.T) {
withPath("/ws"), withPath("/ws"),
).open() ).open()
require.NoError(t, err) require.NoError(t, err)
conn.Close() conn.Close()
serverErr := <-errChan serverErr := <-errChan
wsErr, ok := serverErr.(*gorillawebsocket.CloseError) var wsErr *gorillawebsocket.CloseError
assert.Equal(t, true, ok) require.True(t, errors.As(serverErr, &wsErr))
assert.Equal(t, 1006, wsErr.Code) assert.Equal(t, 1006, wsErr.Code)
} }
@ -119,7 +121,7 @@ func TestWebSocketPingPong(t *testing.T) {
_, _, err = conn.ReadMessage() _, _, err = conn.ReadMessage()
if err != goodErr { if !errors.Is(err, goodErr) {
require.NoError(t, err) require.NoError(t, err)
} }
} }

View file

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"errors"
"io" "io"
"net" "net"
"net/http" "net/http"
@ -197,10 +198,11 @@ func (c *Conn) Read(p []byte) (n int, err error) {
func clientHelloServerName(br *bufio.Reader) (string, bool, string, error) { func clientHelloServerName(br *bufio.Reader) (string, bool, string, error) {
hdr, err := br.Peek(1) hdr, err := br.Peek(1)
if err != nil { if err != nil {
opErr, ok := err.(*net.OpError) var opErr *net.OpError
if err != io.EOF && (!ok || !opErr.Timeout()) { if !errors.Is(err, io.EOF) && (!errors.As(err, &opErr) || opErr.Timeout()) {
log.WithoutContext().Debugf("Error while Peeking first byte: %s", err) log.WithoutContext().Debugf("Error while Peeking first byte: %s", err)
} }
return "", false, "", err return "", false, "", err
} }

View file

@ -18,7 +18,7 @@ type Config struct {
LocalAgentHostPort string `description:"Set datadog-agent's host:port that the reporter will used." json:"localAgentHostPort,omitempty" toml:"localAgentHostPort,omitempty" yaml:"localAgentHostPort,omitempty"` LocalAgentHostPort string `description:"Set datadog-agent's host:port that the reporter will used." json:"localAgentHostPort,omitempty" toml:"localAgentHostPort,omitempty" yaml:"localAgentHostPort,omitempty"`
GlobalTag string `description:"Key:Value tag to be set on all the spans." json:"globalTag,omitempty" toml:"globalTag,omitempty" yaml:"globalTag,omitempty" export:"true"` GlobalTag string `description:"Key:Value tag to be set on all the spans." json:"globalTag,omitempty" toml:"globalTag,omitempty" yaml:"globalTag,omitempty" export:"true"`
Debug bool `description:"Enable Datadog debug." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"` Debug bool `description:"Enable Datadog debug." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"`
PrioritySampling bool `description:"Enable priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled." json:"prioritySampling,omitempty" toml:"prioritySampling,omitempty" yaml:"prioritySampling,omitempty"` PrioritySampling bool `description:"Enable priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled." json:"prioritySampling,omitempty" toml:"prioritySampling,omitempty" yaml:"prioritySampling,omitempty" export:"true"`
TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID." json:"traceIDHeaderName,omitempty" toml:"traceIDHeaderName,omitempty" yaml:"traceIDHeaderName,omitempty" export:"true"` TraceIDHeaderName string `description:"Specifies the header name that will be used to store the trace ID." json:"traceIDHeaderName,omitempty" toml:"traceIDHeaderName,omitempty" yaml:"traceIDHeaderName,omitempty" export:"true"`
ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." json:"parentIDHeaderName,omitempty" toml:"parentIDHeaderName,omitempty" yaml:"parentIDHeaderName,omitempty" export:"true"` ParentIDHeaderName string `description:"Specifies the header name that will be used to store the parent ID." json:"parentIDHeaderName,omitempty" toml:"parentIDHeaderName,omitempty" yaml:"parentIDHeaderName,omitempty" export:"true"`
SamplingPriorityHeaderName string `description:"Specifies the header name that will be used to store the sampling priority." json:"samplingPriorityHeaderName,omitempty" toml:"samplingPriorityHeaderName,omitempty" yaml:"samplingPriorityHeaderName,omitempty" export:"true"` SamplingPriorityHeaderName string `description:"Specifies the header name that will be used to store the sampling priority." json:"samplingPriorityHeaderName,omitempty" toml:"samplingPriorityHeaderName,omitempty" yaml:"samplingPriorityHeaderName,omitempty" export:"true"`

View file

@ -26,7 +26,7 @@ func init() {
type Config struct { type Config struct {
ServerURL string `description:"Set the URL of the Elastic APM server." json:"serverURL,omitempty" toml:"serverURL,omitempty" yaml:"serverURL,omitempty"` ServerURL string `description:"Set the URL of the Elastic APM server." json:"serverURL,omitempty" toml:"serverURL,omitempty" yaml:"serverURL,omitempty"`
SecretToken string `description:"Set the token used to connect to Elastic APM Server." json:"secretToken,omitempty" toml:"secretToken,omitempty" yaml:"secretToken,omitempty"` SecretToken string `description:"Set the token used to connect to Elastic APM Server." json:"secretToken,omitempty" toml:"secretToken,omitempty" yaml:"secretToken,omitempty"`
ServiceEnvironment string `description:"Set the name of the environment Traefik is deployed in, e.g. 'production' or 'staging'." json:"serviceEnvironment,omitempty" toml:"serviceEnvironment,omitempty" yaml:"serviceEnvironment,omitempty"` ServiceEnvironment string `description:"Set the name of the environment Traefik is deployed in, e.g. 'production' or 'staging'." json:"serviceEnvironment,omitempty" toml:"serviceEnvironment,omitempty" yaml:"serviceEnvironment,omitempty" export:"true"`
} }
// Setup sets up the tracer. // Setup sets up the tracer.

View file

@ -42,7 +42,7 @@ func (c *Config) SetDefaults() {
// Collector provides configuration settings for jaeger collector. // Collector provides configuration settings for jaeger collector.
type Collector struct { type Collector struct {
Endpoint string `description:"Instructs reporter to send spans to jaeger-collector at this URL." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty" export:"true"` Endpoint string `description:"Instructs reporter to send spans to jaeger-collector at this URL." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"`
User string `description:"User for basic http authentication when sending spans to jaeger-collector." json:"user,omitempty" toml:"user,omitempty" yaml:"user,omitempty"` User string `description:"User for basic http authentication when sending spans to jaeger-collector." json:"user,omitempty" toml:"user,omitempty" yaml:"user,omitempty"`
Password string `description:"Password for basic http authentication when sending spans to jaeger-collector." json:"password,omitempty" toml:"password,omitempty" yaml:"password,omitempty"` Password string `description:"Password for basic http authentication when sending spans to jaeger-collector." json:"password,omitempty" toml:"password,omitempty" yaml:"password,omitempty"`
} }

View file

@ -23,7 +23,7 @@ const (
type TraefikLog struct { type TraefikLog struct {
Level string `description:"Log level set to traefik logs." json:"level,omitempty" toml:"level,omitempty" yaml:"level,omitempty" export:"true"` Level string `description:"Log level set to traefik logs." json:"level,omitempty" toml:"level,omitempty" yaml:"level,omitempty" export:"true"`
FilePath string `description:"Traefik log file path. Stdout is used when omitted or empty." json:"filePath,omitempty" toml:"filePath,omitempty" yaml:"filePath,omitempty"` FilePath string `description:"Traefik log file path. Stdout is used when omitted or empty." json:"filePath,omitempty" toml:"filePath,omitempty" yaml:"filePath,omitempty"`
Format string `description:"Traefik log format: json | common" json:"format,omitempty" toml:"format,omitempty" yaml:"format,omitempty"` Format string `description:"Traefik log format: json | common" json:"format,omitempty" toml:"format,omitempty" yaml:"format,omitempty" export:"true"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.
@ -34,7 +34,7 @@ func (l *TraefikLog) SetDefaults() {
// AccessLog holds the configuration settings for the access logger (middlewares/accesslog). // AccessLog holds the configuration settings for the access logger (middlewares/accesslog).
type AccessLog struct { type AccessLog struct {
FilePath string `description:"Access log file path. Stdout is used when omitted or empty." json:"filePath,omitempty" toml:"filePath,omitempty" yaml:"filePath,omitempty" export:"true"` FilePath string `description:"Access log file path. Stdout is used when omitted or empty." json:"filePath,omitempty" toml:"filePath,omitempty" yaml:"filePath,omitempty"`
Format string `description:"Access log format: json | common" json:"format,omitempty" toml:"format,omitempty" yaml:"format,omitempty" export:"true"` Format string `description:"Access log format: json | common" json:"format,omitempty" toml:"format,omitempty" yaml:"format,omitempty" export:"true"`
Filters *AccessLogFilters `description:"Access log filters, used to keep only specific access logs." json:"filters,omitempty" toml:"filters,omitempty" yaml:"filters,omitempty" export:"true"` Filters *AccessLogFilters `description:"Access log filters, used to keep only specific access logs." json:"filters,omitempty" toml:"filters,omitempty" yaml:"filters,omitempty" export:"true"`
Fields *AccessLogFields `description:"AccessLogFields." json:"fields,omitempty" toml:"fields,omitempty" yaml:"fields,omitempty" export:"true"` Fields *AccessLogFields `description:"AccessLogFields." json:"fields,omitempty" toml:"fields,omitempty" yaml:"fields,omitempty" export:"true"`

View file

@ -8,10 +8,10 @@ import (
// Metrics provides options to expose and send Traefik metrics to different third party monitoring systems. // Metrics provides options to expose and send Traefik metrics to different third party monitoring systems.
type Metrics struct { type Metrics struct {
Prometheus *Prometheus `description:"Prometheus metrics exporter type." json:"prometheus,omitempty" toml:"prometheus,omitempty" yaml:"prometheus,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Prometheus *Prometheus `description:"Prometheus metrics exporter type." json:"prometheus,omitempty" toml:"prometheus,omitempty" yaml:"prometheus,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
Datadog *Datadog `description:"Datadog metrics exporter type." json:"datadog,omitempty" toml:"datadog,omitempty" yaml:"datadog,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Datadog *Datadog `description:"Datadog metrics exporter type." json:"datadog,omitempty" toml:"datadog,omitempty" yaml:"datadog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
StatsD *Statsd `description:"StatsD metrics exporter type." json:"statsD,omitempty" toml:"statsD,omitempty" yaml:"statsD,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` StatsD *Statsd `description:"StatsD metrics exporter type." json:"statsD,omitempty" toml:"statsD,omitempty" yaml:"statsD,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
InfluxDB *InfluxDB `description:"InfluxDB metrics exporter type." json:"influxDB,omitempty" toml:"influxDB,omitempty" yaml:"influxDB,omitempty" label:"allowEmpty" file:"allowEmpty"` InfluxDB *InfluxDB `description:"InfluxDB metrics exporter type." json:"influxDB,omitempty" toml:"influxDB,omitempty" yaml:"influxDB,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
} }
// Prometheus can contain specific configuration used by the Prometheus Metrics exporter. // Prometheus can contain specific configuration used by the Prometheus Metrics exporter.
@ -20,7 +20,7 @@ type Prometheus struct {
AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"` AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"`
AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"` AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"`
EntryPoint string `description:"EntryPoint" export:"true" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"` EntryPoint string `description:"EntryPoint" export:"true" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"`
ManualRouting bool `description:"Manual routing" json:"manualRouting,omitempty" toml:"manualRouting,omitempty" yaml:"manualRouting,omitempty"` ManualRouting bool `description:"Manual routing" json:"manualRouting,omitempty" toml:"manualRouting,omitempty" yaml:"manualRouting,omitempty" export:"true"`
} }
// SetDefaults sets the default values. // SetDefaults sets the default values.
@ -72,8 +72,8 @@ type InfluxDB struct {
PushInterval types.Duration `description:"InfluxDB push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"` PushInterval types.Duration `description:"InfluxDB push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"`
Database string `description:"InfluxDB database used when protocol is http." json:"database,omitempty" toml:"database,omitempty" yaml:"database,omitempty" export:"true"` Database string `description:"InfluxDB database used when protocol is http." json:"database,omitempty" toml:"database,omitempty" yaml:"database,omitempty" export:"true"`
RetentionPolicy string `description:"InfluxDB retention policy used when protocol is http." json:"retentionPolicy,omitempty" toml:"retentionPolicy,omitempty" yaml:"retentionPolicy,omitempty" export:"true"` RetentionPolicy string `description:"InfluxDB retention policy used when protocol is http." json:"retentionPolicy,omitempty" toml:"retentionPolicy,omitempty" yaml:"retentionPolicy,omitempty" export:"true"`
Username string `description:"InfluxDB username (only with http)." json:"username,omitempty" toml:"username,omitempty" yaml:"username,omitempty" export:"true"` Username string `description:"InfluxDB username (only with http)." json:"username,omitempty" toml:"username,omitempty" yaml:"username,omitempty"`
Password string `description:"InfluxDB password (only with http)." json:"password,omitempty" toml:"password,omitempty" yaml:"password,omitempty" export:"true"` Password string `description:"InfluxDB password (only with http)." json:"password,omitempty" toml:"password,omitempty" yaml:"password,omitempty"`
AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"` AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"`
AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"` AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"`
} }

View file

@ -15,10 +15,10 @@ import (
// CA, Cert and Key can be either path or file contents. // CA, Cert and Key can be either path or file contents.
type ClientTLS struct { type ClientTLS struct {
CA string `description:"TLS CA" json:"ca,omitempty" toml:"ca,omitempty" yaml:"ca,omitempty"` CA string `description:"TLS CA" json:"ca,omitempty" toml:"ca,omitempty" yaml:"ca,omitempty"`
CAOptional bool `description:"TLS CA.Optional" json:"caOptional,omitempty" toml:"caOptional,omitempty" yaml:"caOptional,omitempty"` CAOptional bool `description:"TLS CA.Optional" json:"caOptional,omitempty" toml:"caOptional,omitempty" yaml:"caOptional,omitempty" export:"true"`
Cert string `description:"TLS cert" json:"cert,omitempty" toml:"cert,omitempty" yaml:"cert,omitempty"` Cert string `description:"TLS cert" json:"cert,omitempty" toml:"cert,omitempty" yaml:"cert,omitempty"`
Key string `description:"TLS key" json:"key,omitempty" toml:"key,omitempty" yaml:"key,omitempty"` Key string `description:"TLS key" json:"key,omitempty" toml:"key,omitempty" yaml:"key,omitempty"`
InsecureSkipVerify bool `description:"TLS insecure skip verify" json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty"` InsecureSkipVerify bool `description:"TLS insecure skip verify" json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"`
} }
// CreateTLSConfig creates a TLS config from ClientTLS structures. // CreateTLSConfig creates a TLS config from ClientTLS structures.

View file

@ -1,6 +1,7 @@
package udp package udp
import ( import (
"errors"
"io" "io"
"net" "net"
"testing" "testing"
@ -24,7 +25,7 @@ func TestConsecutiveWrites(t *testing.T) {
go func() { go func() {
for { for {
conn, err := ln.Accept() conn, err := ln.Accept()
if err == errClosedListener { if errors.Is(err, errClosedListener) {
return return
} }
require.NoError(t, err) require.NoError(t, err)
@ -86,7 +87,7 @@ func TestListenNotBlocking(t *testing.T) {
go func() { go func() {
for { for {
conn, err := ln.Accept() conn, err := ln.Accept()
if err == errClosedListener { if errors.Is(err, errClosedListener) {
return return
} }
require.NoError(t, err) require.NoError(t, err)
@ -183,7 +184,7 @@ func testTimeout(t *testing.T, withRead bool) {
go func() { go func() {
for { for {
conn, err := ln.Accept() conn, err := ln.Accept()
if err == errClosedListener { if errors.Is(err, errClosedListener) {
return return
} }
require.NoError(t, err) require.NoError(t, err)