Merge branch 'v2.2' into master

This commit is contained in:
Michael 2020-05-18 18:37:11 +02:00
commit 7928e6d0cd
No known key found for this signature in database
GPG key ID: 71EDE16780F920E8
167 changed files with 554 additions and 563 deletions

View file

@ -49,6 +49,9 @@
"wsl", # Too strict
"gomnd", # Too strict
"stylecheck", # skip because report issues related to some generated files.
"testpackage", # Too strict
"goerr113", # Too strict
"nestif", # Too many false-positive.
]
[issues]
@ -62,7 +65,7 @@
]
[[issues.exclude-rules]]
path = "(.+)_test.go"
linters = ["goconst", "funlen"]
linters = ["goconst", "funlen", "godot"]
[[issues.exclude-rules]]
path = "integration/.+_test.go"
text = "Error return value of `cmd\\.Process\\.Kill` is not checked"
@ -105,3 +108,6 @@
[[issues.exclude-rules]]
path = "pkg/tracing/tracing.go"
text = "printf-like formatting function 'SetErrorWithEvent' should be named 'SetErrorWithEventf'"
[[issues.exclude-rules]]
path = "pkg/log/deprecated.go"
linters = ["godot"]

View file

@ -32,7 +32,7 @@ TRAEFIK_ENVS := \
TRAEFIK_MOUNT := -v "$(CURDIR)/$(BIND_DIR):/go/src/github.com/containous/traefik/$(BIND_DIR)"
DOCKER_RUN_OPTS := $(TRAEFIK_ENVS) $(TRAEFIK_MOUNT) "$(TRAEFIK_DEV_IMAGE)"
DOCKER_NON_INTERACTIVE ?= false
DOCKER_RUN_TRAEFIK := docker run $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -it) $(DOCKER_RUN_OPTS)
DOCKER_RUN_TRAEFIK := docker run --add-host=host.docker.internal:127.0.0.1 $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -it) $(DOCKER_RUN_OPTS)
DOCKER_RUN_TRAEFIK_NOTTY := docker run $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -i) $(DOCKER_RUN_OPTS)
PRE_TARGET ?= build-dev-image

View file

@ -19,7 +19,7 @@ RUN mkdir -p /usr/local/bin \
&& chmod +x /usr/local/bin/go-bindata
# 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.23.8
RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.26.0
# 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

View file

@ -7,7 +7,7 @@ import (
"syscall"
)
// ContextWithSignal creates a context canceled when SIGINT or SIGTERM are notified
// ContextWithSignal creates a context canceled when SIGINT or SIGTERM are notified.
func ContextWithSignal(ctx context.Context) context.Context {
newCtx, cancel := context.WithCancel(ctx)
signals := make(chan os.Signal)

View file

@ -45,7 +45,7 @@ func runCmd(traefikConfiguration *static.Configuration) func(_ []string) error {
}
}
// Do try to do a healthcheck
// Do try to do a healthcheck.
func Do(staticConfiguration static.Configuration) (*http.Response, error) {
if staticConfiguration.Ping == nil {
return nil, errors.New("please enable `ping` to use health check")

View file

@ -274,7 +274,7 @@ func switchRouter(routerFactory *server.RouterFactory, acmeProviders []*acme.Pro
}
}
// initACMEProvider creates an acme provider from the ACME part of globalConfiguration
// initACMEProvider creates an acme provider from the ACME part of globalConfiguration.
func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.ProviderAggregator, tlsManager *traefiktls.Manager) []*acme.Provider {
challengeStore := acme.NewLocalChallengeStore()
localStores := map[string]*acme.LocalStore{}

View file

@ -17,7 +17,7 @@ Go version: {{.GoVersion}}
Built: {{.BuildTime}}
OS/Arch: {{.Os}}/{{.Arch}}`
// NewCmd builds a new Version command
// NewCmd builds a new Version command.
func NewCmd() *cli.Command {
return &cli.Command{
Name: "version",
@ -33,7 +33,7 @@ func NewCmd() *cli.Command {
}
}
// GetPrint write Printable version
// GetPrint write Printable version.
func GetPrint(wr io.Writer) error {
tmpl, err := template.New("").Parse(versionTemplate)
if err != nil {

View file

@ -83,7 +83,7 @@ helm install traefik traefik/traefik
```bash tab="Using Helm CLI"
helm install --namespace=traefik-v2 \
--set="additionalArguments={--logs.level=DEBUG}" \
--set="additionalArguments={--log.level=DEBUG}" \
traefik traefik/traefik
```

View file

@ -105,13 +105,13 @@ Please check the [configuration examples below](#configuration-examples) for mor
```
```bash tab="CLI"
--entryPoints.web.address=:80
--entryPoints.websecure.address=:443
--entrypoints.web.address=:80
--entrypoints.websecure.address=:443
# ...
--certificatesResolvers.myresolver.acme.email=your-email@example.com
--certificatesResolvers.myresolver.acme.storage=acme.json
--certificatesresolvers.myresolver.acme.email=your-email@example.com
--certificatesresolvers.myresolver.acme.storage=acme.json
# used during the challenge
--certificatesResolvers.myresolver.acme.httpChallenge.entryPoint=web
--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
```
!!! important "Defining a certificates resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must [reference](../routing/routers/index.md#certresolver) it."
@ -181,7 +181,7 @@ when using the `TLS-ALPN-01` challenge, Traefik must be reachable by Let's Encry
```bash tab="CLI"
# ...
--certificatesResolvers.myresolver.acme.tlsChallenge=true
--certificatesresolvers.myresolver.acme.tlschallenge=true
```
### `httpChallenge`
@ -189,7 +189,7 @@ when using the `TLS-ALPN-01` challenge, Traefik must be reachable by Let's Encry
Use the `HTTP-01` challenge to generate and renew ACME certificates by provisioning an HTTP resource under a well-known URI.
As described on the Let's Encrypt [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72),
when using the `HTTP-01` challenge, `certificatesResolvers.myresolver.acme.httpChallenge.entryPoint` must be reachable by Let's Encrypt through port 80.
when using the `HTTP-01` challenge, `certificatesresolvers.myresolver.acme.httpchallenge.entrypoint` must be reachable by Let's Encrypt through port 80.
??? example "Using an EntryPoint Called web for the `httpChallenge`"
@ -224,10 +224,10 @@ when using the `HTTP-01` challenge, `certificatesResolvers.myresolver.acme.httpC
```
```bash tab="CLI"
--entryPoints.web.address=:80
--entryPoints.websecure.address=:443
--entrypoints.web.address=:80
--entrypoints.websecure.address=:443
# ...
--certificatesResolvers.myresolver.acme.httpChallenge.entryPoint=web
--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
```
!!! info ""
@ -261,8 +261,8 @@ Use the `DNS-01` challenge to generate and renew ACME certificates by provisioni
```bash tab="CLI"
# ...
--certificatesResolvers.myresolver.acme.dnsChallenge.provider=digitalocean
--certificatesResolvers.myresolver.acme.dnsChallenge.delayBeforeCheck=0
--certificatesresolvers.myresolver.acme.dnschallenge.provider=digitalocean
--certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0
# ...
```
@ -294,6 +294,7 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used
| [CloudXNS](https://www.cloudxns.net) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) |
| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conoha) |
| [Constellix](https://constellix.com) | `constellix` | `CONSTELLIX_API_KEY`, `CONSTELLIX_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/constellix) |
| [deSEC](https://desec.io) | `desec` | `DESEC_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/desec) |
| [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/digitalocean) |
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) |
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) |
@ -312,6 +313,7 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used
| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) |
| [GoDaddy](https://godaddy.com/) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) |
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) |
| [Hetzner](https://hetzner.com) | `hetzner` | `HETZNER_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hetzner) |
| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/hostingde) |
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) |
| [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) |
@ -321,12 +323,15 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used
| [Linode](https://www.linode.com) | `linode` | `LINODE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) |
| [Linode v4](https://www.linode.com) | `linodev4` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linodev4) |
| [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) |
| [LuaDNS](https://luadns.com) | `luadns` | `LUADNS_API_USERNAME`, `LUADNS_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/luadns) |
| manual | `manual` | none, but you need to run Traefik interactively [^4], turn on debug log to see instructions and press <kbd>Enter</kbd>. | |
| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) |
| [Mythic Beasts](https://www.mythic-beasts.com) | `mythicbeasts` | `MYTHICBEASTS_USER_NAME`, `MYTHICBEASTS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mythicbeasts) |
| [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namecheap) |
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/namedotcom) |
| [Namesilo](https://www.namesilo.com/) | `namesilo` | `NAMESILO_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namesilo) |
| [Netcup](https://www.netcup.eu/) | `netcup` | `NETCUP_CUSTOMER_NUMBER`, `NETCUP_API_KEY`, `NETCUP_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/netcup) |
| [Netlify](https://www.netlify.com) | `netlify` | `NETLIFY_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/netlify) |
| [NIFCloud](https://cloud.nifty.com/service/dns.htm) | `nifcloud` | `NIFCLOUD_ACCESS_KEY_ID`, `NIFCLOUD_SECRET_ACCESS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/nifcloud) |
| [Ns1](https://ns1.com/) | `ns1` | `NS1_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ns1) |
| [Open Telekom Cloud](https://cloud.telekom.de) | `otc` | `OTC_DOMAIN_NAME`, `OTC_USER_NAME`, `OTC_PASSWORD`, `OTC_PROJECT_NAME`, `OTC_IDENTITY_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/otc) |
@ -349,6 +354,7 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used
| [Versio](https://www.versio.nl/domeinnamen) | `versio` | `VERSIO_USERNAME`, `VERSIO_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/versio) |
| [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vscale) |
| [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/vultr) |
| [Yandex](https://yandex.com) | `yandex` | `YANDEX_PDD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandex) |
| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneee) |
| [Zonomi](https://zonomi.com) | `zonomi` | `ZONOMI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zonomi) |
@ -389,7 +395,7 @@ certificatesResolvers:
```bash tab="CLI"
# ...
--certificatesResolvers.myresolver.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53
--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53
```
#### Wildcard Domains
@ -428,7 +434,7 @@ The CA server to use:
```bash tab="CLI"
# ...
--certificatesResolvers.myresolver.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory
--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
# ...
```
@ -456,7 +462,7 @@ certificatesResolvers:
```bash tab="CLI"
# ...
--certificatesResolvers.myresolver.acme.storage=acme.json
--certificatesresolvers.myresolver.acme.storage=acme.json
# ...
```
@ -473,7 +479,7 @@ docker run -v "/my/host/acme:/etc/traefik/acme" traefik
```
!!! warning
For concurrency reason, this file cannot be shared across multiple instances of Traefik.
For concurrency reasons, this file cannot be shared across multiple instances of Traefik.
## Fallback

View file

@ -4,13 +4,13 @@
#
# Required
#
--certificatesResolvers.myresolver.acme.email=test@example.com
--certificatesresolvers.myresolver.acme.email=test@example.com
# File or key used for certificates storage.
#
# Required
#
--certificatesResolvers.myresolver.acme.storage=acme.json
--certificatesresolvers.myresolver.acme.storage=acme.json
# CA server to use.
# Uncomment the line to use Let's Encrypt's staging server,
@ -19,7 +19,7 @@
# Optional
# Default: "https://acme-v02.api.letsencrypt.org/directory"
#
--certificatesResolvers.myresolver.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory
--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
# KeyType to use.
#
@ -28,38 +28,38 @@
#
# Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192"
#
--certificatesResolvers.myresolver.acme.keyType=RSA4096
--certificatesresolvers.myresolver.acme.keytype=RSA4096
# Use a TLS-ALPN-01 ACME challenge.
#
# Optional (but recommended)
#
--certificatesResolvers.myresolver.acme.tlsChallenge=true
--certificatesresolvers.myresolver.acme.tlschallenge=true
# Use a HTTP-01 ACME challenge.
#
# Optional
#
--certificatesResolvers.myresolver.acme.httpChallenge=true
--certificatesresolvers.myresolver.acme.httpchallenge=true
# EntryPoint to use for the HTTP-01 challenges.
#
# Required
#
--certificatesResolvers.myresolver.acme.httpChallenge.entryPoint=web
--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
# Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
# Note: mandatory for wildcard certificate generation.
#
# Optional
#
--certificatesResolvers.myresolver.acme.dnsChallenge=true
--certificatesresolvers.myresolver.acme.dnschallenge=true
# DNS provider used.
#
# Required
#
--certificatesResolvers.myresolver.acme.dnsChallenge.provider=digitalocean
--certificatesresolvers.myresolver.acme.dnschallenge.provider=digitalocean
# By default, the provider will verify the TXT DNS challenge record before letting ACME verify.
# If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds.
@ -68,14 +68,14 @@
# Optional
# Default: 0
#
--certificatesResolvers.myresolver.acme.dnsChallenge.delayBeforeCheck=0
--certificatesresolvers.myresolver.acme.dnschallenge.delaybeforecheck=0
# Use following DNS servers to resolve the FQDN authority.
#
# Optional
# Default: empty
#
--certificatesResolvers.myresolver.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53
--certificatesresolvers.myresolver.acme.dnschallenge.resolvers=1.1.1.1:53,8.8.8.8:53
# Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready.
#
@ -85,4 +85,4 @@
# Optional
# Default: false
#
--certificatesResolvers.myresolver.acme.dnsChallenge.disablePropagationCheck=true
--certificatesresolvers.myresolver.acme.dnschallenge.disablepropagationcheck=true

View file

@ -208,7 +208,7 @@ metadata:
spec:
redirectScheme:
# ...
port: 443
port: "443"
```
```yaml tab="Consul Catalog"
@ -247,5 +247,7 @@ http:
test-redirectscheme:
redirectScheme:
# ...
port: 443
port: "443"
```
!!! info "Port in this configuration is a string, not a numeric value."

View file

@ -358,17 +358,3 @@ providers:
If one wants to know more about the various aspects of the Ingress spec that Traefik supports,
many examples of Ingresses definitions are located in the tests [data](https://github.com/containous/traefik/tree/v2.2/pkg/provider/kubernetes/ingress/fixtures) of the Traefik repository.
## LetsEncrypt Support with the Ingress Provider
By design, Traefik is a stateless application, meaning that it only derives its configuration from the environment it runs in, without additional configuration.
For this reason, users can run multiple instances of Traefik at the same time to achieve HA, as is a common pattern in the kubernetes ecosystem.
When using a single instance of Traefik with LetsEncrypt, no issues should be encountered, however this could be a single point of failure.
Unfortunately, it is not possible to run multiple instances of Traefik 2.0 with LetsEncrypt enabled, because there is no way to ensure that the correct instance of Traefik will receive the challenge request, and subsequent responses.
Previous versions of Traefik used a [KV store](https://docs.traefik.io/v1.7/configuration/acme/#storage) to attempt to achieve this, but due to sub-optimal performance was dropped as a feature in 2.0.
If you require LetsEncrypt with HA in a kubernetes environment, we recommend using [TraefikEE](https://containo.us/traefikee/) where distributed LetsEncrypt is a supported feature.
If you are wanting to continue to run Traefik Community Edition, LetsEncrypt HA can be achieved by using a Certificate Controller such as [Cert-Manager](https://docs.cert-manager.io/en/latest/index.html).
When using Cert-Manager to manage certificates, it will create secrets in your namespaces that can be referenced as TLS secrets in your [ingress objects](https://kubernetes.io/docs/concepts/services-networking/ingress/#tls).

View file

@ -26,7 +26,7 @@ theme:
prev: 'Previous'
next: 'Next'
copyright: "Copyright &copy; 2016-2019 Containous"
copyright: "Copyright &copy; 2016-2020 Containous"
google_analytics:
- 'UA-51880359-3'

2
go.mod
View file

@ -36,7 +36,7 @@ require (
github.com/fatih/structs v1.1.0
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2
github.com/go-acme/lego/v3 v3.6.0
github.com/go-acme/lego/v3 v3.7.0
github.com/go-check/check v0.0.0-00010101000000-000000000000
github.com/go-kit/kit v0.9.0
github.com/golang/protobuf v1.3.4

17
go.sum
View file

@ -109,8 +109,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aws/aws-sdk-go v1.16.23/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.23.0 h1:ilfJN/vJtFo1XDFxB2YMBYGeOvGZl6Qow17oyD4+Z9A=
github.com/aws/aws-sdk-go v1.23.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.30.20 h1:ktsy2vodSZxz/arYqo7DlpkIeNohHL+4Rmjdo7YGtrE=
github.com/aws/aws-sdk-go v1.30.20/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@ -182,8 +182,8 @@ github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TR
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2 h1:G9/PqfhOrt8JXnw0DGTfVoOkKHDhOlEZqhE/cu+NvQM=
github.com/dnaeon/go-vcr v0.0.0-20180814043457-aafff18a5cc2/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/dnsimple/dnsimple-go v0.30.0 h1:IBIrn9jMKRMwporIRwdFyKdnHXVmwy6obnguB+ZMDIY=
github.com/dnsimple/dnsimple-go v0.30.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
github.com/dnsimple/dnsimple-go v0.60.0 h1:N+q+ML1CZGf+5r4udu9Opy7WJNtOaFT9aM86Af9gLhk=
github.com/dnsimple/dnsimple-go v0.60.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
github.com/docker/cli v0.0.0-20200221155518-740919cc7fc0 h1:hlGHcYGaaHs/yffSubcUKlp8TyV1v7qhcZZ5nGNQ2Fw=
github.com/docker/cli v0.0.0-20200221155518-740919cc7fc0/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
@ -247,8 +247,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 v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-acme/lego/v3 v3.6.0 h1:Rv0MrX3DpVp9Xg77yR7x+PCksLLph3Ut/69/9Kim8ac=
github.com/go-acme/lego/v3 v3.6.0/go.mod h1:sB/T7hfyz0HYIBvPmz/C8jIaxF6scbbiGKTzbQ22V6A=
github.com/go-acme/lego/v3 v3.7.0 h1:qC5/8/CbltyAE8fGLE6bGlqucj7pXc/vBxiLwLOsmAQ=
github.com/go-acme/lego/v3 v3.7.0/go.mod h1:4eDjjYkAsDXyNcwN8IhhZAwxz9Ltiks1Zmpv0q20J7A=
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/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
@ -277,6 +277,7 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
@ -425,6 +426,8 @@ github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4=
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
github.com/jonboulle/clockwork v0.1.0 h1:VKV+ZcuP6l3yW9doeqz6ziZGgcynBVQO+obU0+0hcPo=
@ -587,6 +590,8 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=

View file

@ -24,7 +24,7 @@ const (
traefikTestAccessLogFile = "access.log"
)
// AccessLogSuite
// AccessLogSuite tests suite.
type AccessLogSuite struct{ BaseSuite }
type accessLogValue struct {
@ -562,7 +562,7 @@ func extractLines(c *check.C) []string {
func checkStatsForLogFile(c *check.C) {
err := try.Do(1*time.Second, func() error {
if _, errStat := os.Stat(traefikTestLogFile); errStat != nil {
return fmt.Errorf("could not get stats for log file: %s", errStat)
return fmt.Errorf("could not get stats for log file: %w", errStat)
}
return nil
})

View file

@ -20,7 +20,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// ACME test suites (using libcompose)
// ACME test suites (using libcompose).
type AcmeSuite struct {
BaseSuite
pebbleIP string
@ -74,7 +74,7 @@ func setupPebbleRootCA() (*http.Transport, error) {
certPool := x509.NewCertPool()
if ok := certPool.AppendCertsFromPEM(customCAs); !ok {
return nil, fmt.Errorf("error creating x509 cert pool from %q: %v", path, err)
return nil, fmt.Errorf("error creating x509 cert pool from %q: %w", path, err)
}
return &http.Transport{
@ -394,7 +394,7 @@ func (s *AcmeSuite) TestTLSALPN01DomainsInSAN(c *check.C) {
s.retrieveAcmeCertificate(c, testCase)
}
// Test Let's encrypt down
// Test Let's encrypt down.
func (s *AcmeSuite) TestNoValidLetsEncryptServer(c *check.C) {
file := s.adaptFile(c, "fixtures/acme/acme_base.toml", templateModel{
Acme: map[string]static.CertificateResolver{
@ -417,7 +417,7 @@ func (s *AcmeSuite) TestNoValidLetsEncryptServer(c *check.C) {
c.Assert(err, checker.IsNil)
}
// Doing an HTTPS request and test the response certificate
// Doing an HTTPS request and test the response certificate.
func (s *AcmeSuite) retrieveAcmeCertificate(c *check.C, testCase acmeTestCase) {
if len(testCase.template.PortHTTP) == 0 {
testCase.template.PortHTTP = ":5002"

View file

@ -47,7 +47,7 @@ func (s *ConsulCatalogSuite) waitToElectConsulLeader() error {
leader, err := s.consulClient.Status().Leader()
if err != nil || len(leader) == 0 {
return fmt.Errorf("leader not found. %v", err)
return fmt.Errorf("leader not found. %w", err)
}
return nil

View file

@ -19,7 +19,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// Consul test suites (using libcompose)
// Consul test suites (using libcompose).
type ConsulSuite struct {
BaseSuite
kvClient store.Store

View file

@ -18,7 +18,7 @@ const (
composeProject = "minimal"
)
// Docker test suites
// Docker tests suite.
type DockerComposeSuite struct {
BaseSuite
}

View file

@ -17,14 +17,14 @@ import (
checker "github.com/vdemeester/shakers"
)
// Images to have or pull before the build in order to make it work
// FIXME handle this offline but loading them before build
// Images to have or pull before the build in order to make it work.
// FIXME handle this offline but loading them before build.
var RequiredImages = map[string]string{
"swarm": "1.0.0",
"containous/whoami": "latest",
}
// Docker test suites
// Docker tests suite.
type DockerSuite struct {
BaseSuite
project *docker.Project

View file

@ -10,7 +10,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// ErrorPagesSuite test suites (using libcompose)
// ErrorPagesSuite test suites (using libcompose).
type ErrorPagesSuite struct {
BaseSuite
ErrorPageIP string

View file

@ -19,7 +19,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// etcd test suites (using libcompose)
// etcd test suites (using libcompose).
type EtcdSuite struct {
BaseSuite
kvClient store.Store

View file

@ -10,7 +10,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// File test suites
// File tests suite.
type FileSuite struct{ BaseSuite }
func (s *FileSuite) SetUpSuite(c *check.C) {
@ -32,7 +32,7 @@ func (s *FileSuite) TestSimpleConfiguration(c *check.C) {
c.Assert(err, checker.IsNil)
}
// #56 regression test, make sure it does not fail
// #56 regression test, make sure it does not fail?
func (s *FileSuite) TestSimpleConfigurationNoPanic(c *check.C) {
cmd, display := s.traefikCmd(withConfigFile("fixtures/file/56-simple-panic.toml"))
defer display(c)

View file

@ -24,7 +24,7 @@ var LocalhostKey []byte
const randCharset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
// GRPCSuite
// GRPCSuite tests suite.
type GRPCSuite struct{ BaseSuite }
type myserver struct {

View file

@ -10,7 +10,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// Headers test suites
// Headers tests suite.
type HeadersSuite struct{ BaseSuite }
func (s *HeadersSuite) TestSimpleConfiguration(c *check.C) {

View file

@ -11,7 +11,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// HealthCheck test suites (using libcompose)
// HealthCheck test suites (using libcompose).
type HealthCheckSuite struct {
BaseSuite
whoami1IP string
@ -206,7 +206,7 @@ func (s *HealthCheckSuite) TestPortOverload(c *check.C) {
c.Assert(err, checker.IsNil)
}
// Checks if all the loadbalancers created will correctly update the server status
// Checks if all the loadbalancers created will correctly update the server status.
func (s *HealthCheckSuite) TestMultipleRoutersOnSameService(c *check.C) {
file := s.adaptFile(c, "fixtures/healthcheck/multiple-routers-one-same-service.toml", struct {
Server1 string

View file

@ -18,7 +18,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// HTTPSSuite
// HTTPSSuite tests suite.
type HTTPSSuite struct{ BaseSuite }
// TestWithSNIConfigHandshake involves a client sending a SNI hostname of
@ -441,7 +441,7 @@ func (s *HTTPSSuite) TestWithOverlappingDynamicCertificate(c *check.C) {
}
// TestWithClientCertificateAuthentication
// The client can send a certificate signed by a CA trusted by the server but it's optional
// The client can send a certificate signed by a CA trusted by the server but it's optional.
func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) {
file := s.adaptFile(c, "fixtures/https/clientca/https_1ca1config.toml", struct{}{})
defer os.Remove(file)
@ -499,7 +499,7 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) {
}
// TestWithClientCertificateAuthentication
// Use two CA:s and test that clients with client signed by either of them can connect
// Use two CA:s and test that clients with client signed by either of them can connect.
func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipleCAs(c *check.C) {
server1 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) { _, _ = rw.Write([]byte("server1")) }))
server2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) { _, _ = rw.Write([]byte("server2")) }))
@ -596,7 +596,7 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipleCAs(c *check
}
// TestWithClientCertificateAuthentication
// Use two CA:s in two different files and test that clients with client signed by either of them can connect
// Use two CA:s in two different files and test that clients with client signed by either of them can connect.
func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipleCAsMultipleFiles(c *check.C) {
server1 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) { _, _ = rw.Write([]byte("server1")) }))
server2 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, _ *http.Request) { _, _ = rw.Write([]byte("server2")) }))

View file

@ -24,7 +24,7 @@ import (
var updateExpected = flag.Bool("update_expected", false, "Update expected files in testdata")
// K8sSuite
// K8sSuite tests suite.
type K8sSuite struct{ BaseSuite }
func (s *K8sSuite) SetUpSuite(c *check.C) {
@ -128,7 +128,7 @@ func matchesConfig(wantConfig string, buf *bytes.Buffer) try.ResponseCondition {
return func(res *http.Response) error {
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %s", err)
return fmt.Errorf("failed to read response body: %w", err)
}
if err := res.Body.Close(); err != nil {

View file

@ -16,7 +16,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// Log rotation integration test suite
// Log rotation integration test suite.
type LogRotationSuite struct{ BaseSuite }
func (s *LogRotationSuite) SetUpSuite(c *check.C) {

View file

@ -12,7 +12,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// Marathon test suites (using libcompose)
// Marathon test suites (using libcompose).
type MarathonSuite15 struct {
BaseSuite
marathonURL string

View file

@ -17,7 +17,7 @@ const (
containerNameMarathon = "marathon"
)
// Marathon test suites (using libcompose)
// Marathon test suites (using libcompose).
type MarathonSuite struct {
BaseSuite
marathonURL string

View file

@ -19,7 +19,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// Redis test suites (using libcompose)
// Redis test suites (using libcompose).
type RedisSuite struct {
BaseSuite
kvClient store.Store

View file

@ -20,7 +20,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// SimpleSuite
// SimpleSuite tests suite.
type SimpleSuite struct{ BaseSuite }
func (s *SimpleSuite) TestInvalidConfigShouldFail(c *check.C) {

View file

@ -12,18 +12,16 @@ import (
)
// ResponseCondition is a retry condition function.
// It receives a response, and returns an error
// if the response failed the condition.
// It receives a response, and returns an error if the response failed the condition.
type ResponseCondition func(*http.Response) error
// BodyContains returns a retry condition function.
// The condition returns an error if the request body does not contain all the given
// strings.
// The condition returns an error if the request body does not contain all the given strings.
func BodyContains(values ...string) ResponseCondition {
return func(res *http.Response) error {
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %s", err)
return fmt.Errorf("failed to read response body: %w", err)
}
for _, value := range values {
@ -36,13 +34,12 @@ func BodyContains(values ...string) ResponseCondition {
}
// BodyNotContains returns a retry condition function.
// The condition returns an error if the request body contain one of the given
// strings.
// The condition returns an error if the request body contain one of the given strings.
func BodyNotContains(values ...string) ResponseCondition {
return func(res *http.Response) error {
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %s", err)
return fmt.Errorf("failed to read response body: %w", err)
}
for _, value := range values {
@ -55,13 +52,12 @@ func BodyNotContains(values ...string) ResponseCondition {
}
// BodyContainsOr returns a retry condition function.
// The condition returns an error if the request body does not contain one of the given
// strings.
// The condition returns an error if the request body does not contain one of the given strings.
func BodyContainsOr(values ...string) ResponseCondition {
return func(res *http.Response) error {
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %s", err)
return fmt.Errorf("failed to read response body: %w", err)
}
for _, value := range values {
@ -79,7 +75,7 @@ func HasBody() ResponseCondition {
return func(res *http.Response) error {
body, err := ioutil.ReadAll(res.Body)
if err != nil {
return fmt.Errorf("failed to read response body: %s", err)
return fmt.Errorf("failed to read response body: %w", err)
}
if len(body) == 0 {
@ -182,11 +178,11 @@ func HasHeaderStruct(header http.Header) ResponseCondition {
}
// DoCondition is a retry condition function.
// It returns an error
// It returns an error.
type DoCondition func() error
// KVExists is a retry condition function.
// Verify if a Key exists in the store
// Verify if a Key exists in the store.
func KVExists(kv store.Store, key string) DoCondition {
return func() error {
_, err := kv.Exists(key, nil)

View file

@ -115,7 +115,7 @@ func Do(timeout time.Duration, operation DoCondition) error {
select {
case <-stopTimer.C:
fmt.Println("-")
return fmt.Errorf("try operation failed: %s", err)
return fmt.Errorf("try operation failed: %w", err)
case <-retryTick.C:
fmt.Print("*")
if err = operation(); err == nil {

View file

@ -18,7 +18,7 @@ import (
"golang.org/x/net/websocket"
)
// WebsocketSuite
// WebsocketSuite tests suite.
type WebsocketSuite struct{ BaseSuite }
func (s *WebsocketSuite) TestBase(c *check.C) {

View file

@ -19,7 +19,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// Zk test suites (using libcompose)
// Zk test suites (using libcompose).
type ZookeeperSuite struct {
BaseSuite
kvClient store.Store

View file

@ -15,7 +15,7 @@ const (
maskLarge = maskShort + maskShort + maskShort + maskShort + maskShort + maskShort + maskShort + maskShort
)
// Do configuration.
// Do sends configuration.
func Do(baseConfig interface{}, indent bool) (string, error) {
anomConfig, err := copystructure.Copy(baseConfig)
if err != nil {
@ -120,7 +120,7 @@ func reset(field reflect.Value, name string) error {
return nil
}
// isExported return true is a struct field is exported, else false
// isExported return true is a struct field is exported, else false.
func isExported(f reflect.StructField) bool {
if f.PkgPath != "" && !f.Anonymous {
return false

View file

@ -8,12 +8,12 @@ import (
"github.com/gorilla/mux"
)
// DashboardHandler expose dashboard routes
// DashboardHandler expose dashboard routes.
type DashboardHandler struct {
Assets *assetfs.AssetFS
}
// Append add dashboard routes on a router
// Append add dashboard routes on a router.
func (g DashboardHandler) Append(router *mux.Router) {
if g.Assets == nil {
log.WithoutContext().Error("No assets for dashboard")

View file

@ -19,10 +19,10 @@ func goroutines() interface{} {
return runtime.NumGoroutine()
}
// DebugHandler expose debug routes
// DebugHandler expose debug routes.
type DebugHandler struct{}
// Append add debug routes on a router
// Append add debug routes on a router.
func (g DebugHandler) Append(router *mux.Router) {
router.Methods(http.MethodGet).Path("/debug/vars").
HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {

View file

@ -55,7 +55,7 @@ type Handler struct {
runtimeConfiguration *runtime.Configuration
}
// NewBuilder returns a http.Handler builder based on runtime.Configuration
// NewBuilder returns a http.Handler builder based on runtime.Configuration.
func NewBuilder(staticConfig static.Configuration) func(*runtime.Configuration) http.Handler {
return func(configuration *runtime.Configuration) http.Handler {
return New(staticConfig, configuration).createRouter()

View file

@ -55,7 +55,7 @@ func execute(cmd *Command, args []string, root bool) error {
// Calls command without args.
if len(args) == 1 {
if err := run(cmd, args[1:]); err != nil {
return fmt.Errorf("command %s error: %v", args[0], err)
return fmt.Errorf("command %s error: %w", args[0], err)
}
return nil
}
@ -65,7 +65,7 @@ func execute(cmd *Command, args []string, root bool) error {
// then we run the top level command itself.
if root && cmd.Name != args[1] && !contains(cmd.subCommands, args[1]) {
if err := run(cmd, args[1:]); err != nil {
return fmt.Errorf("command %s error: %v", filepath.Base(args[0]), err)
return fmt.Errorf("command %s error: %w", filepath.Base(args[0]), err)
}
return nil
}
@ -74,7 +74,7 @@ func execute(cmd *Command, args []string, root bool) error {
if len(args) >= 2 && cmd.Name == args[1] {
if len(args) < 3 || !contains(cmd.subCommands, args[2]) {
if err := run(cmd, args[2:]); err != nil {
return fmt.Errorf("command %s error: %v", cmd.Name, err)
return fmt.Errorf("command %s error: %w", cmd.Name, err)
}
return nil
}
@ -83,7 +83,7 @@ func execute(cmd *Command, args []string, root bool) error {
// No sub-command, calls the current command.
if len(cmd.subCommands) == 0 {
if err := run(cmd, args[1:]); err != nil {
return fmt.Errorf("command %s error: %v", cmd.Name, err)
return fmt.Errorf("command %s error: %w", cmd.Name, err)
}
return nil
}

View file

@ -21,7 +21,7 @@ func (e *EnvLoader) Load(_ []string, cmd *Command) (bool, error) {
if err := env.Decode(vars, env.DefaultNamePrefix, cmd.Configuration); err != nil {
log.WithoutContext().Debug("environment variables", strings.Join(vars, ", "))
return false, fmt.Errorf("failed to decode configuration from environment variables: %v ", err)
return false, fmt.Errorf("failed to decode configuration from environment variables: %w ", err)
}
log.WithoutContext().Println("Configuration loaded from environment variables.")

View file

@ -17,7 +17,7 @@ func (*FlagLoader) Load(args []string, cmd *Command) (bool, error) {
}
if err := flag.Decode(args, cmd.Configuration); err != nil {
return false, fmt.Errorf("failed to decode configuration from flags: %v", err)
return false, fmt.Errorf("failed to decode configuration from flags: %w", err)
}
log.WithoutContext().Println("Configuration loaded from flags.")

View file

@ -16,10 +16,10 @@ import (
"github.com/mitchellh/hashstructure"
)
// collectorURL URL where the stats are send
// collectorURL URL where the stats are send.
const collectorURL = "https://collect.traefik.io/9vxmmkcdmalbdi635d4jgc5p5rx0h7h8"
// Collected data
// Collected data.
type data struct {
Version string
Codename string

View file

@ -19,7 +19,7 @@ type Configurations map[string]*Configuration
// +k8s:deepcopy-gen=true
// Configuration is the root of the dynamic configuration
// Configuration is the root of the dynamic configuration.
type Configuration struct {
HTTP *HTTPConfiguration `json:"http,omitempty" toml:"http,omitempty" yaml:"http,omitempty"`
TCP *TCPConfiguration `json:"tcp,omitempty" toml:"tcp,omitempty" yaml:"tcp,omitempty"`

View file

@ -47,7 +47,7 @@ type Router struct {
// +k8s:deepcopy-gen=true
// RouterTLSConfig holds the TLS configuration for a router
// RouterTLSConfig holds the TLS configuration for a router.
type RouterTLSConfig struct {
Options string `json:"options,omitempty" toml:"options,omitempty" yaml:"options,omitempty"`
CertResolver string `json:"certResolver,omitempty" toml:"certResolver,omitempty" yaml:"certResolver,omitempty"`

View file

@ -95,7 +95,7 @@ type Buffering struct {
// +k8s:deepcopy-gen=true
// Chain holds a chain of middlewares
// Chain holds a chain of middlewares.
type Chain struct {
Middlewares []string `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty"`
}
@ -191,13 +191,13 @@ type Headers struct {
IsDevelopment bool `json:"isDevelopment,omitempty" toml:"isDevelopment,omitempty" yaml:"isDevelopment,omitempty"`
}
// HasCustomHeadersDefined checks to see if any of the custom header elements have been set
// HasCustomHeadersDefined checks to see if any of the custom header elements have been set.
func (h *Headers) HasCustomHeadersDefined() bool {
return h != nil && (len(h.CustomResponseHeaders) != 0 ||
len(h.CustomRequestHeaders) != 0)
}
// HasCorsHeadersDefined checks to see if any of the cors header elements have been set
// HasCorsHeadersDefined checks to see if any of the cors header elements have been set.
func (h *Headers) HasCorsHeadersDefined() bool {
return h != nil && (h.AccessControlAllowCredentials ||
len(h.AccessControlAllowHeaders) != 0 ||
@ -208,7 +208,7 @@ func (h *Headers) HasCorsHeadersDefined() bool {
h.AddVaryHeader)
}
// HasSecureHeadersDefined checks to see if any of the secure header elements have been set
// HasSecureHeadersDefined checks to see if any of the secure header elements have been set.
func (h *Headers) HasSecureHeadersDefined() bool {
return h != nil && (len(h.AllowedHosts) != 0 ||
len(h.HostsProxyHeaders) != 0 ||
@ -245,7 +245,7 @@ type IPStrategy struct {
// Get an IP selection strategy.
// If nil return the RemoteAddr strategy
// else return a strategy base on the configuration using the X-Forwarded-For Header.
// Depth override the ExcludedIPs
// Depth override the ExcludedIPs.
func (s *IPStrategy) Get() (ip.Strategy, error) {
if s == nil {
return &ip.RemoteAddrStrategy{}, nil
@ -420,7 +420,7 @@ type TLSCLientCertificateDNInfo struct {
// +k8s:deepcopy-gen=true
// Users holds a list of users
// Users holds a list of users.
type Users []string
// +k8s:deepcopy-gen=true
@ -449,7 +449,7 @@ func (c *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
if _, errCA := os.Stat(c.CA); errCA == nil {
ca, err = ioutil.ReadFile(c.CA)
if err != nil {
return nil, fmt.Errorf("failed to read CA. %s", err)
return nil, fmt.Errorf("failed to read CA. %w", err)
}
} else {
ca = []byte(c.CA)
@ -478,7 +478,7 @@ func (c *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
if errKeyIsFile == nil {
cert, err = tls.LoadX509KeyPair(c.Cert, c.Key)
if err != nil {
return nil, fmt.Errorf("failed to load TLS keypair: %v", err)
return nil, fmt.Errorf("failed to load TLS keypair: %w", err)
}
} else {
return nil, fmt.Errorf("tls cert is a file, but tls key is not")
@ -487,7 +487,7 @@ func (c *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
if errKeyIsFile != nil {
cert, err = tls.X509KeyPair([]byte(c.Cert), []byte(c.Key))
if err != nil {
return nil, fmt.Errorf("failed to load TLS keypair: %v", err)
return nil, fmt.Errorf("failed to load TLS keypair: %w", err)
}
} else {
return nil, fmt.Errorf("TLS key is a file, but tls cert is not")

View file

@ -55,7 +55,7 @@ type TCPRouter struct {
// +k8s:deepcopy-gen=true
// RouterTCPTLSConfig holds the TLS configuration for a router
// RouterTCPTLSConfig holds the TLS configuration for a router.
type RouterTCPTLSConfig struct {
Passthrough bool `json:"passthrough" toml:"passthrough" yaml:"passthrough"`
Options string `json:"options,omitempty" toml:"options,omitempty" yaml:"options,omitempty"`
@ -76,7 +76,7 @@ type TCPServersLoadBalancer struct {
Servers []TCPServer `json:"servers,omitempty" toml:"servers,omitempty" yaml:"servers,omitempty" label-slice-as-struct:"server"`
}
// SetDefaults Default values for a TCPServersLoadBalancer
// SetDefaults Default values for a TCPServersLoadBalancer.
func (l *TCPServersLoadBalancer) SetDefaults() {
defaultTerminationDelay := 100 // in milliseconds
l.TerminationDelay = &defaultTerminationDelay
@ -101,7 +101,7 @@ func (l *TCPServersLoadBalancer) Mergeable(loadBalancer *TCPServersLoadBalancer)
// +k8s:deepcopy-gen=true
// TCPServer holds a TCP Server configuration
// TCPServer holds a TCP Server configuration.
type TCPServer struct {
Address string `json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty" label:"-"`
Port string `toml:"-" json:"-" yaml:"-"`

View file

@ -17,7 +17,7 @@ const DefaultNamePrefix = "TRAEFIK_"
// env vars -> map
// map -> tree of untyped nodes
// untyped nodes -> nodes augmented with metadata such as kind (inferred from element)
// "typed" nodes -> typed element
// "typed" nodes -> typed element.
func Decode(environ []string, prefix string, element interface{}) error {
if err := checkPrefix(prefix); err != nil {
return err
@ -40,7 +40,7 @@ func Decode(environ []string, prefix string, element interface{}) error {
// The operation goes through three stages roughly summarized as:
// typed configuration in element -> tree of untyped nodes
// untyped nodes -> nodes augmented with metadata such as kind (inferred from element)
// "typed" nodes -> environment variables with default values (determined by type/kind)
// "typed" nodes -> environment variables with default values (determined by type/kind).
func Encode(element interface{}) ([]parser.Flat, error) {
if element == nil {
return nil, nil

View file

@ -9,7 +9,7 @@ import (
// The operation goes through three stages roughly summarized as:
// file contents -> tree of untyped nodes
// untyped nodes -> nodes augmented with metadata such as kind (inferred from element)
// "typed" nodes -> typed element
// "typed" nodes -> typed element.
func Decode(filePath string, element interface{}) error {
if element == nil {
return nil

View file

@ -10,7 +10,7 @@ import (
// flag arguments -> parsed map of flags
// map -> tree of untyped nodes
// untyped nodes -> nodes augmented with metadata such as kind (inferred from element)
// "typed" nodes -> typed element
// "typed" nodes -> typed element.
func Decode(args []string, element interface{}) error {
ref, err := Parse(args, element)
if err != nil {
@ -24,7 +24,7 @@ func Decode(args []string, element interface{}) error {
// The operation goes through three stages roughly summarized as:
// typed configuration in element -> tree of untyped nodes
// untyped nodes -> nodes augmented with metadata such as kind (inferred from element)
// "typed" nodes -> flags with default values (determined by type/kind)
// "typed" nodes -> flags with default values (determined by type/kind).
func Encode(element interface{}) ([]parser.Flat, error) {
if element == nil {
return nil, nil

View file

@ -12,7 +12,7 @@ import (
// The operation goes through three stages roughly summarized as:
// KV pairs -> tree of untyped nodes
// untyped nodes -> nodes augmented with metadata such as kind (inferred from element)
// "typed" nodes -> typed element
// "typed" nodes -> typed element.
func Decode(pairs []*store.KVPair, element interface{}, rootName string) error {
if element == nil {
return nil

View file

@ -28,7 +28,7 @@ func EncodeConfiguration(conf *dynamic.Configuration) (map[string]string, error)
}
// Decode converts the labels to an element.
// labels -> [ node -> node + metadata (type) ] -> element (node)
// labels -> [ node -> node + metadata (type) ] -> element (node).
func Decode(labels map[string]string, element interface{}, filters ...string) error {
return parser.Decode(labels, element, parser.DefaultRootName, filters...)
}

View file

@ -15,7 +15,7 @@ type EncoderToNodeOpts struct {
}
// EncodeToNode converts an element to a node.
// element -> nodes
// element -> nodes.
func EncodeToNode(element interface{}, rootName string, opts EncoderToNodeOpts) (*Node, error) {
rValue := reflect.ValueOf(element)
node := &Node{Name: rootName}

View file

@ -1,7 +1,7 @@
package parser
// EncodeNode Converts a node to labels.
// nodes -> labels
// nodes -> labels.
func EncodeNode(node *Node) map[string]string {
labels := make(map[string]string)
encodeNode(labels, node.Name, node)

View file

@ -6,7 +6,7 @@ package parser
// The operation goes through three stages roughly summarized as:
// labels -> tree of untyped nodes
// untyped nodes -> nodes augmented with metadata such as kind (inferred from element)
// "typed" nodes -> typed element
// "typed" nodes -> typed element.
func Decode(labels map[string]string, element interface{}, rootName string, filters ...string) error {
node, err := DecodeToNode(labels, rootName, filters...)
if err != nil {
@ -28,7 +28,7 @@ func Decode(labels map[string]string, element interface{}, rootName string, filt
}
// Encode converts an element to labels.
// element -> node (value) -> label (node)
// element -> node (value) -> label (node).
func Encode(element interface{}, rootName string) (map[string]string, error) {
etnOpts := EncoderToNodeOpts{OmitEmpty: true, TagName: TagLabel, AllowSliceAsStruct: true}
node, err := EncodeToNode(element, rootName, etnOpts)

View file

@ -8,7 +8,7 @@ import (
"github.com/containous/traefik/v2/pkg/log"
)
// Status of the router/service
// Status of the router/service.
const (
StatusEnabled = "enabled"
StatusDisabled = "disabled"

View file

@ -179,7 +179,7 @@ func (s *ServiceInfo) UpdateServerStatus(server string, status string) {
}
// GetAllStatus returns all the statuses of all the servers in ServiceInfo.
// It is the responsibility of the caller to check that s is not nil
// It is the responsibility of the caller to check that s is not nil.
func (s *ServiceInfo) GetAllStatus() map[string]string {
s.serverStatusMu.RLock()
defer s.serverStatusMu.RUnlock()

View file

@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/require"
)
// all the Routers/Middlewares/Services are considered fully qualified
// all the Routers/Middlewares/Services are considered fully qualified.
func TestPopulateUsedBy(t *testing.T) {
testCases := []struct {
desc string

View file

@ -49,7 +49,7 @@ const (
DefaultAcmeCAServer = "https://acme-v02.api.letsencrypt.org/directory"
)
// Configuration is the static configuration
// Configuration is the static configuration.
type Configuration struct {
Global *Global `description:"Global configuration options" json:"global,omitempty" toml:"global,omitempty" yaml:"global,omitempty" export:"true"`
@ -81,7 +81,7 @@ type Global struct {
SendAnonymousUsage bool `description:"Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default." json:"sendAnonymousUsage,omitempty" toml:"sendAnonymousUsage,omitempty" yaml:"sendAnonymousUsage,omitempty" label:"allowEmpty" export:"true"`
}
// ServersTransport options to configure communication between Traefik and the servers
// ServersTransport options to configure communication between Traefik and the servers.
type ServersTransport struct {
InsecureSkipVerify bool `description:"Disable SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"`
RootCAs []tls.FileOrContent `description:"Add cert file for self-signed certificate." json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"`
@ -89,7 +89,7 @@ type ServersTransport struct {
ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers." json:"forwardingTimeouts,omitempty" toml:"forwardingTimeouts,omitempty" yaml:"forwardingTimeouts,omitempty" export:"true"`
}
// API holds the API configuration
// API holds the API configuration.
type API struct {
Insecure bool `description:"Activate API directly on the entryPoint named traefik." json:"insecure,omitempty" toml:"insecure,omitempty" yaml:"insecure,omitempty" export:"true"`
Dashboard bool `description:"Activate dashboard." json:"dashboard,omitempty" toml:"dashboard,omitempty" yaml:"dashboard,omitempty" export:"true"`
@ -158,7 +158,7 @@ func (t *Tracing) SetDefaults() {
t.SpanNameLimit = 0
}
// Providers contains providers configuration
// Providers contains providers configuration.
type Providers struct {
ProvidersThrottleDuration types.Duration `description:"Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time." json:"providersThrottleDuration,omitempty" toml:"providersThrottleDuration,omitempty" yaml:"providersThrottleDuration,omitempty" export:"true"`
@ -224,7 +224,7 @@ func (c *Configuration) initACMEProvider() {
legolog.Logger = stdlog.New(log.WithoutContext().WriterLevel(logrus.DebugLevel), "legolog: ", 0)
}
// ValidateConfiguration validate that configuration is coherent
// ValidateConfiguration validate that configuration is coherent.
func (c *Configuration) ValidateConfiguration() error {
var acmeEmail string
for name, resolver := range c.CertificatesResolvers {

View file

@ -25,8 +25,7 @@ const (
var singleton *HealthCheck
var once sync.Once
// Balancer is the set of operations required to manage the list of servers in a
// load-balancer.
// Balancer is the set of operations required to manage the list of servers in a load-balancer.
type Balancer interface {
Servers() []*url.URL
RemoveServer(u *url.URL) error
@ -39,8 +38,9 @@ type BalancerHandler interface {
Balancer
}
// metricsRegistry is a local interface in the health check package, exposing only the required metrics
// necessary for the health check package. This makes it easier for the tests.
// metricsRegistry is a local interface in the health check package,
// exposing only the required metrics necessary for the health check package.
// This makes it easier for the tests.
type metricsRegistry interface {
BackendServerUpGauge() metrics.Gauge
}
@ -68,7 +68,7 @@ type backendURL struct {
weight int
}
// BackendConfig HealthCheck configuration for a backend
// BackendConfig HealthCheck configuration for a backend.
type BackendConfig struct {
Options
name string
@ -92,7 +92,7 @@ func (b *BackendConfig) newRequest(serverURL *url.URL) (*http.Request, error) {
return http.NewRequest(http.MethodGet, u.String(), http.NoBody)
}
// this function adds additional http headers and hostname to http.request
// this function adds additional http headers and hostname to http.request.
func (b *BackendConfig) addHeadersAndHost(req *http.Request) *http.Request {
if b.Options.Hostname != "" {
req.Host = b.Options.Hostname
@ -104,14 +104,14 @@ func (b *BackendConfig) addHeadersAndHost(req *http.Request) *http.Request {
return req
}
// HealthCheck struct
// HealthCheck struct.
type HealthCheck struct {
Backends map[string]*BackendConfig
metrics metricsRegistry
cancel context.CancelFunc
}
// SetBackendsConfiguration set backends configuration
// SetBackendsConfiguration set backends configuration.
func (hc *HealthCheck) SetBackendsConfiguration(parentCtx context.Context, backends map[string]*BackendConfig) {
hc.Backends = backends
if hc.cancel != nil {
@ -152,28 +152,21 @@ func (hc *HealthCheck) checkBackend(ctx context.Context, backend *BackendConfig)
enabledURLs := backend.LB.Servers()
var newDisabledURLs []backendURL
// FIXME re enable metrics
for _, disabledURL := range backend.disabledURLs {
// FIXME serverUpMetricValue := float64(0)
if err := checkHealth(disabledURL.url, backend); err == nil {
logger.Warnf("Health check up: Returning to server list. Backend: %q URL: %q Weight: %d",
backend.name, disabledURL.url.String(), disabledURL.weight)
if err = backend.LB.UpsertServer(disabledURL.url, roundrobin.Weight(disabledURL.weight)); err != nil {
logger.Error(err)
}
// FIXME serverUpMetricValue = 1
} else {
logger.Warnf("Health check still failing. Backend: %q URL: %q Reason: %s", backend.name, disabledURL.url.String(), err)
newDisabledURLs = append(newDisabledURLs, disabledURL)
}
// FIXME labelValues := []string{"backend", backend.name, "url", backendurl.url.String()}
// FIXME hc.metrics.BackendServerUpGauge().With(labelValues...).Set(serverUpMetricValue)
}
backend.disabledURLs = newDisabledURLs
// FIXME re enable metrics
for _, enableURL := range enabledURLs {
// FIXME serverUpMetricValue := float64(1)
if err := checkHealth(enableURL, backend); err != nil {
weight := 1
rr, ok := backend.LB.(*roundrobin.RoundRobin)
@ -189,35 +182,25 @@ func (hc *HealthCheck) checkBackend(ctx context.Context, backend *BackendConfig)
logger.Error(err)
}
backend.disabledURLs = append(backend.disabledURLs, backendURL{enableURL, weight})
// FIXME serverUpMetricValue = 0
}
// FIXME labelValues := []string{"backend", backend.name, "url", enableURL.String()}
// FIXME hc.metrics.BackendServerUpGauge().With(labelValues...).Set(serverUpMetricValue)
}
}
// FIXME re add metrics
//func GetHealthCheck(metrics metricsRegistry) *HealthCheck {
// GetHealthCheck returns the health check which is guaranteed to be a singleton.
func GetHealthCheck() *HealthCheck {
once.Do(func() {
singleton = newHealthCheck()
//singleton = newHealthCheck(metrics)
})
return singleton
}
// FIXME re add metrics
//func newHealthCheck(metrics metricsRegistry) *HealthCheck {
func newHealthCheck() *HealthCheck {
return &HealthCheck{
Backends: make(map[string]*BackendConfig),
//metrics: metrics,
}
}
// NewBackendConfig Instantiate a new BackendConfig
// NewBackendConfig Instantiate a new BackendConfig.
func NewBackendConfig(options Options, backendName string) *BackendConfig {
return &BackendConfig{
Options: options,
@ -230,7 +213,7 @@ func NewBackendConfig(options Options, backendName string) *BackendConfig {
func checkHealth(serverURL *url.URL, backend *BackendConfig) error {
req, err := backend.newRequest(serverURL)
if err != nil {
return fmt.Errorf("failed to create HTTP request: %s", err)
return fmt.Errorf("failed to create HTTP request: %w", err)
}
req = backend.addHeadersAndHost(req)
@ -248,7 +231,7 @@ func checkHealth(serverURL *url.URL, backend *BackendConfig) error {
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("HTTP request failed: %s", err)
return fmt.Errorf("HTTP request failed: %w", err)
}
defer resp.Body.Close()
@ -260,7 +243,7 @@ func checkHealth(serverURL *url.URL, backend *BackendConfig) error {
return nil
}
// NewLBStatusUpdater returns a new LbStatusUpdater
// NewLBStatusUpdater returns a new LbStatusUpdater.
func NewLBStatusUpdater(bh BalancerHandler, info *runtime.ServiceInfo) *LbStatusUpdater {
return &LbStatusUpdater{
BalancerHandler: bh,
@ -298,7 +281,7 @@ func (lb *LbStatusUpdater) UpsertServer(u *url.URL, options ...roundrobin.Server
// Balancers is a list of Balancers(s) that implements the Balancer interface.
type Balancers []Balancer
// Servers returns the servers url from all the BalancerHandler
// Servers returns the servers url from all the BalancerHandler.
func (b Balancers) Servers() []*url.URL {
var servers []*url.URL
for _, lb := range b {

View file

@ -7,13 +7,13 @@ import (
"strings"
)
// Checker allows to check that addresses are in a trusted IPs
// Checker allows to check that addresses are in a trusted IPs.
type Checker struct {
authorizedIPs []*net.IP
authorizedIPsNet []*net.IPNet
}
// NewChecker builds a new Checker given a list of CIDR-Strings to trusted IPs
// NewChecker builds a new Checker given a list of CIDR-Strings to trusted IPs.
func NewChecker(trustedIPs []string) (*Checker, error) {
if len(trustedIPs) == 0 {
return nil, errors.New("no trusted IPs provided")
@ -27,7 +27,7 @@ func NewChecker(trustedIPs []string) (*Checker, error) {
} else {
_, ipAddr, err := net.ParseCIDR(ipMask)
if err != nil {
return nil, fmt.Errorf("parsing CIDR trusted IPs %s: %v", ipAddr, err)
return nil, fmt.Errorf("parsing CIDR trusted IPs %s: %w", ipAddr, err)
}
checker.authorizedIPsNet = append(checker.authorizedIPsNet, ipAddr)
}
@ -36,7 +36,7 @@ func NewChecker(trustedIPs []string) (*Checker, error) {
return checker, nil
}
// IsAuthorized checks if provided request is authorized by the trusted IPs
// IsAuthorized checks if provided request is authorized by the trusted IPs.
func (ip *Checker) IsAuthorized(addr string) error {
var invalidMatches []string
@ -58,7 +58,7 @@ func (ip *Checker) IsAuthorized(addr string) error {
return nil
}
// Contains checks if provided address is in the trusted IPs
// Contains checks if provided address is in the trusted IPs.
func (ip *Checker) Contains(addr string) (bool, error) {
if len(addr) == 0 {
return false, errors.New("empty IP address")
@ -66,13 +66,13 @@ func (ip *Checker) Contains(addr string) (bool, error) {
ipAddr, err := parseIP(addr)
if err != nil {
return false, fmt.Errorf("unable to parse address: %s: %s", addr, err)
return false, fmt.Errorf("unable to parse address: %s: %w", addr, err)
}
return ip.ContainsIP(ipAddr), nil
}
// ContainsIP checks if provided address is in the trusted IPs
// ContainsIP checks if provided address is in the trusted IPs.
func (ip *Checker) ContainsIP(addr net.IP) bool {
for _, authorizedIP := range ip.authorizedIPs {
if authorizedIP.Equal(addr) {

View file

@ -10,15 +10,15 @@ const (
xForwardedFor = "X-Forwarded-For"
)
// Strategy a strategy for IP selection
// Strategy a strategy for IP selection.
type Strategy interface {
GetIP(req *http.Request) string
}
// RemoteAddrStrategy a strategy that always return the remote address
// RemoteAddrStrategy a strategy that always return the remote address.
type RemoteAddrStrategy struct{}
// GetIP returns the selected IP
// GetIP returns the selected IP.
func (s *RemoteAddrStrategy) GetIP(req *http.Request) string {
ip, _, err := net.SplitHostPort(req.RemoteAddr)
if err != nil {
@ -27,12 +27,12 @@ func (s *RemoteAddrStrategy) GetIP(req *http.Request) string {
return ip
}
// DepthStrategy a strategy based on the depth inside the X-Forwarded-For from right to left
// DepthStrategy a strategy based on the depth inside the X-Forwarded-For from right to left.
type DepthStrategy struct {
Depth int
}
// GetIP return the selected IP
// GetIP return the selected IP.
func (s *DepthStrategy) GetIP(req *http.Request) string {
xff := req.Header.Get(xForwardedFor)
xffs := strings.Split(xff, ",")
@ -44,12 +44,12 @@ func (s *DepthStrategy) GetIP(req *http.Request) string {
}
// CheckerStrategy a strategy based on an IP Checker
// allows to check that addresses are in a trusted IPs
// allows to check that addresses are in a trusted IPs.
type CheckerStrategy struct {
Checker *Checker
}
// GetIP return the selected IP
// GetIP return the selected IP.
func (s *CheckerStrategy) GetIP(req *http.Request) string {
if s.Checker == nil {
return ""

View file

@ -80,7 +80,7 @@ func AddHook(hook logrus.Hook) {
}
// CustomWriterLevel logs writer for a specific level. (with a custom scanner buffer size.)
// adapted from github.com/Sirupsen/logrus/writer.go
// adapted from github.com/Sirupsen/logrus/writer.go.
func CustomWriterLevel(level logrus.Level, maxScanTokenSize int) *io.PipeWriter {
reader, writer := io.Pipe()
@ -110,7 +110,7 @@ func CustomWriterLevel(level logrus.Level, maxScanTokenSize int) *io.PipeWriter
}
// extract from github.com/Sirupsen/logrus/writer.go
// Hack the buffer size
// Hack the buffer size.
func writerScanner(reader io.ReadCloser, scanTokenSize int, printFunc func(args ...interface{})) {
scanner := bufio.NewScanner(reader)

View file

@ -1,6 +1,6 @@
package log
// Log entry name
// Log entry names.
const (
EntryPointName = "entryPointName"
RouterName = "routerName"

View file

@ -15,7 +15,7 @@ const (
loggerKey contextKey = iota
)
// Logger the Traefik logger
// Logger the Traefik logger.
type Logger interface {
logrus.FieldLogger
WriterLevel(logrus.Level) *io.PipeWriter
@ -57,14 +57,14 @@ func GetLevel() logrus.Level {
return logrus.GetLevel()
}
// Str adds a string field
// Str adds a string field.
func Str(key, value string) func(logrus.Fields) {
return func(fields logrus.Fields) {
fields[key] = value
}
}
// With Adds fields
// With Adds fields.
func With(ctx context.Context, opts ...func(logrus.Fields)) context.Context {
logger := FromContext(ctx)
@ -77,7 +77,7 @@ func With(ctx context.Context, opts ...func(logrus.Fields)) context.Context {
return context.WithValue(ctx, loggerKey, logger)
}
// FromContext Gets the logger from context
// FromContext Gets the logger from context.
func FromContext(ctx context.Context) Logger {
if ctx == nil {
panic("nil context")
@ -91,12 +91,12 @@ func FromContext(ctx context.Context) Logger {
return logger
}
// WithoutContext Gets the main logger
// WithoutContext Gets the main logger.
func WithoutContext() Logger {
return mainLogger
}
// OpenFile opens the log file using the specified path
// OpenFile opens the log file using the specified path.
func OpenFile(path string) error {
logFilePath = path
@ -110,7 +110,7 @@ func OpenFile(path string) error {
return nil
}
// CloseFile closes the log and sets the Output to stdout
// CloseFile closes the log and sets the Output to stdout.
func CloseFile() error {
logrus.SetOutput(os.Stdout)
@ -120,9 +120,8 @@ func CloseFile() error {
return nil
}
// RotateFile closes and reopens the log file to allow for rotation
// by an external source. If the log isn't backed by a file then
// it does nothing.
// RotateFile closes and reopens the log file to allow for rotation by an external source.
// If the log isn't backed by a file then it does nothing.
func RotateFile() error {
logger := FromContext(context.Background())

View file

@ -80,7 +80,7 @@ func RegisterInfluxDB(ctx context.Context, config *types.InfluxDB) Registry {
return registry
}
// initInfluxDBTicker creates a influxDBClient
// initInfluxDBTicker creates a influxDBClient.
func initInfluxDBClient(ctx context.Context, config *types.InfluxDB) *influx.Influx {
logger := log.FromContext(ctx)
@ -123,7 +123,7 @@ func initInfluxDBClient(ctx context.Context, config *types.InfluxDB) *influx.Inf
}))
}
// initInfluxDBTicker initializes metrics pusher
// initInfluxDBTicker initializes metrics pusher.
func initInfluxDBTicker(ctx context.Context, config *types.InfluxDB) *time.Ticker {
report := time.NewTicker(time.Duration(config.PushInterval))
@ -135,7 +135,7 @@ func initInfluxDBTicker(ctx context.Context, config *types.InfluxDB) *time.Ticke
return report
}
// StopInfluxDB stops internal influxDBTicker which controls the pushing of metrics to InfluxDB Agent and resets it to `nil`
// StopInfluxDB stops internal influxDBTicker which controls the pushing of metrics to InfluxDB Agent and resets it to `nil`.
func StopInfluxDB() {
if influxDBTicker != nil {
influxDBTicker.Stop()

View file

@ -71,7 +71,7 @@ func RegisterStatsd(ctx context.Context, config *types.Statsd) Registry {
return registry
}
// initStatsdTicker initializes metrics pusher and creates a statsdClient if not created already
// initStatsdTicker initializes metrics pusher and creates a statsdClient if not created already.
func initStatsdTicker(ctx context.Context, config *types.Statsd) *time.Ticker {
address := config.Address
if len(address) == 0 {
@ -87,7 +87,7 @@ func initStatsdTicker(ctx context.Context, config *types.Statsd) *time.Ticker {
return report
}
// StopStatsd stops internal statsdTicker which controls the pushing of metrics to StatsD Agent and resets it to `nil`
// StopStatsd stops internal statsdTicker which controls the pushing of metrics to StatsD Agent and resets it to `nil`.
func StopStatsd() {
if statsdTicker != nil {
statsdTicker.Stop()

View file

@ -28,7 +28,7 @@ func newCaptureResponseWriter(rw http.ResponseWriter) capturer {
}
// captureResponseWriter is a wrapper of type http.ResponseWriter
// that tracks request status and size
// that tracks request status and size.
type captureResponseWriter struct {
rw http.ResponseWriter
status int

View file

@ -7,7 +7,7 @@ import (
"github.com/vulcand/oxy/utils"
)
// FieldApply function hook to add data in accesslog
// FieldApply function hook to add data in accesslog.
type FieldApply func(rw http.ResponseWriter, r *http.Request, next http.Handler, data *LogData)
// FieldHandler sends a new field to the logger.
@ -39,7 +39,7 @@ func (f *FieldHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
}
}
// AddServiceFields add service fields
// AddServiceFields add service fields.
func AddServiceFields(rw http.ResponseWriter, req *http.Request, next http.Handler, data *LogData) {
data.Core[ServiceURL] = req.URL // note that this is *not* the original incoming URL
data.Core[ServiceAddr] = req.URL.Host
@ -47,7 +47,7 @@ func AddServiceFields(rw http.ResponseWriter, req *http.Request, next http.Handl
next.ServeHTTP(rw, req)
}
// AddOriginFields add origin fields
// AddOriginFields add origin fields.
func AddOriginFields(rw http.ResponseWriter, req *http.Request, next http.Handler, data *LogData) {
crw := newCaptureResponseWriter(rw)
start := time.Now().UTC()

View file

@ -75,7 +75,7 @@ func NewHandler(config *types.AccessLog) (*Handler, error) {
if len(config.FilePath) > 0 {
f, err := openAccessLogFile(config.FilePath)
if err != nil {
return nil, fmt.Errorf("error opening access log file: %s", err)
return nil, fmt.Errorf("error opening access log file: %w", err)
}
file = f
}
@ -132,12 +132,12 @@ func openAccessLogFile(filePath string) (*os.File, error) {
dir := filepath.Dir(filePath)
if err := os.MkdirAll(dir, 0755); err != nil {
return nil, fmt.Errorf("failed to create log path %s: %s", dir, err)
return nil, fmt.Errorf("failed to create log path %s: %w", dir, err)
}
file, err := os.OpenFile(filePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0664)
if err != nil {
return nil, fmt.Errorf("error opening file %s: %s", filePath, err)
return nil, fmt.Errorf("error opening file %s: %w", filePath, err)
}
return file, nil

View file

@ -5,7 +5,7 @@ import (
"regexp"
)
// ParseAccessLog parse line of access log and return a map with each fields
// ParseAccessLog parse line of access log and return a map with each fields.
func ParseAccessLog(data string) (map[string]string, error) {
var buffer bytes.Buffer
buffer.WriteString(`(\S+)`) // 1 - ClientHost

View file

@ -20,7 +20,7 @@ const (
wwwAuthenticate = "Www-Authenticate"
)
// DigestRequest is a client for digest authentication requests
// DigestRequest is a client for digest authentication requests.
type digestRequest struct {
client *http.Client
username, password string
@ -35,7 +35,7 @@ func (nc nonceCount) String() string {
var wanted = []string{algorithm, nonce, opaque, qop, realm}
// New makes a DigestRequest instance
// New makes a DigestRequest instance.
func newDigestRequest(username, password string, client *http.Client) *digestRequest {
return &digestRequest{
client: client,
@ -44,7 +44,7 @@ func newDigestRequest(username, password string, client *http.Client) *digestReq
}
}
// Do does requests as http.Do does
// Do does requests as http.Do does.
func (r *digestRequest) Do(req *http.Request) (*http.Response, error) {
parts, err := r.makeParts(req)
if err != nil {
@ -133,7 +133,7 @@ func (r *digestRequest) makeAuthorization(req *http.Request, parts map[string]st
)
}
// GenerateRandom generates random string
// GenerateRandom generates random string.
func generateRandom(n int) string {
b := make([]byte, 8)
_, _ = io.ReadFull(rand.Reader, b)

View file

@ -18,7 +18,7 @@ type chainBuilder interface {
BuildChain(ctx context.Context, middlewares []string) *alice.Chain
}
// New creates a chain middleware
// New creates a chain middleware.
func New(ctx context.Context, next http.Handler, config dynamic.Chain, builder chainBuilder, name string) (http.Handler, error) {
log.FromContext(middlewares.GetLoggerCtx(ctx, name, typeName)).Debug("Creating middleware")

View file

@ -39,7 +39,7 @@ func New(ctx context.Context, next http.Handler, confCircuitBreaker dynamic.Circ
}, nil
}
// NewCircuitBreakerOptions returns a new CircuitBreakerOption
// NewCircuitBreakerOptions returns a new CircuitBreakerOption.
func createCircuitBreakerOptions(expression string) cbreaker.CircuitBreakerOption {
return cbreaker.Fallback(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
tracing.SetErrorWithEvent(req, "blocked by circuit-breaker (%q)", expression)

View file

@ -131,12 +131,12 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
func newRequest(baseURL string) (*http.Request, error) {
u, err := url.Parse(baseURL)
if err != nil {
return nil, fmt.Errorf("error pages: error when parse URL: %v", err)
return nil, fmt.Errorf("error pages: error when parse URL: %w", err)
}
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
if err != nil {
return nil, fmt.Errorf("error pages: error when create query: %v", err)
return nil, fmt.Errorf("error pages: error when create query: %w", err)
}
req.RequestURI = u.RequestURI()
@ -250,7 +250,7 @@ func (cc *codeCatcher) WriteHeader(code int) {
cc.headersSent = true
}
// Hijack hijacks the connection
// Hijack hijacks the connection.
func (cc *codeCatcher) Hijack() (net.Conn, *bufio.ReadWriter, error) {
if hj, ok := cc.responseWriter.(http.Hijacker); ok {
return hj.Hijack()
@ -349,7 +349,7 @@ func (r *responseRecorderWithoutCloseNotify) WriteHeader(code int) {
r.Code = code
}
// Hijack hijacks the connection
// Hijack hijacks the connection.
func (r *responseRecorderWithoutCloseNotify) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return r.responseWriter.(http.Hijacker).Hijack()
}

View file

@ -37,9 +37,10 @@ var xHeaders = []string{
xRealIP,
}
// XForwarded is an HTTP handler wrapper that sets the X-Forwarded headers, and other relevant headers for a
// reverse-proxy. Unless insecure is set, it first removes all the existing values for those headers if the remote
// address is not one of the trusted ones.
// XForwarded is an HTTP handler wrapper that sets the X-Forwarded headers,
// and other relevant headers for a reverse-proxy.
// Unless insecure is set,
// it first removes all the existing values for those headers if the remote address is not one of the trusted ones.
type XForwarded struct {
insecure bool
trustedIps []string
@ -80,15 +81,13 @@ func (x *XForwarded) isTrustedIP(ip string) bool {
return x.ipChecker.IsAuthorized(ip) == nil
}
// removeIPv6Zone removes the zone if the given IP is an ipv6 address and it has
// {zone} information in it, like "[fe80::d806:a55d:eb1b:49cc%vEthernet (vmxnet3
// Ethernet Adapter - Virtual Switch)]:64692"
// removeIPv6Zone removes the zone if the given IP is an ipv6 address and it has {zone} information in it,
// like "[fe80::d806:a55d:eb1b:49cc%vEthernet (vmxnet3 Ethernet Adapter - Virtual Switch)]:64692".
func removeIPv6Zone(clientIP string) string {
return strings.Split(clientIP, "%")[0]
}
// isWebsocketRequest returns whether the specified HTTP request is a
// websocket handshake request
// isWebsocketRequest returns whether the specified HTTP request is a websocket handshake request.
func isWebsocketRequest(req *http.Request) bool {
containsHeader := func(name, value string) bool {
items := strings.Split(req.Header.Get(name), ",")
@ -141,7 +140,7 @@ func (x *XForwarded) rewrite(outreq *http.Request) {
}
if isWebsocketRequest(outreq) {
if outreq.Header.Get(xForwardedProto) == "https" {
if outreq.Header.Get(xForwardedProto) == "https" || outreq.Header.Get(xForwardedProto) == "wss" {
outreq.Header.Set(xForwardedProto, "wss")
} else {
outreq.Header.Set(xForwardedProto, "ws")
@ -161,7 +160,7 @@ func (x *XForwarded) rewrite(outreq *http.Request) {
}
}
// ServeHTTP implements http.Handler
// ServeHTTP implements http.Handler.
func (x *XForwarded) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !x.insecure && !x.isTrustedIP(r.RemoteAddr) {
for _, h := range xHeaders {

View file

@ -203,6 +203,17 @@ func TestServeHTTP(t *testing.T) {
xForwardedProto: "wss",
},
},
{
desc: "xForwardedProto with websocket and tls and already x-forwarded-proto with wss",
tls: true,
websocket: true,
incomingHeaders: map[string]string{
xForwardedProto: "wss",
},
expectedHeaders: map[string]string{
xForwardedProto: "wss",
},
},
{
desc: "xForwardedPort with explicit port",
host: "foo.com:8080",

View file

@ -6,12 +6,12 @@ import (
"github.com/containous/traefik/v2/pkg/safe"
)
// HTTPHandlerSwitcher allows hot switching of http.ServeMux
// HTTPHandlerSwitcher allows hot switching of http.ServeMux.
type HTTPHandlerSwitcher struct {
handler *safe.Safe
}
// NewHandlerSwitcher builds a new instance of HTTPHandlerSwitcher
// NewHandlerSwitcher builds a new instance of HTTPHandlerSwitcher.
func NewHandlerSwitcher(newHandler http.Handler) (hs *HTTPHandlerSwitcher) {
return &HTTPHandlerSwitcher{
handler: safe.New(newHandler),
@ -23,13 +23,13 @@ func (h *HTTPHandlerSwitcher) ServeHTTP(rw http.ResponseWriter, req *http.Reques
handlerBackup.ServeHTTP(rw, req)
}
// GetHandler returns the current http.ServeMux
// GetHandler returns the current http.ServeMux.
func (h *HTTPHandlerSwitcher) GetHandler() (newHandler http.Handler) {
handler := h.handler.Get().(http.Handler)
return handler
}
// UpdateHandler safely updates the current http.ServeMux with a new one
// UpdateHandler safely updates the current http.ServeMux with a new one.
func (h *HTTPHandlerSwitcher) UpdateHandler(newHandler http.Handler) {
h.handler.Set(newHandler)
}

View file

@ -38,12 +38,12 @@ func New(ctx context.Context, next http.Handler, config dynamic.InFlightReq, nam
sourceMatcher, err := middlewares.GetSourceExtractor(ctxLog, config.SourceCriterion)
if err != nil {
return nil, fmt.Errorf("error creating requests limiter: %v", err)
return nil, fmt.Errorf("error creating requests limiter: %w", err)
}
handler, err := connlimit.New(next, sourceMatcher, config.Amount)
if err != nil {
return nil, fmt.Errorf("error creating connection limit: %v", err)
return nil, fmt.Errorf("error creating connection limit: %w", err)
}
return &inFlightReq{handler: handler, name: name}, nil

View file

@ -18,7 +18,7 @@ const (
typeName = "IPWhiteLister"
)
// ipWhiteLister is a middleware that provides Checks of the Requesting IP against a set of Whitelists
// ipWhiteLister is a middleware that provides Checks of the Requesting IP against a set of Whitelists.
type ipWhiteLister struct {
next http.Handler
whiteLister *ip.Checker
@ -26,7 +26,7 @@ type ipWhiteLister struct {
name string
}
// New builds a new IPWhiteLister given a list of CIDR-Strings to whitelist
// New builds a new IPWhiteLister given a list of CIDR-Strings to whitelist.
func New(ctx context.Context, next http.Handler, config dynamic.IPWhiteList, name string) (http.Handler, error) {
logger := log.FromContext(middlewares.GetLoggerCtx(ctx, name, typeName))
logger.Debug("Creating middleware")
@ -37,7 +37,7 @@ func New(ctx context.Context, next http.Handler, config dynamic.IPWhiteList, nam
checker, err := ip.NewChecker(config.SourceRange)
if err != nil {
return nil, fmt.Errorf("cannot parse CIDR whitelist %s: %v", config.SourceRange, err)
return nil, fmt.Errorf("cannot parse CIDR whitelist %s: %w", config.SourceRange, err)
}
strategy, err := config.IPStrategy.Get()

View file

@ -50,7 +50,7 @@ func (r *responseRecorder) WriteHeader(status int) {
r.statusCode = status
}
// Hijack hijacks the connection
// Hijack hijacks the connection.
func (r *responseRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return r.ResponseWriter.(http.Hijacker).Hijack()
}

View file

@ -139,7 +139,7 @@ func (p *passTLSClientCert) ServeHTTP(rw http.ResponseWriter, req *http.Request)
// - the `,` is used to separate certificates
// - the `;` is used to separate root fields
// - the value of root fields is always wrapped by double quote
// - if a field is empty, the field is ignored
// - if a field is empty, the field is ignored.
func (p *passTLSClientCert) getCertInfo(ctx context.Context, certs []*x509.Certificate) string {
var headerValues []string

View file

@ -14,12 +14,12 @@ const (
typeName = "Pipelining"
)
// pipelining returns a middleware
// pipelining returns a middleware.
type pipelining struct {
next http.Handler
}
// New returns a new pipelining instance
// New returns a new pipelining instance.
func New(ctx context.Context, next http.Handler, name string) http.Handler {
log.FromContext(middlewares.GetLoggerCtx(ctx, name, typeName)).Debug("Creating middleware")
@ -37,7 +37,7 @@ func (p *pipelining) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
}
}
// writerWithoutCloseNotify helps to disable closeNotify
// writerWithoutCloseNotify helps to disable closeNotify.
type writerWithoutCloseNotify struct {
W http.ResponseWriter
}
@ -52,8 +52,7 @@ func (w *writerWithoutCloseNotify) Write(buf []byte) (int, error) {
return w.W.Write(buf)
}
// WriteHeader sends an HTTP response header with the provided
// status code.
// WriteHeader sends an HTTP response header with the provided status code.
func (w *writerWithoutCloseNotify) WriteHeader(code int) {
w.W.WriteHeader(code)
}

View file

@ -34,7 +34,7 @@ func New(ctx context.Context, next http.Handler, config dynamic.ReplacePathRegex
exp, err := regexp.Compile(strings.TrimSpace(config.Regex))
if err != nil {
return nil, fmt.Errorf("error compiling regular expression %s: %s", config.Regex, err)
return nil, fmt.Errorf("error compiling regular expression %s: %w", config.Regex, err)
}
return &replacePathRegex{

View file

@ -105,7 +105,7 @@ func cnameResolve(ctx context.Context, host string, resolvPath string) (*cnameRe
func getRecord(client *dns.Client, msg *dns.Msg, server string, port string) (*cnameResolv, error) {
resp, _, err := client.Exchange(msg, net.JoinHostPort(server, port))
if err != nil {
return nil, fmt.Errorf("exchange error for server %s: %v", server, err)
return nil, fmt.Errorf("exchange error for server %s: %w", server, err)
}
if resp == nil || len(resp.Answer) == 0 {

View file

@ -3,7 +3,7 @@ package middlewares
import "net/http"
// Stateful interface groups all http interfaces that must be
// implemented by a stateful middleware (ie: recorders)
// implemented by a stateful middleware (ie: recorders).
type Stateful interface {
http.ResponseWriter
http.Hijacker

View file

@ -27,12 +27,12 @@ func (n MockTracer) Extract(format interface{}, carrier interface{}) (opentracin
return nil, opentracing.ErrSpanContextNotFound
}
// MockSpanContext
// MockSpanContext.
type MockSpanContext struct{}
func (n MockSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {}
// MockSpan
// MockSpan.
type MockSpan struct {
OpName string
Tags map[string]interface{}

View file

@ -22,12 +22,12 @@ func (s *statusCodeWithoutCloseNotify) WriteHeader(status int) {
s.ResponseWriter.WriteHeader(status)
}
// Status get response status
// Status get response status.
func (s *statusCodeWithoutCloseNotify) Status() int {
return s.status
}
// Hijack hijacks the connection
// Hijack hijacks the connection.
func (s *statusCodeWithoutCloseNotify) Hijack() (net.Conn, *bufio.ReadWriter, error) {
return s.ResponseWriter.(http.Hijacker).Hijack()
}

View file

@ -35,7 +35,7 @@ func Wrap(ctx context.Context, constructor alice.Constructor) alice.Constructor
}
}
// NewWrapper returns a http.Handler struct
// NewWrapper returns a http.Handler struct.
func NewWrapper(next http.Handler, name string, spanKind ext.SpanKindEnum) http.Handler {
return &Wrapper{
next: next,

View file

@ -12,7 +12,7 @@ import (
"github.com/go-acme/lego/v3/registration"
)
// Account is used to store lets encrypt registration info
// Account is used to store lets encrypt registration info.
type Account struct {
Email string
Registration *registration.Resource
@ -21,11 +21,11 @@ type Account struct {
}
const (
// RegistrationURLPathV1Regexp is a regexp which match ACME registration URL in the V1 format
// RegistrationURLPathV1Regexp is a regexp which match ACME registration URL in the V1 format.
RegistrationURLPathV1Regexp = `^.*/acme/reg/\d+$`
)
// NewAccount creates an account
// NewAccount creates an account.
func NewAccount(ctx context.Context, email string, keyTypeValue string) (*Account, error) {
keyType := GetKeyType(ctx, keyTypeValue)
@ -42,17 +42,17 @@ func NewAccount(ctx context.Context, email string, keyTypeValue string) (*Accoun
}, nil
}
// GetEmail returns email
// GetEmail returns email.
func (a *Account) GetEmail() string {
return a.Email
}
// GetRegistration returns lets encrypt registration resource
// GetRegistration returns lets encrypt registration resource.
func (a *Account) GetRegistration() *registration.Resource {
return a.Registration
}
// GetPrivateKey returns private key
// GetPrivateKey returns private key.
func (a *Account) GetPrivateKey() crypto.PrivateKey {
privateKey, err := x509.ParsePKCS1PrivateKey(a.PrivateKey)
if err != nil {
@ -64,7 +64,7 @@ func (a *Account) GetPrivateKey() crypto.PrivateKey {
return privateKey
}
// GetKeyType used to determine which algo to used
// GetKeyType used to determine which algo to used.
func GetKeyType(ctx context.Context, value string) certcrypto.KeyType {
logger := log.FromContext(ctx)

View file

@ -13,7 +13,7 @@ import (
var _ Store = (*LocalStore)(nil)
// LocalStore Stores implementation for local file
// LocalStore Stores implementation for local file.
type LocalStore struct {
saveDataChan chan map[string]*StoredData
filename string
@ -22,7 +22,7 @@ type LocalStore struct {
storedData map[string]*StoredData
}
// NewLocalStore initializes a new LocalStore with a file name
// NewLocalStore initializes a new LocalStore with a file name.
func NewLocalStore(filename string) *LocalStore {
store := &LocalStore{filename: filename, saveDataChan: make(chan map[string]*StoredData)}
store.listenSaveAction()
@ -93,7 +93,7 @@ func (s *LocalStore) get(resolverName string) (*StoredData, error) {
return s.storedData[resolverName], nil
}
// listenSaveAction listens to a chan to store ACME data in json format into LocalStore.filename
// listenSaveAction listens to a chan to store ACME data in json format into `LocalStore.filename`.
func (s *LocalStore) listenSaveAction() {
safe.Go(func() {
logger := log.WithoutContext().WithField(log.ProviderName, "acme")
@ -111,7 +111,7 @@ func (s *LocalStore) listenSaveAction() {
})
}
// GetAccount returns ACME Account
// GetAccount returns ACME Account.
func (s *LocalStore) GetAccount(resolverName string) (*Account, error) {
storedData, err := s.get(resolverName)
if err != nil {
@ -121,7 +121,7 @@ func (s *LocalStore) GetAccount(resolverName string) (*Account, error) {
return storedData.Account, nil
}
// SaveAccount stores ACME Account
// SaveAccount stores ACME Account.
func (s *LocalStore) SaveAccount(resolverName string, account *Account) error {
storedData, err := s.get(resolverName)
if err != nil {
@ -134,7 +134,7 @@ func (s *LocalStore) SaveAccount(resolverName string, account *Account) error {
return nil
}
// GetCertificates returns ACME Certificates list
// GetCertificates returns ACME Certificates list.
func (s *LocalStore) GetCertificates(resolverName string) ([]*CertAndStore, error) {
storedData, err := s.get(resolverName)
if err != nil {
@ -144,7 +144,7 @@ func (s *LocalStore) GetCertificates(resolverName string) ([]*CertAndStore, erro
return storedData.Certificates, nil
}
// SaveCertificates stores ACME Certificates list
// SaveCertificates stores ACME Certificates list.
func (s *LocalStore) SaveCertificates(resolverName string, certificates []*CertAndStore) error {
storedData, err := s.get(resolverName)
if err != nil {
@ -173,7 +173,7 @@ func NewLocalChallengeStore() *LocalChallengeStore {
}
}
// GetHTTPChallengeToken Get the http challenge token from the store
// GetHTTPChallengeToken Get the http challenge token from the store.
func (s *LocalChallengeStore) GetHTTPChallengeToken(token, domain string) ([]byte, error) {
s.lock.RLock()
defer s.lock.RUnlock()
@ -193,7 +193,7 @@ func (s *LocalChallengeStore) GetHTTPChallengeToken(token, domain string) ([]byt
return result, nil
}
// SetHTTPChallengeToken Set the http challenge token in the store
// SetHTTPChallengeToken Set the http challenge token in the store.
func (s *LocalChallengeStore) SetHTTPChallengeToken(token, domain string, keyAuth []byte) error {
s.lock.Lock()
defer s.lock.Unlock()
@ -210,7 +210,7 @@ func (s *LocalChallengeStore) SetHTTPChallengeToken(token, domain string, keyAut
return nil
}
// RemoveHTTPChallengeToken Remove the http challenge token in the store
// RemoveHTTPChallengeToken Remove the http challenge token in the store.
func (s *LocalChallengeStore) RemoveHTTPChallengeToken(token, domain string) error {
s.lock.Lock()
defer s.lock.Unlock()
@ -228,7 +228,7 @@ func (s *LocalChallengeStore) RemoveHTTPChallengeToken(token, domain string) err
return nil
}
// AddTLSChallenge Add a certificate to the ACME TLS-ALPN-01 certificates storage
// AddTLSChallenge Add a certificate to the ACME TLS-ALPN-01 certificates storage.
func (s *LocalChallengeStore) AddTLSChallenge(domain string, cert *Certificate) error {
s.lock.Lock()
defer s.lock.Unlock()
@ -241,7 +241,7 @@ func (s *LocalChallengeStore) AddTLSChallenge(domain string, cert *Certificate)
return nil
}
// GetTLSChallenge Get a certificate from the ACME TLS-ALPN-01 certificates storage
// GetTLSChallenge Get a certificate from the ACME TLS-ALPN-01 certificates storage.
func (s *LocalChallengeStore) GetTLSChallenge(domain string) (*Certificate, error) {
s.lock.Lock()
defer s.lock.Unlock()
@ -253,7 +253,7 @@ func (s *LocalChallengeStore) GetTLSChallenge(domain string) (*Certificate, erro
return s.storedData.TLSChallenges[domain], nil
}
// RemoveTLSChallenge Remove a certificate from the ACME TLS-ALPN-01 certificates storage
// RemoveTLSChallenge Remove a certificate from the ACME TLS-ALPN-01 certificates storage.
func (s *LocalChallengeStore) RemoveTLSChallenge(domain string) error {
s.lock.Lock()
defer s.lock.Unlock()

View file

@ -7,7 +7,7 @@ import (
"os"
)
// CheckFile checks file permissions and content size
// CheckFile checks file permissions and content size.
func CheckFile(name string) (bool, error) {
f, err := os.Open(name)
if err != nil {

View file

@ -28,11 +28,11 @@ import (
)
var (
// oscpMustStaple enables OSCP stapling as from https://github.com/go-acme/lego/issues/270
// oscpMustStaple enables OSCP stapling as from https://github.com/go-acme/lego/issues/270.
oscpMustStaple = false
)
// Configuration holds ACME configuration provided by users
// Configuration holds ACME configuration provided by users.
type Configuration struct {
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"`
@ -56,14 +56,14 @@ type CertAndStore struct {
Store string
}
// Certificate is a struct which contains all data needed from an ACME certificate
// Certificate is a struct which contains all data needed from an ACME certificate.
type Certificate struct {
Domain types.Domain `json:"domain,omitempty" toml:"domain,omitempty" yaml:"domain,omitempty"`
Certificate []byte `json:"certificate,omitempty" toml:"certificate,omitempty" yaml:"certificate,omitempty"`
Key []byte `json:"key,omitempty" toml:"key,omitempty" yaml:"key,omitempty"`
}
// DNSChallenge contains DNS challenge Configuration
// DNSChallenge contains DNS challenge Configuration.
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"`
DelayBeforeCheck types.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"`
@ -71,12 +71,12 @@ type DNSChallenge struct {
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"`
}
// HTTPChallenge contains HTTP challenge Configuration
// HTTPChallenge contains HTTP challenge Configuration.
type HTTPChallenge struct {
EntryPoint string `description:"HTTP challenge EntryPoint" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty"`
}
// TLSChallenge contains TLS challenge Configuration
// TLSChallenge contains TLS challenge Configuration.
type TLSChallenge struct{}
// Provider holds configurations of the provider.
@ -98,22 +98,22 @@ type Provider struct {
resolvingDomainsMutex sync.RWMutex
}
// SetTLSManager sets the tls manager to use
// SetTLSManager sets the tls manager to use.
func (p *Provider) SetTLSManager(tlsManager *traefiktls.Manager) {
p.tlsManager = tlsManager
}
// SetConfigListenerChan initializes the configFromListenerChan
// SetConfigListenerChan initializes the configFromListenerChan.
func (p *Provider) SetConfigListenerChan(configFromListenerChan chan dynamic.Configuration) {
p.configFromListenerChan = configFromListenerChan
}
// ListenConfiguration sets a new Configuration into the configFromListenerChan
// ListenConfiguration sets a new Configuration into the configFromListenerChan.
func (p *Provider) ListenConfiguration(config dynamic.Configuration) {
p.configFromListenerChan <- config
}
// Init for compatibility reason the BaseProvider implements an empty Init
// Init for compatibility reason the BaseProvider implements an empty Init.
func (p *Provider) Init() error {
ctx := log.With(context.Background(), log.Str(log.ProviderName, p.ResolverName+".acme"))
logger := log.FromContext(ctx)
@ -125,7 +125,7 @@ func (p *Provider) Init() error {
var err error
p.account, err = p.Store.GetAccount(p.ResolverName)
if err != nil {
return fmt.Errorf("unable to get ACME account: %v", err)
return fmt.Errorf("unable to get ACME account: %w", err)
}
// Reset Account if caServer changed, thus registration URI can be updated
@ -136,7 +136,7 @@ func (p *Provider) Init() error {
p.certificates, err = p.Store.GetCertificates(p.ResolverName)
if err != nil {
return fmt.Errorf("unable to get ACME certificates : %v", err)
return fmt.Errorf("unable to get ACME certificates : %w", err)
}
// Init the currently resolved domain map
@ -442,7 +442,7 @@ func (p *Provider) resolveCertificate(ctx context.Context, domain types.Domain,
client, err := p.getClient()
if err != nil {
return nil, fmt.Errorf("cannot get ACME client %v", err)
return nil, fmt.Errorf("cannot get ACME client %w", err)
}
request := certificate.ObtainRequest{
@ -453,7 +453,7 @@ func (p *Provider) resolveCertificate(ctx context.Context, domain types.Domain,
cert, err := client.Certificate.Obtain(request)
if err != nil {
return nil, fmt.Errorf("unable to generate a certificate for the domains %v: %v", uncheckedDomains, err)
return nil, fmt.Errorf("unable to generate a certificate for the domains %v: %w", uncheckedDomains, err)
}
if cert == nil {
return nil, fmt.Errorf("domains %v do not generate a certificate", uncheckedDomains)
@ -498,7 +498,7 @@ func (p *Provider) addCertificateForDomain(domain types.Domain, certificate []by
// deleteUnnecessaryDomains deletes from the configuration :
// - Duplicated domains
// - Domains which are checked by wildcard domain
// - Domains which are checked by wildcard domain.
func deleteUnnecessaryDomains(ctx context.Context, domains []types.Domain) []types.Domain {
var newDomains []types.Domain
@ -657,7 +657,7 @@ func (p *Provider) renewCertificates(ctx context.Context) {
}
// Get provided certificate which check a domains list (Main and SANs)
// from static and dynamic provided certificates
// from static and dynamic provided certificates.
func (p *Provider) getUncheckedDomains(ctx context.Context, domainsToCheck []string, tlsStore string) []string {
p.resolvingDomainsMutex.RLock()
defer p.resolvingDomainsMutex.RUnlock()
@ -716,7 +716,7 @@ func getX509Certificate(ctx context.Context, cert *Certificate) (*x509.Certifica
return crt, err
}
// getValidDomains checks if given domain is allowed to generate a ACME certificate and return it
// getValidDomains checks if given domain is allowed to generate a ACME certificate and return it.
func (p *Provider) getValidDomains(ctx context.Context, domain types.Domain) ([]string, error) {
domains := domain.ToStrArray()
if len(domains) == 0 {

View file

@ -94,12 +94,12 @@ func (p *ProviderAggregator) AddProvider(provider provider.Provider) error {
return nil
}
// Init the provider
// Init the provider.
func (p ProviderAggregator) Init() error {
return nil
}
// Provide calls the provide method of every providers
// Provide calls the provide method of every providers.
func (p ProviderAggregator) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error {
if p.fileProvider != nil {
launchProvider(configurationChan, pool, p.fileProvider)

View file

@ -18,7 +18,7 @@ type constraintLabelFunc func(map[string]string) bool
// The expression must match any logical boolean combination of:
// - `Label(labelName, labelValue)`
// - `LabelRegex(labelName, regexValue)`
// - `MarathonConstraint(field:operator:value)`
// - `MarathonConstraint(field:operator:value)`.
func MatchLabels(labels map[string]string, expr string) (bool, error) {
if expr == "" {
return true, nil

View file

@ -12,7 +12,7 @@ type constraintTagFunc func([]string) bool
// MatchTags reports whether the expression matches with the given tags.
// The expression must match any logical boolean combination of:
// - `Tag(tagValue)`
// - `TagRegex(regexValue)`
// - `TagRegex(regexValue)`.
func MatchTags(tags []string, expr string) (bool, error) {
if expr == "" {
return true, nil

View file

@ -89,7 +89,7 @@ func (p *Provider) SetDefaults() {
func (p *Provider) Init() error {
defaultRuleTpl, err := provider.MakeDefaultRuleTemplate(p.DefaultRule, nil)
if err != nil {
return fmt.Errorf("error while parsing default rule: %v", err)
return fmt.Errorf("error while parsing default rule: %w", err)
}
p.defaultRuleTpl = defaultRuleTpl
@ -107,7 +107,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
p.client, err = createClient(p.Endpoint)
if err != nil {
return fmt.Errorf("error create consul client, %v", err)
return fmt.Errorf("error create consul client, %w", err)
}
ticker := time.NewTicker(time.Duration(p.RefreshInterval))

Some files were not shown because too many files have changed in this diff Show more