diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index a5331e0c3..ff440d3a1 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,3 +1,7 @@ + + +### Do you want to request a *feature* or report a *bug*? + - -### Do you want to request a *feature* or report a *bug*? - - - -### Did you try using a 1.7.x configuration for the version 2.0? - -- [ ] Yes -- [ ] No +Bug @@ -30,7 +25,7 @@ If you just checked the "Yes" box, be aware that this is probably not a bug. The ``` @@ -70,12 +64,13 @@ For the alpine Traefik Docker image: ```toml # (paste your configuration here) ``` + -### If applicable, please paste the log output at DEBUG level (`--log.level=DEBUG` switch) +### If applicable, please paste the log output in DEBUG level (`--log.level=DEBUG` switch) ``` (paste your output here) diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index b782a8a35..973a474cb 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -3,6 +3,9 @@ name: Bug report about: Create a report to help us improve --- + + +### Do you want to request a *feature* or report a *bug*? - -### Do you want to request a *feature* or report a *bug*? - Bug -### Did you try using a 1.7.x configuration for the version 2.0? - -- [ ] Yes -- [ ] No - @@ -56,13 +52,12 @@ HOW TO WRITE A GOOD BUG REPORT? ### Output of `traefik version`: (_What version of Traefik are you using?_) ``` diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md index f071f0931..2495c9aec 100644 --- a/.github/ISSUE_TEMPLATE/Feature_request.md +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -3,6 +3,9 @@ name: Feature request about: Suggest an idea for this project --- + + +### Do you want to request a *feature* or report a *bug*? - -### Do you want to request a *feature* or report a *bug*? - Feature ### What did you expect to see? diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index a28934ae2..94f89bedd 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,18 +1,19 @@ diff --git a/.golangci.toml b/.golangci.toml index 995580a8b..006728e82 100644 --- a/.golangci.toml +++ b/.golangci.toml @@ -1,6 +1,9 @@ [run] - deadline = "10m" + timeout = "10m" skip-files = [] + skip-dirs = [ + "pkg/provider/kubernetes/crd/generated/", + ] [linters-settings] @@ -40,7 +43,11 @@ "scopelint", "gochecknoinits", "gochecknoglobals", + "godox", + "gocognit", "bodyclose", # Too many false-positive and panics. + "wsl", # Too strict + "stylecheck", # skip because report issues related to some generated files. ] [issues] diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ba317c6d..dfc989d2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,75 @@ +## [v2.0.2](https://github.com/containous/traefik/tree/v2.0.2) (2019-10-09) +[All Commits](https://github.com/containous/traefik/compare/v2.0.1...v2.0.2) + +**Bug fixes:** +- **[acme]** fix: ovh client int overflow. ([#5607](https://github.com/containous/traefik/pull/5607) by [ldez](https://github.com/ldez)) +- **[api,k8s,k8s/ingress]** fix: default router name for k8s ingress. ([#5612](https://github.com/containous/traefik/pull/5612) by [ldez](https://github.com/ldez)) +- **[file]** fix: default passHostHeader for file provider. ([#5516](https://github.com/containous/traefik/pull/5516) by [ldez](https://github.com/ldez)) +- **[k8s,k8s/crd]** Fix typo in log ([#5590](https://github.com/containous/traefik/pull/5590) by [XciD](https://github.com/XciD)) +- **[middleware,metrics]** fix: panic with metrics recorder. ([#5536](https://github.com/containous/traefik/pull/5536) by [ldez](https://github.com/ldez)) +- **[webui]** Add a service sticky details vue component ([#5579](https://github.com/containous/traefik/pull/5579) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- fix: return an error instead of panic. ([#5549](https://github.com/containous/traefik/pull/5549) by [ldez](https://github.com/ldez)) + +**Documentation:** +- **[acme,file]** Fix yaml domains example ([#5569](https://github.com/containous/traefik/pull/5569) by [SuperSandro2000](https://github.com/SuperSandro2000)) +- **[api,webui]** Clarifies how to configure and access the dashboard in the api & dashboard documentations ([#5523](https://github.com/containous/traefik/pull/5523) by [dduportal](https://github.com/dduportal)) +- **[api]** Add overview to API documentation ([#5539](https://github.com/containous/traefik/pull/5539) by [lnxbil](https://github.com/lnxbil)) +- **[cli]** typo in cli command ([#5586](https://github.com/containous/traefik/pull/5586) by [basraven](https://github.com/basraven)) +- **[cli]** Replace ambiguous cli help message wording ([#5233](https://github.com/containous/traefik/pull/5233) by [jansauer](https://github.com/jansauer)) +- **[docker]** Fixed typo in routing/providers/docker documentation ([#5520](https://github.com/containous/traefik/pull/5520) by [lyrixx](https://github.com/lyrixx)) +- **[docker]** $ needs escaping in docker-compose.yml ([#5528](https://github.com/containous/traefik/pull/5528) by [lnxbil](https://github.com/lnxbil)) +- **[file]** State clearly, that they are mutual exclusive ([#5527](https://github.com/containous/traefik/pull/5527) by [lnxbil](https://github.com/lnxbil)) +- **[healthcheck]** fix: typo in healthCheck examples ([#5575](https://github.com/containous/traefik/pull/5575) by [serpi90](https://github.com/serpi90)) +- **[k8s/crd]** Update 04-ingressroutes.yml ([#5585](https://github.com/containous/traefik/pull/5585) by [basraven](https://github.com/basraven)) +- **[k8s/crd]** Update apiVersion in documentation descriptor ([#5605](https://github.com/containous/traefik/pull/5605) by [pyaillet](https://github.com/pyaillet)) +- **[metrics]** doc: fix influxDB and statsD case in configuration page. ([#5531](https://github.com/containous/traefik/pull/5531) by [ldez](https://github.com/ldez)) +- **[middleware]** Update scope of services and middlewares ([#5584](https://github.com/containous/traefik/pull/5584) by [Thoorium](https://github.com/Thoorium)) +- **[middleware]** Typo in documentation ([#5558](https://github.com/containous/traefik/pull/5558) by [Constans](https://github.com/Constans)) +- **[middleware]** Fix misleading text ([#5540](https://github.com/containous/traefik/pull/5540) by [joassouza](https://github.com/joassouza)) +- **[tls]** document serversTransport ([#5529](https://github.com/containous/traefik/pull/5529) by [mpl](https://github.com/mpl)) +- **[tls]** TLS_RSA_WITH_AES_256_GCM_SHA384 is considered weak ([#5578](https://github.com/containous/traefik/pull/5578) by [Constans](https://github.com/Constans)) +- **[tls]** Improve ciphersuite examples ([#5594](https://github.com/containous/traefik/pull/5594) by [Constans](https://github.com/Constans)) +- Remove deprecated videos ([#5570](https://github.com/containous/traefik/pull/5570) by [emilevauge](https://github.com/emilevauge)) +- fix: remove extra backtick from routers docs ([#5572](https://github.com/containous/traefik/pull/5572) by [serpi90](https://github.com/serpi90)) +- document providersThrottleDuration ([#5519](https://github.com/containous/traefik/pull/5519) by [mpl](https://github.com/mpl)) +- Add a response forwarding section to the service documentation ([#5517](https://github.com/containous/traefik/pull/5517) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Change instances of "dymanic" to "dynamic" ([#5504](https://github.com/containous/traefik/pull/5504) by [dat-gitto-kid](https://github.com/dat-gitto-kid)) +- Add the pass host header section to the services documentation ([#5500](https://github.com/containous/traefik/pull/5500) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- fix misspelling on documentation landing page ([#5613](https://github.com/containous/traefik/pull/5613) by [cthompson527](https://github.com/cthompson527)) + +## [v2.0.1](https://github.com/containous/traefik/tree/v2.0.1) (2019-09-26) +[All Commits](https://github.com/containous/traefik/compare/v2.0.0...v2.0.1) + +**Bug fixes:** +- **[go,security]** This version is compiled with [Go 1.13.1](https://groups.google.com/d/msg/golang-announce/cszieYyuL9Q/g4Z7pKaqAgAJ), which fixes a vulnerability in previous versions. See the [CVE](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-16276) about it for more details. +- **[api,healthcheck]** Return an actual server status updater ([#5407](https://github.com/containous/traefik/pull/5407) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[cli]** Flag names don't need a consistent case. ([#5438](https://github.com/containous/traefik/pull/5438) by [ldez](https://github.com/ldez)) +- **[docker]** fix: docker service name. ([#5491](https://github.com/containous/traefik/pull/5491) by [ldez](https://github.com/ldez)) +- **[logs,middleware]** fix: improve log for invalid middleware. ([#5486](https://github.com/containous/traefik/pull/5486) by [ldez](https://github.com/ldez)) +- **[middleware]** Update Casing on STS Header Directive ([#5492](https://github.com/containous/traefik/pull/5492) by [dtomcej](https://github.com/dtomcej)) +- **[server]** Do not initialize list of middlewares if not needed ([#5485](https://github.com/containous/traefik/pull/5485) by [mpl](https://github.com/mpl)) +- **[websocket]** Fix case-sensitive header in websocket ([#5397](https://github.com/containous/traefik/pull/5397) by [juliens](https://github.com/juliens)) + +**Documentation:** +- **[acme,tls]** Improve TLS documentation. ([#5448](https://github.com/containous/traefik/pull/5448) by [ldez](https://github.com/ldez)) +- **[acme]** fix typo for kubectl version ([#5409](https://github.com/containous/traefik/pull/5409) by [mpl](https://github.com/mpl)) +- **[acme]** Wrong acme example. ([#5439](https://github.com/containous/traefik/pull/5439) by [ldez](https://github.com/ldez)) +- **[cli,docker]** doc: Flags and labels are case insensitive. ([#5428](https://github.com/containous/traefik/pull/5428) by [ldez](https://github.com/ldez)) +- **[docker,marathon,rancher]** clarify automatic service creation/assignment with labels ([#5493](https://github.com/containous/traefik/pull/5493) by [mpl](https://github.com/mpl)) +- **[file]** fix doc about file.filename ([#5494](https://github.com/containous/traefik/pull/5494) by [ldez](https://github.com/ldez)) +- **[k8s]** add indent to fix notes ([#5467](https://github.com/containous/traefik/pull/5467) by [mpl](https://github.com/mpl)) +- **[middleware,docker,marathon,tls]** Improve documentation for the TLS section of the provider connection. ([#5437](https://github.com/containous/traefik/pull/5437) by [ldez](https://github.com/ldez)) +- **[yaml]** YAML I love you ([#5461](https://github.com/containous/traefik/pull/5461) by [mmatur](https://github.com/mmatur)) +- Improve routing documentation ([#5450](https://github.com/containous/traefik/pull/5450) by [ldez](https://github.com/ldez)) +- fix: typo in TOML for HTTP to HTTPS redirection ([#5452](https://github.com/containous/traefik/pull/5452) by [krerkkiat](https://github.com/krerkkiat)) +- document that /dashboard should be preferred over / ([#5431](https://github.com/containous/traefik/pull/5431) by [mpl](https://github.com/mpl)) +- Improve the migration guide ([#5430](https://github.com/containous/traefik/pull/5430) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- fixed doc typoes ([#5425](https://github.com/containous/traefik/pull/5425) by [mpl](https://github.com/mpl)) +- fix indentation for tab on migration guide ([#5423](https://github.com/containous/traefik/pull/5423) by [ViceIce](https://github.com/ViceIce)) +- Update links in readme. ([#5411](https://github.com/containous/traefik/pull/5411) by [ldez](https://github.com/ldez)) +- Add the router priority documentation ([#5481](https://github.com/containous/traefik/pull/5481) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- Improve the Migration Guide ([#5391](https://github.com/containous/traefik/pull/5391) by [jbdoumenjou](https://github.com/jbdoumenjou)) + ## [v2.0.0](https://github.com/containous/traefik/tree/v2.0.0) (2019-09-16) [All Commits](https://github.com/containous/traefik/compare/v2.0.0-alpha1...v2.0.0) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6279fa377..e774b3e04 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,4 @@ # Contributing -See . +- https://docs.traefik.io/contributing/submitting-pull-requests/ +- https://docs.traefik.io/contributing/submitting-issues/ diff --git a/README.md b/README.md index 40049965a..ac1ad3fbb 100644 --- a/README.md +++ b/README.md @@ -121,17 +121,7 @@ git clone https://github.com/containous/traefik ## Introductory Videos -:warning: Please be aware that these videos are for v1.X. The old configurations for Traefik v1.X are NOT compatible with Traefik v2. If you're running v2, please ensure you are using a [v2 configuration](https://docs.traefik.io/). - -Here is a talk given by [Emile Vauge](https://github.com/emilevauge) at GopherCon 2017. -You will learn Traefik basics in less than 10 minutes. - -[![Traefik GopherCon 2017](https://img.youtube.com/vi/RgudiksfL-k/0.jpg)](https://www.youtube.com/watch?v=RgudiksfL-k) - -Here is a talk given by [Ed Robinson](https://github.com/errm) at [ContainerCamp UK](https://container.camp) conference. -You will learn fundamental Traefik features and see some demos with Kubernetes. - -[![Traefik ContainerCamp UK](https://img.youtube.com/vi/aFtpIShV60I/0.jpg)](https://www.youtube.com/watch?v=aFtpIShV60I) +You can find high level and deep dive videos on [videos.containo.us](https://videos.containo.us) ## Maintainers diff --git a/build.Dockerfile b/build.Dockerfile index 542617644..a37091948 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -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.18.0 +RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.20.0 # Download golangci-lint and misspell binary to bin folder in $GOPATH RUN GO111MODULE=off go get github.com/client9/misspell/cmd/misspell diff --git a/cmd/healthcheck/healthcheck.go b/cmd/healthcheck/healthcheck.go index 829e473aa..bf1c2762f 100644 --- a/cmd/healthcheck/healthcheck.go +++ b/cmd/healthcheck/healthcheck.go @@ -15,7 +15,7 @@ import ( func NewCmd(traefikConfiguration *static.Configuration, loaders []cli.ResourceLoader) *cli.Command { return &cli.Command{ Name: "healthcheck", - Description: `Calls Traefik /ping to check the health of Traefik (the API must be enabled).`, + Description: `Calls Traefik /ping endpoint (disabled by default) to check the health of Traefik.`, Configuration: traefikConfiguration, Run: runCmd(traefikConfiguration), Resources: loaders, diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index d0d55e55d..b551e0926 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -119,7 +119,6 @@ func runCmd(staticConfiguration *static.Configuration) error { return fmt.Errorf("error while building entryPoint %s: %v", entryPointName, err) } serverEntryPointsTCP[entryPointName].RouteAppenderFactory = router.NewRouteAppenderFactory(*staticConfiguration, entryPointName, acmeProviders) - } svr := server.NewServer(*staticConfiguration, providerAggregator, serverEntryPointsTCP, tlsManager) diff --git a/docs/content/https/acme.md b/docs/content/https/acme.md index ce690d748..1e3e35680 100644 --- a/docs/content/https/acme.md +++ b/docs/content/https/acme.md @@ -219,7 +219,7 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used | [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) | | [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) | | [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) | -| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` - The `Global API Key` needs to be used, not the `Origin CA Key` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) | +| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` [^5] | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) | | [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) | | [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/digitalocean) | @@ -247,6 +247,7 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used | [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) | | [Linode](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) | | manual | - | none, but you need to run Traefik interactively [^4], turn on debug log to see instructions and press Enter. | | | [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) | | [Namecheap](https://www.namecheap.com) | `namecheap` | `NAMECHEAP_API_USER`, `NAMECHEAP_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/namecheap) | @@ -277,6 +278,7 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used [^2]: [providing_credentials_to_your_application](https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application) [^3]: [google/default.go](https://github.com/golang/oauth2/blob/36a7019397c4c86cf59eeab3bc0d188bac444277/google/default.go#L61-L76) [^4]: `docker stack` remark: there is no way to support terminal attached to container when deploying with `docker stack`, so you might need to run container with `docker run -it` to generate certificates using `manual` provider. +[^5]: The `Global API Key` needs to be used, not the `Origin CA Key`. !!! info "`delayBeforeCheck`" By default, the `provider` verifies the TXT record _before_ letting ACME verify. diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md index 5ea0859e0..7a53cce1e 100644 --- a/docs/content/https/tls.md +++ b/docs/content/https/tls.md @@ -191,8 +191,7 @@ See [cipherSuites](https://godoc.org/crypto/tls#pkg-constants) for more informat [tls.options] [tls.options.default] cipherSuites = [ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384" + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" ] ``` @@ -204,7 +203,6 @@ tls: default: cipherSuites: - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - TLS_RSA_WITH_AES_256_GCM_SHA384 ``` ```yaml tab="Kubernetes" @@ -217,7 +215,6 @@ metadata: spec: cipherSuites: - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - TLS_RSA_WITH_AES_256_GCM_SHA384 ``` !!! important "TLS 1.3" diff --git a/docs/content/index.md b/docs/content/index.md index 58b8aa523..6f7cdb268 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -20,4 +20,4 @@ Developing Traefik, our main goal is to make it simple to use, and we're sure yo !!! info - If you're a businness running critical services behind Traefik, know that [Containous](https://containo.us), the company that sponsors Traefik's development, can provide [commercial support](https://containo.us/services/#commercial-support) and develops an [Enterprise Edition](https://containo.us/traefikee/) of Traefik. + If you're a business running critical services behind Traefik, know that [Containous](https://containo.us), the company that sponsors Traefik's development, can provide [commercial support](https://containo.us/services/#commercial-support) and develops an [Enterprise Edition](https://containo.us/traefikee/) of Traefik. diff --git a/docs/content/middlewares/headers.md b/docs/content/middlewares/headers.md index 05c713a63..20fdffcc8 100644 --- a/docs/content/middlewares/headers.md +++ b/docs/content/middlewares/headers.md @@ -235,7 +235,7 @@ http: middlewares: testHeader: headers: - accessControlAllowMethod: + accessControlAllowMethods: - GET - OPTIONS - PUT @@ -331,7 +331,7 @@ If set to 0, would NOT include the header. ### `stsIncludeSubdomains` -The `stsIncludeSubdomains` is set to true, the `includeSubdomains` will be appended to the Strict-Transport-Security header. +The `stsIncludeSubdomains` is set to true, the `includeSubDomains` directive will be appended to the Strict-Transport-Security header. ### `stsPreload` diff --git a/docs/content/middlewares/overview.md b/docs/content/middlewares/overview.md index 51b9fb1f0..a9825bec5 100644 --- a/docs/content/middlewares/overview.md +++ b/docs/content/middlewares/overview.md @@ -183,14 +183,14 @@ and therefore this specification would be ignored even if present. routes: - match: Host(`bar.com`) kind: Rule - services: - - name: whoami - port: 80 - middlewares: - - name: add-foo-prefix@file - # namespace: bar - # A namespace specification such as above is ignored - # when the cross-provider syntax is used. + services: + - name: whoami + port: 80 + middlewares: + - name: add-foo-prefix@file + # namespace: bar + # A namespace specification such as above is ignored + # when the cross-provider syntax is used. ``` ## Available Middlewares diff --git a/docs/content/middlewares/redirectscheme.md b/docs/content/middlewares/redirectscheme.md index e430885a1..fa0142dce 100644 --- a/docs/content/middlewares/redirectscheme.md +++ b/docs/content/middlewares/redirectscheme.md @@ -7,7 +7,7 @@ Redirecting the Client to a Different Scheme/Port TODO: add schema --> -RegexRedirect redirect request from a scheme to another. +RedirectScheme redirect request from a scheme to another. ## Configuration Examples diff --git a/docs/content/migration/v1-to-v2.md b/docs/content/migration/v1-to-v2.md index 19096245d..121ba375b 100644 --- a/docs/content/migration/v1-to-v2.md +++ b/docs/content/migration/v1-to-v2.md @@ -36,7 +36,7 @@ Then any router can refer to an instance of the wanted middleware. ```yaml tab="Docker" labels: - "traefik.frontend.rule=Host:test.localhost;PathPrefix:/test" - - "traefik.frontend.auth.basic.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" + - "traefik.frontend.auth.basic.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" ``` ```yaml tab="K8s Ingress" @@ -99,7 +99,7 @@ Then any router can refer to an instance of the wanted middleware. labels: - "traefik.http.routers.router0.rule=Host(`bar.com`) && PathPrefix(`/test`)" - "traefik.http.routers.router0.middlewares=auth" - - "traefik.http.middlewares.auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" + - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" ``` ```yaml tab="K8s IngressRoute" @@ -204,7 +204,11 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o minVersion = "VersionTLS12" cipherSuites = [ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384" + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", ] [[entryPoints.web-secure.tls.certificates]] certFile = "path/to/my.cert" @@ -212,7 +216,7 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o ``` ```bash tab="CLI" - --entryPoints='Name:web-secure Address::443 TLS:path/to/my.cert,path/to/my.key TLS.MinVersion:VersionTLS12 TLS.CipherSuites:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA384' + --entryPoints='Name:web-secure Address::443 TLS:path/to/my.cert,path/to/my.key TLS.MinVersion:VersionTLS12 TLS.CipherSuites:TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256' ``` !!! info "v2" @@ -238,8 +242,12 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o [tls.options.myTLSOptions] minVersion = "VersionTLS13" cipherSuites = [ - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384" + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", ] ``` @@ -261,8 +269,11 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o myTLSOptions: minVersion: VersionTLS13 cipherSuites: - - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - TLS_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ``` ```yaml tab="K8s IngressRoute" @@ -277,8 +288,11 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o spec: minVersion: VersionTLS13 cipherSuites: - - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - TLS_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 --- apiVersion: traefik.containo.us/v1alpha1 @@ -413,7 +427,7 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd ##---------------------## ## dynamic configuration - # dymanic-conf.toml + # dynamic-conf.toml [http.routers] [http.routers.router0] @@ -457,7 +471,7 @@ To apply a redirection, one of the redirect middlewares, [RedirectRegex](../midd ##---------------------## ## dynamic configuration - # dymanic-conf.yml + # dynamic-conf.yml http: routers: @@ -824,7 +838,7 @@ Each root item has been moved to a related section or removed. ## Dashboard -You need to activate the [API](../operations/dashboard.md#enabling-the-dashboard) to access the dashboard. +You need to activate the API to access the [dashboard](../operations/dashboard.md). As the dashboard access is now secured by default you can either: * define a [specific router](../operations/api.md#configuration) with the `api@internal` service and one authentication middleware like the following example @@ -870,7 +884,7 @@ As the dashboard access is now secured by default you can either: - "traefik.http.routers.api.service=api@internal" - "traefik.http.routers.api.middlewares=myAuth" - "traefik.http.routers.api.tls" - - "traefik.http.middlewares.myAuth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" + - "traefik.http.middlewares.myAuth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/" ``` ```toml tab="File (TOML)" @@ -883,12 +897,12 @@ As the dashboard access is now secured by default you can either: [api] [providers.file] - filename = "/dymanic-conf.toml" + filename = "/dynamic-conf.toml" ##---------------------## ## dynamic configuration - # dymanic-conf.toml + # dynamic-conf.toml [http.routers.api] rule = "Host(`traefik.docker.localhost`)" @@ -915,12 +929,12 @@ As the dashboard access is now secured by default you can either: providers: file: - filename: /dymanic-conf.yaml + filename: /dynamic-conf.yaml ##---------------------## ## dynamic configuration - # dymanic-conf.yaml + # dynamic-conf.yaml http: routers: diff --git a/docs/content/observability/metrics/influxdb.md b/docs/content/observability/metrics/influxdb.md index 71c8ebd70..c30fd44b3 100644 --- a/docs/content/observability/metrics/influxdb.md +++ b/docs/content/observability/metrics/influxdb.md @@ -4,12 +4,12 @@ To enable the InfluxDB: ```toml tab="File (TOML)" [metrics] - [metrics.influxdb] + [metrics.influxDB] ``` ```yaml tab="File (YAML)" metrics: - influxdb: {} + influxDB: {} ``` ```bash tab="CLI" @@ -24,13 +24,13 @@ Address instructs exporter to send metrics to influxdb at this address. ```toml tab="File (TOML)" [metrics] - [metrics.influxdb] + [metrics.influxDB] address = "localhost:8089" ``` ```yaml tab="File (YAML)" metrics: - influxdb: + influxDB: address: localhost:8089 ``` @@ -46,13 +46,13 @@ InfluxDB's address protocol (udp or http). ```toml tab="File (TOML)" [metrics] - [metrics.influxdb] + [metrics.influxDB] protocol = "udp" ``` ```yaml tab="File (YAML)" metrics: - influxdb: + influxDB: protocol: udp ``` @@ -68,13 +68,13 @@ InfluxDB database used when protocol is http. ```toml tab="File (TOML)" [metrics] - [metrics.influxdb] + [metrics.influxDB] database = "" ``` ```yaml tab="File (YAML)" metrics: - influxdb: + influxDB: database: "" ``` @@ -90,13 +90,13 @@ InfluxDB retention policy used when protocol is http. ```toml tab="File (TOML)" [metrics] - [metrics.influxdb] + [metrics.influxDB] retentionPolicy = "" ``` ```yaml tab="File (YAML)" metrics: - influxdb: + influxDB: retentionPolicy: "" ``` @@ -112,13 +112,13 @@ InfluxDB username (only with http). ```toml tab="File (TOML)" [metrics] - [metrics.influxdb] + [metrics.influxDB] username = "" ``` ```yaml tab="File (YAML)" metrics: - influxdb: + influxDB: username: "" ``` @@ -134,13 +134,13 @@ InfluxDB password (only with http). ```toml tab="File (TOML)" [metrics] - [metrics.influxdb] + [metrics.influxDB] password = "" ``` ```yaml tab="File (YAML)" metrics: - influxdb: + influxDB: password: "" ``` @@ -156,13 +156,13 @@ Enable metrics on entry points. ```toml tab="File (TOML)" [metrics] - [metrics.influxdb] + [metrics.influxDB] addEntryPointsLabels = true ``` ```yaml tab="File (YAML)" metrics: - influxdb: + influxDB: addEntryPointsLabels: true ``` @@ -178,13 +178,13 @@ Enable metrics on services. ```toml tab="File (TOML)" [metrics] - [metrics.influxdb] + [metrics.influxDB] addServicesLabels = true ``` ```yaml tab="File (YAML)" metrics: - influxdb: + influxDB: addServicesLabels: true ``` @@ -200,13 +200,13 @@ The interval used by the exporter to push metrics to influxdb. ```toml tab="File (TOML)" [metrics] - [metrics.influxdb] + [metrics.influxDB] pushInterval = 10s ``` ```yaml tab="File (YAML)" metrics: - influxdb: + influxDB: pushInterval: 10s ``` diff --git a/docs/content/observability/metrics/prometheus.md b/docs/content/observability/metrics/prometheus.md index 634c34877..fcb95bd1c 100644 --- a/docs/content/observability/metrics/prometheus.md +++ b/docs/content/observability/metrics/prometheus.md @@ -114,5 +114,5 @@ metrics: ```bash tab="CLI" --entryPoints.metrics.address=":8082" ---metrics.prometheus..entryPoint="metrics" +--metrics.prometheus.entryPoint="metrics" ``` diff --git a/docs/content/observability/metrics/statsd.md b/docs/content/observability/metrics/statsd.md index b7624101b..a777ae74f 100644 --- a/docs/content/observability/metrics/statsd.md +++ b/docs/content/observability/metrics/statsd.md @@ -4,12 +4,12 @@ To enable the Statsd: ```toml tab="File (TOML)" [metrics] - [metrics.statsd] + [metrics.statsD] ``` ```yaml tab="File (YAML)" metrics: - statsd: {} + statsD: {} ``` ```bash tab="CLI" @@ -24,13 +24,13 @@ Address instructs exporter to send metrics to statsd at this address. ```toml tab="File (TOML)" [metrics] - [metrics.statsd] + [metrics.statsD] address = "localhost:8125" ``` ```yaml tab="File (YAML)" metrics: - statsd: + statsD: address: localhost:8125 ``` @@ -46,13 +46,13 @@ Enable metrics on entry points. ```toml tab="File (TOML)" [metrics] - [metrics.statsd] + [metrics.statsD] addEntryPointsLabels = true ``` ```yaml tab="File (YAML)" metrics: - statsd: + statsD: addEntryPointsLabels: true ``` @@ -68,13 +68,13 @@ Enable metrics on services. ```toml tab="File (TOML)" [metrics] - [metrics.statsd] + [metrics.statsD] addServicesLabels = true ``` ```yaml tab="File (YAML)" metrics: - statsd: + statsD: addServicesLabels: true ``` @@ -90,13 +90,13 @@ The interval used by the exporter to push metrics to statsD. ```toml tab="File (TOML)" [metrics] - [metrics.statsd] + [metrics.statsD] pushInterval = 10s ``` ```yaml tab="File (YAML)" metrics: - statsd: + statsD: pushInterval: 10s ``` diff --git a/docs/content/operations/api.md b/docs/content/operations/api.md index 39e41c3c3..24911b440 100644 --- a/docs/content/operations/api.md +++ b/docs/content/operations/api.md @@ -159,24 +159,25 @@ api: All the following endpoints must be accessed with a `GET` HTTP request. -| Path | Description | -|--------------------------------|-------------------------------------------------------------------------------------------| -| `/api/http/routers` | Lists all the HTTP routers information. | -| `/api/http/routers/{name}` | Returns the information of the HTTP router specified by `name`. | -| `/api/http/services` | Lists all the HTTP services information. | -| `/api/http/services/{name}` | Returns the information of the HTTP service specified by `name`. | -| `/api/http/middlewares` | Lists all the HTTP middlewares information. | -| `/api/http/middlewares/{name}` | Returns the information of the HTTP middleware specified by `name`. | -| `/api/tcp/routers` | Lists all the TCP routers information. | -| `/api/tcp/routers/{name}` | Returns the information of the TCP router specified by `name`. | -| `/api/tcp/services` | Lists all the TCP services information. | -| `/api/tcp/services/{name}` | Returns the information of the TCP service specified by `name`. | -| `/api/entrypoints` | Lists all the entry points information. | -| `/api/entrypoints/{name}` | Returns the information of the entry point specified by `name`. | -| `/api/version` | Returns information about Traefik version. | -| `/debug/vars` | See the [expvar](https://golang.org/pkg/expvar/) Go documentation. | -| `/debug/pprof/` | See the [pprof Index](https://golang.org/pkg/net/http/pprof/#Index) Go documentation. | -| `/debug/pprof/cmdline` | See the [pprof Cmdline](https://golang.org/pkg/net/http/pprof/#Cmdline) Go documentation. | -| `/debug/pprof/profile` | See the [pprof Profile](https://golang.org/pkg/net/http/pprof/#Profile) Go documentation. | -| `/debug/pprof/symbol` | See the [pprof Symbol](https://golang.org/pkg/net/http/pprof/#Symbol) Go documentation. | -| `/debug/pprof/trace` | See the [pprof Trace](https://golang.org/pkg/net/http/pprof/#Trace) Go documentation. | +| Path | Description | +|--------------------------------|---------------------------------------------------------------------------------------------| +| `/api/http/routers` | Lists all the HTTP routers information. | +| `/api/http/routers/{name}` | Returns the information of the HTTP router specified by `name`. | +| `/api/http/services` | Lists all the HTTP services information. | +| `/api/http/services/{name}` | Returns the information of the HTTP service specified by `name`. | +| `/api/http/middlewares` | Lists all the HTTP middlewares information. | +| `/api/http/middlewares/{name}` | Returns the information of the HTTP middleware specified by `name`. | +| `/api/tcp/routers` | Lists all the TCP routers information. | +| `/api/tcp/routers/{name}` | Returns the information of the TCP router specified by `name`. | +| `/api/tcp/services` | Lists all the TCP services information. | +| `/api/tcp/services/{name}` | Returns the information of the TCP service specified by `name`. | +| `/api/entrypoints` | Lists all the entry points information. | +| `/api/entrypoints/{name}` | Returns the information of the entry point specified by `name`. | +| `/api/overview` | Returns statistic information about http and tcp as well as enabled features and providers. | +| `/api/version` | Returns information about Traefik version. | +| `/debug/vars` | See the [expvar](https://golang.org/pkg/expvar/) Go documentation. | +| `/debug/pprof/` | See the [pprof Index](https://golang.org/pkg/net/http/pprof/#Index) Go documentation. | +| `/debug/pprof/cmdline` | See the [pprof Cmdline](https://golang.org/pkg/net/http/pprof/#Cmdline) Go documentation. | +| `/debug/pprof/profile` | See the [pprof Profile](https://golang.org/pkg/net/http/pprof/#Profile) Go documentation. | +| `/debug/pprof/symbol` | See the [pprof Symbol](https://golang.org/pkg/net/http/pprof/#Symbol) Go documentation. | +| `/debug/pprof/trace` | See the [pprof Trace](https://golang.org/pkg/net/http/pprof/#Trace) Go documentation. | diff --git a/docs/content/operations/dashboard.md b/docs/content/operations/dashboard.md index 74dfe5ec6..9dc77bb5e 100644 --- a/docs/content/operations/dashboard.md +++ b/docs/content/operations/dashboard.md @@ -3,24 +3,32 @@ See What's Going On {: .subtitle } -The dashboard is the central place that shows you the current active routes handled by Traefik. +The dashboard is the central place that shows you the current active routes handled by Traefik.
Dashboard - Providers
The dashboard in action
-By default, the dashboard is available on `/dashboard` on port `:8080`. -There is also a redirect of `/` to `/dashboard`, but one should not rely on that property as it is bound to change, -and it might make for confusing routing rules anyway. +The dashboard is available at the same location as the [API](./api.md) but on the path `/dashboard/` by default. -!!! info "Did You Know?" - It is possible to customize the dashboard endpoint. - To learn how, refer to the [API documentation](./api.md) - -## Enabling the Dashboard +!!! warning "The trailing slash `/` in `/dashboard/` is mandatory" -To enable the dashboard, you need to enable [Traefik's API](./api.md). +There are 2 ways to configure and access the dashboard: + +- [Secure mode (Recommended)](#secure-mode) +- [Insecure mode](#insecure-mode) + +!!! note "" + There is also a redirect of the path `/` to the path `/dashboard/`, + but one should not rely on that property as it is bound to change, + and it might make for confusing routing rules anyway. + +## Secure Mode + +This is the **recommended** method. + +Start by enabling the dashboard by using the following option from [Traefik's API](./api.md): ```toml tab="File (TOML)" [api] @@ -51,12 +59,39 @@ api: --api.dashboard=true ``` -!!! important "API/Dashboard Security" - - To secure your dashboard, the use of a `service` named `api@internal` is mandatory and requires the definition of a router using one or more security [middlewares](../middlewares/overview.md) - like authentication ([basicAuth](../middlewares/basicauth.md) , [digestAuth](../middlewares/digestauth.md), [forwardAuth](../middlewares/forwardauth.md)) or [whitelisting](../middlewares/ipwhitelist.md). - More information about `api@internal` can be found in the [API documentation](./api.md#configuration) +Then specify a router associated to the service `api@internal` to allow: -!!! info "Did You Know?" - The API provides more features than the Dashboard. - To learn more about it, refer to the [API documentation](./api.md) +- Defining one or more security features through [middlewares](../middlewares/overview.md) + like authentication ([basicAuth](../middlewares/basicauth.md) , [digestAuth](../middlewares/digestauth.md), + [forwardAuth](../middlewares/forwardauth.md)) or [whitelisting](../middlewares/ipwhitelist.md). + +- Defining your own [HTTP routing rule](../../routing/routers/#rule) for accessing the dashboard, + through Traefik itself (sometimes referred as "Traefik-ception"). + +Please visit the ["Configuration" section of the API documentation](./api.md#configuration) +to learn about configuring a router with the service `api@internal` and enabling the security features. + +## Insecure Mode + +This mode is not recommended because it does not allow the use of security features. + +To enable the "insecure mode", use the following options from [Traefik's API](./api.md#insecure): + +```toml tab="File (TOML)" +[api] + dashboard = true + insecure = true +``` + +```yaml tab="File (YAML)" +api: + dashboard: true + insecure: true +``` + +```bash tab="CLI" +--api.dashboard=true --api.insecure=true +``` + +You can now access the dashboard on the port `8080` of the Traefik instance, +at the following URL: `http://:8080/dashboard/` (trailing slash is mandatory). diff --git a/docs/content/operations/ping.md b/docs/content/operations/ping.md index 26c03fca4..b0640207b 100644 --- a/docs/content/operations/ping.md +++ b/docs/content/operations/ping.md @@ -29,6 +29,9 @@ You can customize the `entryPoint` where the `/ping` is active with the `entryPo |---------|---------------|-----------------------------------------------------------------------------------------------------| | `/ping` | `GET`, `HEAD` | A simple endpoint to check for Traefik process liveness. Return a code `200` with the content: `OK` | +!!! note + The `cli` comes with a [`healthcheck`](./cli.md#healthcheck) command which can be used for calling this endpoint. + ### `entryPoint` Enabling /ping on a dedicated EntryPoint. diff --git a/docs/content/providers/file.md b/docs/content/providers/file.md index ca99369ba..747c2de1a 100644 --- a/docs/content/providers/file.md +++ b/docs/content/providers/file.md @@ -4,7 +4,7 @@ Good Old Configuration File {: .subtitle } The file provider lets you define the [dynamic configuration](./overview.md) in a TOML or YAML file. -You can write these configuration elements: +You can write one of these mutually exclusive configuration elements: * In [a dedicated file](#filename) * In [several dedicated files](#directory) diff --git a/docs/content/providers/overview.md b/docs/content/providers/overview.md index bb1280510..e2376cce8 100644 --- a/docs/content/providers/overview.md +++ b/docs/content/providers/overview.md @@ -39,6 +39,38 @@ Below is the list of the currently supported providers in Traefik. The current version of Traefik doesn't support (yet) every provider. See the [previous version (v1.7)](https://docs.traefik.io/v1.7/) for more providers. +### Configuration reload frequency + +In some cases, some providers might undergo a sudden burst of changes, +which would generate a lot of configuration change events. +If Traefik took them all into account, +that would trigger a lot more configuration reloads than what is necessary, +or even useful. + +In order to mitigate that, the `providers.providersThrottleDuration` option can be set. +It is the duration that Traefik waits for, after a configuration reload, +before taking into account any new configuration refresh event. +If any event arrives during that duration, only the most recent one is taken into account, +and all the previous others are dropped. + +This option cannot be set per provider, +but the throttling algorithm applies independently to each of them. +It defaults to 2 seconds. + +```toml tab="File (TOML)" +[providers] + providers.providersThrottleDuration = 10s +``` + +```yaml tab="File (YAML)" +providers: + providersThrottleDuration: 10s +``` + +```bash tab="CLI" +--providers.providersThrottleDuration=10s +``` + diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index c5c813407..e2b6322e2 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -283,10 +283,10 @@ Watch provider. (Default: ```true```) Enable debug logging of generated configuration template. (Default: ```false```) `--providers.file.directory`: -Load configuration from one or more .toml files in a directory. +Load dynamic configuration from one or more .toml or .yml files in a directory. `--providers.file.filename`: -Override default configuration template. For advanced users :) +Load dynamic configuration from a file. `--providers.file.watch`: Watch provider. (Default: ```true```) diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index a223da524..1e7a79b83 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -283,10 +283,10 @@ Watch provider. (Default: ```true```) Enable debug logging of generated configuration template. (Default: ```false```) `TRAEFIK_PROVIDERS_FILE_DIRECTORY`: -Load configuration from one or more .toml files in a directory. +Load dynamic configuration from one or more .toml or .yml files in a directory. `TRAEFIK_PROVIDERS_FILE_FILENAME`: -Override default configuration template. For advanced users :) +Load dynamic configuration from a file. `TRAEFIK_PROVIDERS_FILE_WATCH`: Watch provider. (Default: ```true```) diff --git a/docs/content/routing/overview.md b/docs/content/routing/overview.md index a02c6e6d6..c18e1ad3a 100644 --- a/docs/content/routing/overview.md +++ b/docs/content/routing/overview.md @@ -235,3 +235,168 @@ http: servers: - address: xx.xx.xx.xx:xx ``` + +## Transport configuration + +Most of what happens to the connection between the clients and Traefik, +and then between Traefik and the backend servers, is configured through the +[entrypoints](../entrypoints) and the [routers](../routers). + +In addition, a few parameters are dedicated to configuring globally +what happens with the connections between Traefik and the backends. +This is done through the `serversTransport` section of the configuration, +which features these options: + +### `insecureSkipVerify` + +_Optional, Default=false_ + +`insecureSkipVerify` disables SSL certificate verification. + +```toml tab="File (TOML)" +## Static configuration +[serversTransport] + insecureSkipVerify = true +``` + +```yaml tab="File (YAML)" +## Static configuration +serversTransport: + insecureSkipVerify: true +``` + +```bash tab="CLI" +## Static configuration +--serversTransport.insecureSkipVerify=true +``` + +### `rootCAs` + +_Optional_ + +`rootCAs` is the list of certificates (as file paths, or data bytes) +that will be set as Root Certificate Authorities when using a self-signed TLS certificate. + +```toml tab="File (TOML)" +## Static configuration +[serversTransport] + rootCAs = ["foo.crt", "bar.crt"] +``` + +```yaml tab="File (YAML)" +## Static configuration +serversTransport: + rootCAs: + - foo.crt + - bar.crt +``` + +```bash tab="CLI" +## Static configuration +--serversTransport.rootCAs=foo.crt,bar.crt +``` + +### `maxIdleConnsPerHost` + +_Optional, Default=2_ + +If non-zero, `maxIdleConnsPerHost` controls the maximum idle (keep-alive) connections to keep per-host. + +```toml tab="File (TOML)" +## Static configuration +[serversTransport] + maxIdleConnsPerHost = 7 +``` + +```yaml tab="File (YAML)" +## Static configuration +serversTransport: + maxIdleConnsPerHost: 7 +``` + +```bash tab="CLI" +## Static configuration +--serversTransport.maxIdleConnsPerHost=7 +``` + +### `forwardingTimeouts` + +`forwardingTimeouts` is about a number of timeouts relevant to when forwarding requests to the backend servers. + +#### forwardingTimeouts.dialTimeout` + +_Optional, Default=30s_ + +`dialTimeout` is the maximum duration allowed for a connection to a backend server to be established. +Zero means no timeout. + +```toml tab="File (TOML)" +## Static configuration +[serversTransport.forwardingTimeouts] + dialTimeout = "1s" +``` + +```yaml tab="File (YAML)" +## Static configuration +serversTransport: + forwardingTimeouts: + dialTimeout: 1s +``` + +```bash tab="CLI" +## Static configuration +--serversTransport.forwardingTimeouts.dialTimeout=1s +``` + +#### forwardingTimeouts.responseHeaderTimeout` + +_Optional, Default=0s_ + +`responseHeaderTimeout`, if non-zero, specifies the amount of time to wait for a server's response headers +after fully writing the request (including its body, if any). +This time does not include the time to read the response body. +Zero means no timeout. + +```toml tab="File (TOML)" +## Static configuration +[serversTransport.forwardingTimeouts] + responseHeaderTimeout = "1s" +``` + +```yaml tab="File (YAML)" +## Static configuration +serversTransport: + forwardingTimeouts: + responseHeaderTimeout: 1s +``` + +```bash tab="CLI" +## Static configuration +--serversTransport.forwardingTimeouts.responseHeaderTimeout=1s +``` + +#### forwardingTimeouts.idleConnTimeout` + +_Optional, Default=90s_ + +`idleConnTimeout`, is the maximum amount of time an idle (keep-alive) connection +will remain idle before closing itself. +Zero means no limit. + +```toml tab="File (TOML)" +## Static configuration +[serversTransport.forwardingTimeouts] + idleConnTimeout = "1s" +``` + +```yaml tab="File (YAML)" +## Static configuration +serversTransport: + forwardingTimeouts: + idleConnTimeout: 1s +``` + +```bash tab="CLI" +## Static configuration +--serversTransport.forwardingTimeouts.idleConnTimeout=1s +``` diff --git a/docs/content/routing/providers/docker.md b/docs/content/routing/providers/docker.md index 52347640d..eade358c5 100644 --- a/docs/content/routing/providers/docker.md +++ b/docs/content/routing/providers/docker.md @@ -87,7 +87,7 @@ Attach labels to your containers and let Traefik do the rest! !!! info "Labels" - Labels are case insensitive. - - The complete list of labels can be found [the reference page](../../reference/dynamic-configuration/docker.md) + - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/docker.md). ### General @@ -96,6 +96,32 @@ Traefik creates, for each container, a corresponding [service](../services/index The Service automatically gets a server per instance of the container, and the router automatically gets a rule defined by `defaultRule` (if no rule for it was defined in labels). +#### Service definition + +--8<-- "content/routing/providers/service-by-label.md" + +??? example "Automatic service assignment with labels" + + With labels in a compose file + + ```yaml + labels: + - "traefik.http.routers.myproxy.rule=Host(`foo.com`)" + # service myservice gets automatically assigned to router myproxy + - "traefik.http.services.myservice.loadbalancer.server.port=80" + ``` + +??? example "Automatic service creation and assignment with labels" + + With labels in a compose file + + ```yaml + labels: + # no service specified or defined and yet one gets automatically created + # and assigned to router myproxy. + - "traefik.http.routers.myproxy.rule=Host(`foo.com`)" + ``` + ### Routers To update the configuration of the Router automatically attached to the container, @@ -140,7 +166,7 @@ For example, to change the rule, you could add the label ```traefik.http.routers See [tls](../routers/index.md#tls) for more information. ```yaml - - "traefik.http.routers.myrouter>.tls=true" + - "traefik.http.routers.myrouter.tls=true" ``` ??? info "`traefik.http.routers..tls.certresolver`" @@ -176,7 +202,8 @@ For example, to change the rule, you could add the label ```traefik.http.routers ``` ??? info "`traefik.http.routers..priority`" - + + See [options](../routers/index.md#priority) for more information. ```yaml - "traefik.http.routers.myrouter.priority=42" @@ -210,7 +237,8 @@ you'd add the label `traefik.http.services..loadbalancer.pa ``` ??? info "`traefik.http.services..loadbalancer.passhostheader`" - + + See [pass Host header](../services/index.md#pass-host-header) for more information. ```yaml - "traefik.http.services.myservice.loadbalancer.passhostheader=true" @@ -305,9 +333,8 @@ you'd add the label `traefik.http.services..loadbalancer.pa ``` ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" - - FlushInterval specifies the flush interval to flush to the client while copying the response body. + See [response forwarding](../services/index.md#response-forwarding) for more information. ```yaml - "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10" diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index 96b192daf..a8654701a 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -110,9 +110,9 @@ spec: !!! important "Cross-provider namespace" As Kubernetes also has its own notion of namespace, one should not confuse the kubernetes namespace of a resource -(in the reference to the middleware) with the [provider namespace](../../middlewares/overview.md#provider-namespace), -when the definition of the middleware is from another provider. -In this context, specifying a namespace when referring to the resource does not make any sense, and will be ignored. + (in the reference to the middleware) with the [provider namespace](../../middlewares/overview.md#provider-namespace), + when the definition of the middleware is from another provider. + In this context, specifying a namespace when referring to the resource does not make any sense, and will be ignored. More information about available middlewares in the dedicated [middlewares section](../../middlewares/overview.md). @@ -163,9 +163,9 @@ spec: If the optional `namespace` attribute is not set, the configuration will be applied with the namespace of the IngressRoute. Additionally, when the definition of the TLS option is from another provider, -the cross-provider syntax (`middlewarename@provider`) should be used to refer to the TLS option, -just as in the [middleware case](../../middlewares/overview.md#provider-namespace). -Specifying a namespace attribute in this case would not make any sense, and will be ignored. + the cross-provider syntax (`middlewarename@provider`) should be used to refer to the TLS option, + just as in the [middleware case](../../middlewares/overview.md#provider-namespace). + Specifying a namespace attribute in this case would not make any sense, and will be ignored. ### TLS diff --git a/docs/content/routing/providers/marathon.md b/docs/content/routing/providers/marathon.md index 3fbad1408..10478c39e 100644 --- a/docs/content/routing/providers/marathon.md +++ b/docs/content/routing/providers/marathon.md @@ -10,7 +10,7 @@ See also [Marathon user guide](../../user-guides/marathon.md). !!! info "Labels" - Labels are case insensitive. - - The complete list of labels can be found [the reference page](../../reference/dynamic-configuration/marathon.md) + - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/marathon.md). ### General @@ -19,6 +19,32 @@ Traefik creates, for each Marathon application, a corresponding [service](../ser The Service automatically gets a server per instance of the application, and the router automatically gets a rule defined by defaultRule (if no rule for it was defined in labels). +#### Service definition + +--8<-- "content/routing/providers/service-by-label.md" + +??? example "Automatic service assignment with labels" + + Service myservice gets automatically assigned to router myproxy. + + ```json + labels: { + "traefik.http.routers.myproxy.rule": "Host(`foo.com`)", + "traefik.http.services.myservice.loadbalancer.server.port": "80" + } + ``` + +??? example "Automatic service creation and assignment with labels" + + No service specified or defined, and yet one gets automatically created. + and assigned to router myproxy. + + ```json + labels: { + "traefik.http.routers.myproxy.rule": "Host(`foo.com`)" + } + ``` + ### Routers To update the configuration of the Router automatically attached to the application, @@ -99,7 +125,8 @@ For example, to change the routing rule, you could add the label ```"traefik.htt ``` ??? info "`traefik.http.routers..priority`" - + + See [options](../routers/index.md#priority) for more information. ```json "traefik.http.routers.myrouter.priority": "42" @@ -130,7 +157,8 @@ For example, to change the passHostHeader behavior, you'd add the label `"traefi ``` ??? info "`traefik.http.services..loadbalancer.passhostheader`" - + + See [pass Host header](../services/index.md#pass-host-header) for more information. ```json "traefik.http.services.myservice.loadbalancer.passhostheader": "true" @@ -225,10 +253,9 @@ For example, to change the passHostHeader behavior, you'd add the label `"traefi ``` ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" - - - FlushInterval specifies the flush interval to flush to the client while copying the response body. + See [response forwarding](../services/index.md#response-forwarding) for more information. + ```json "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval": "10" ``` diff --git a/docs/content/routing/providers/rancher.md b/docs/content/routing/providers/rancher.md index 9c4804b91..4adb45614 100644 --- a/docs/content/routing/providers/rancher.md +++ b/docs/content/routing/providers/rancher.md @@ -17,7 +17,7 @@ Attach labels to your services and let Traefik do the rest! !!! info "Labels" - Labels are case insensitive. - - The complete list of labels can be found [the reference page](../../reference/dynamic-configuration/rancher.md) + - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/rancher.md). ### General @@ -25,6 +25,32 @@ Traefik creates, for each rancher service, a corresponding [service](../services The Service automatically gets a server per container in this rancher service, and the router gets a default rule attached to it, based on the service name. +#### Service definition + +--8<-- "content/routing/providers/service-by-label.md" + +??? example "Automatic service assignment with labels" + + With labels in a compose file + + ```yaml + labels: + - "traefik.http.routers.myproxy.rule=Host(`foo.com`)" + # service myservice gets automatically assigned to router myproxy + - "traefik.http.services.myservice.loadbalancer.server.port=80" + ``` + +??? example "Automatic service creation and assignment with labels" + + With labels in a compose file + + ```yaml + labels: + # no service specified or defined and yet one gets automatically created + # and assigned to router myproxy. + - "traefik.http.routers.myproxy.rule=Host(`foo.com`)" + ``` + ### Routers To update the configuration of the Router automatically attached to the container, add labels starting with `traefik.routers.{name-of-your-choice}.` and followed by the option you want to change. @@ -104,7 +130,8 @@ For example, to change the rule, you could add the label ```traefik.http.routers ``` ??? info "`traefik.http.routers..priority`" - + + See [options](../routers/index.md#priority) for more information. ```yaml - "traefik.http.routers.myrouter.priority=42" @@ -136,7 +163,8 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa ``` ??? info "`traefik.http.services..loadbalancer.passhostheader`" - + + See [pass Host header](../services/index.md#pass-host-header) for more information. ```yaml - "traefik.http.services.myservice.loadbalancer.passhostheader=true" @@ -231,10 +259,9 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa ``` ??? info "`traefik.http.services..loadbalancer.responseforwarding.flushinterval`" - - - FlushInterval specifies the flush interval to flush to the client while copying the response body. + See [response forwarding](../services/index.md#response-forwarding) for more information. + ```yaml - "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10" ``` diff --git a/docs/content/routing/providers/service-by-label.md b/docs/content/routing/providers/service-by-label.md new file mode 100644 index 000000000..bd16fd43e --- /dev/null +++ b/docs/content/routing/providers/service-by-label.md @@ -0,0 +1,16 @@ +In general when configuring a Traefik provider, +a service assigned to one (or several) router(s) must be defined as well for the routing to be functional. + +There are, however, exceptions when using label-based configurations: + +1. If a label defines a router (e.g. through a router Rule) +and a label defines a service (e.g. implicitly through a loadbalancer server port value), +but the router does not specify any service, +then that service is automatically assigned to the router. +1. If a label defines a router (e.g. through a router Rule) +but no service is defined, then a service is automatically created +and assigned to the router. + +!!! info "" + As one would expect, in either of these cases, if in addition a service is specified for the router, + then that service is the one assigned, regardless of whether it actually is defined or whatever else other services are defined. diff --git a/docs/content/routing/routers/index.md b/docs/content/routing/routers/index.md index bf717a8a1..22186a5c0 100644 --- a/docs/content/routing/routers/index.md +++ b/docs/content/routing/routers/index.md @@ -229,7 +229,7 @@ The table below lists all the available matchers: | ```Method(`GET`, ...)``` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`) | | ```Path(`/path`, `/articles/{category}/{id:[0-9]+}`, ...)``` | Match exact request path. It accepts a sequence of literal and regular expression paths. | | ```PathPrefix(`/products/`, `/articles/{category}/{id:[0-9]+}`)``` | Match request prefix path. It accepts a sequence of literal and regular expression prefix paths. | -| ```Query(`foo=bar`, `bar=baz`)``` | Match` Query String parameters. It accepts a sequence of key=value pairs. | +| ```Query(`foo=bar`, `bar=baz`)``` | Match Query String parameters. It accepts a sequence of key=value pairs. | !!! important "Regexp Syntax" @@ -253,6 +253,85 @@ The table below lists all the available matchers: For instance, `PathPrefix: /products` would match `/products` but also `/products/shoes` and `/products/shirts`. Since the path is forwarded as-is, your service is expected to listen on `/products`. +### Priority + +To avoid path overlap, routes are sorted, by default, in descending order using rules length. The priority is directly equal to the length of the rule, and so the longest length has the highest priority. + +A value of `0` for the priority is ignored: `priority = 0` means that the default rules length sorting is used. + +??? info "How default priorities are computed" + + ```toml tab="File (TOML)" + ## Dynamic configuration + [http.routers] + [http.routers.Router-1] + rule = "HostRegexp(`.*\.traefik\.com`)" + # ... + [http.routers.Router-2] + rule = "Host(`foobar.traefik.com`)" + # ... + ``` + + ```yaml tab="File (YAML)" + ## Dynamic configuration + http: + routers: + Router-1: + rule: "HostRegexp(`.*\.traefik\.com`)" + # ... + Router-2: + rule: "Host(`foobar.traefik.com`)" + # ... + ``` + + In this case, all requests with host `foobar.traefik.com` will be routed through `Router-1` instead of `Router-2`. + + | Name | Rule | Priority | + |----------|--------------------------------------|----------| + | Router-1 | ```HostRegexp(`.*\.traefik\.com`)``` | 30 | + | Router-2 | ```Host(`foobar.traefik.com`)``` | 26 | + + The previous table shows that `Router-1` has a higher priority than `Router-2`. + + To solve this issue, the priority must be setted. + +??? example "Set priorities -- using the [File Provider](../../providers/file.md)" + + ```toml tab="File (TOML)" + ## Dynamic configuration + [http.routers] + [http.routers.Router-1] + rule = "HostRegexp(`.*\.traefik\.com`)" + entryPoints = ["web"] + service = "service-1" + priority = 1 + [http.routers.Router-2] + rule = "Host(`foobar.traefik.com`)" + entryPoints = ["web"] + priority = 2 + service = "service-2" + ``` + + ```yaml tab="File (YAML)" + ## Dynamic configuration + http: + routers: + Router-1: + rule: "HostRegexp(`.*\.traefik\.com`)" + entryPoints: + - "web" + service: service-1 + priority: 1 + Router-2: + rule: "Host(`foobar.traefik.com`)" + entryPoints: + - "web" + priority: 2 + service: service-2 + ``` + + In this configuration, the priority is configured to allow `Router-2` to handle requests with the `foobar.traefik.com` host. + ### Middlewares You can attach a list of [middlewares](../../middlewares/overview.md) to each HTTP router. @@ -288,8 +367,14 @@ The middlewares will take effect only if the rule matches, and before forwarding ### Service -You must attach a [service](../services/index.md) per router. -Services are the target for the router. +Each request must eventually be handled by a [service](../services/index.md), +which is why each router definition should include a service target, +which is basically where the request will be passed along to. + +In general, a service assigned to a router should have been defined, +but there are exceptions for label-based providers. +See the specific [docker](../providers/docker.md#service-definition), [rancher](../providers/rancher.md#service-definition), +or [marathon](../providers/marathon.md#service-definition) documentation. !!! important "HTTP routers can only target HTTP services (not TCP services)." @@ -394,8 +479,11 @@ It refers to a [TLS Options](../../https/tls.md#tls-options) and will be applied [tls.options.foo] minVersion = "VersionTLS12" cipherSuites = [ + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384" ] ``` @@ -415,8 +503,11 @@ It refers to a [TLS Options](../../https/tls.md#tls-options) and will be applied foo: minVersion: VersionTLS12 cipherSuites: + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - TLS_RSA_WITH_AES_256_GCM_SHA384 ``` !!! important "Conflicting TLS Options" @@ -511,7 +602,8 @@ http: certResolver: "bar" domains: - main: "snitest.com" - sans: "*.snitest.com" + sans: + - "*.snitest.com" ``` [ACME v2](https://community.letsencrypt.org/t/acme-v2-and-wildcard-certificate-support-is-live/55579) supports wildcard certificates. @@ -766,8 +858,11 @@ It refers to a [TLS Options](../../https/tls.md#tls-options) and will be applied [tls.options.foo] minVersion = "VersionTLS12" cipherSuites = [ + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_GCM_SHA384" ] ``` @@ -787,8 +882,11 @@ It refers to a [TLS Options](../../https/tls.md#tls-options) and will be applied foo: minVersion: VersionTLS12 cipherSuites: - - "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" - - "TLS_RSA_WITH_AES_256_GCM_SHA384" + - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 + - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ``` #### `certResolver` @@ -840,5 +938,6 @@ tcp: certResolver: "bar" domains: - main: "snitest.com" - sans: "*.snitest.com" + sans: + - "*.snitest.com" ``` diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md index 95c79c57f..2e8b4e53e 100644 --- a/docs/content/routing/services/index.md +++ b/docs/content/routing/services/index.md @@ -232,7 +232,7 @@ Below are the available options for the health check mechanism: ```toml tab="TOML" ## Dynamic configuration [http.services] - [http.servicess.Service-1] + [http.services.Service-1] [http.services.Service-1.loadBalancer.healthCheck] path = "/health" interval = "10s" @@ -242,7 +242,7 @@ Below are the available options for the health check mechanism: ```yaml tab="YAML" ## Dynamic configuration http: - servicess: + services: Service-1: loadBalancer: healthCheck: @@ -322,6 +322,63 @@ Below are the available options for the health check mechanism: My-Header: bar ``` +#### Pass Host Header + +The `passHostHeader` allows to forward client Host header to server. + +By default, `passHostHeader` is true. + +??? example "Don't forward the host header -- Using the [File Provider](../../providers/file.md)" + + ```toml tab="TOML" + ## Dynamic configuration + [http.services] + [http.services.Service01] + [http.services.Service01.loadBalancer] + passHostHeader = false + ``` + + ```yaml tab="YAML" + ## Dynamic configuration + http: + services: + Service01: + loadBalancer: + passHostHeader: false + ``` + +#### Response Forwarding + +This section is about configuring how Traefik forwards the response from the backend server to the client. + +Below are the available options for the Response Forwarding mechanism: + +- `FlushInterval` specifies the interval in between flushes to the client while copying the response body. + It is a duration in milliseconds, defaulting to 100. + A negative value means to flush immediately after each write to the client. + The FlushInterval is ignored when ReverseProxy recognizes a response as a streaming response; + for such responses, writes are flushed to the client immediately. + +??? example "Using a custom FlushInterval -- Using the [File Provider](../../providers/file.md)" + + ```toml tab="TOML" + ## Dynamic configuration + [http.services] + [http.services.Service-1] + [http.services.Service-1.loadBalancer.responseForwarding] + flushInterval = "1s" + ``` + + ```yaml tab="YAML" + ## Dynamic configuration + http: + services: + Service-1: + loadBalancer: + responseForwarding: + flushInterval: 1s + ``` + ### Weighted Round Robin (service) The WRR is able to load balance the requests between multiple services based on weights. diff --git a/docs/content/user-guides/crd-acme/03-deployments.yml b/docs/content/user-guides/crd-acme/03-deployments.yml index 1d1f98c3a..4873b34c9 100644 --- a/docs/content/user-guides/crd-acme/03-deployments.yml +++ b/docs/content/user-guides/crd-acme/03-deployments.yml @@ -6,7 +6,7 @@ metadata: --- kind: Deployment -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 metadata: namespace: default name: traefik @@ -49,7 +49,7 @@ spec: --- kind: Deployment -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 metadata: namespace: default name: whoami diff --git a/docs/content/user-guides/crd-acme/04-ingressroutes.yml b/docs/content/user-guides/crd-acme/04-ingressroutes.yml index dae1bce30..9c6376d62 100644 --- a/docs/content/user-guides/crd-acme/04-ingressroutes.yml +++ b/docs/content/user-guides/crd-acme/04-ingressroutes.yml @@ -2,6 +2,7 @@ apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: simpleingressroute + namespace: default spec: entryPoints: - web @@ -17,6 +18,7 @@ apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: ingressroutetls + namespace: default spec: entryPoints: - websecure diff --git a/go.mod b/go.mod index 512bcc464..0bc1b3eba 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/felixge/httpsnoop v1.0.0 // indirect 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.0.2 + github.com/go-acme/lego/v3 v3.1.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.2 @@ -51,7 +51,6 @@ require ( github.com/huandu/xstrings v1.2.0 // indirect github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc github.com/instana/go-sensor v1.4.17-0.20190515112224-78c14625025a - github.com/labbsr0x/goh v0.0.0-20190830205702-3d6988c73e10 // indirect github.com/libkermit/compose v0.0.0-20171122111507-c04e39c026ad github.com/libkermit/docker v0.0.0-20171122101128-e6674d32b807 github.com/libkermit/docker-check v0.0.0-20171122104347-1113af38e591 @@ -72,26 +71,24 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/philhofer/fwd v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 - github.com/prometheus/client_golang v1.0.0 + github.com/prometheus/client_golang v1.1.0 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 - github.com/prometheus/common v0.6.0 // indirect - github.com/prometheus/procfs v0.0.3 // indirect github.com/rancher/go-rancher-metadata v0.0.0-00010101000000-000000000000 github.com/sirupsen/logrus v1.4.2 - github.com/stretchr/testify v1.3.0 + github.com/stretchr/testify v1.4.0 github.com/stvp/go-udp-testing v0.0.0-20171104055251-c4434f09ec13 github.com/tinylib/msgp v1.0.2 // indirect github.com/transip/gotransip v5.8.2+incompatible // indirect github.com/uber/jaeger-client-go v2.16.0+incompatible github.com/uber/jaeger-lib v2.0.0+incompatible github.com/unrolled/render v1.0.1 - github.com/unrolled/secure v1.0.1 + github.com/unrolled/secure v1.0.4 github.com/vdemeester/shakers v0.1.0 github.com/vulcand/oxy v1.0.0 github.com/vulcand/predicate v1.1.0 - golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 + golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // indirect - golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 + golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 // indirect google.golang.org/grpc v1.22.1 gopkg.in/DataDog/dd-trace-go.v1 v1.16.1 diff --git a/go.sum b/go.sum index d062717cd..dcebb5ef1 100644 --- a/go.sum +++ b/go.sum @@ -78,6 +78,8 @@ github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/c0va23/go-proxyprotocol v0.9.1 h1:5BCkp0fDJOhzzH1lhjUgHhmZz9VvRMMif1U2D31hb34= github.com/c0va23/go-proxyprotocol v0.9.1/go.mod h1:TNjUV+llvk8TvWJxlPYAeAYZgSzT/iicNr3nWBWX320= github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= @@ -85,8 +87,8 @@ github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4r github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cloudflare-go v0.10.0 h1:wJPNqfrQO0w3fCiQcf/2T4lR2y6Q2fAwRszllljgb8I= -github.com/cloudflare/cloudflare-go v0.10.0/go.mod h1:fOESqHl/jzAmCtEyjceLkw3v0rVjzl8V9iehxZPynXY= +github.com/cloudflare/cloudflare-go v0.10.2 h1:VBodKICVPnwmDxstcW3biKcDSpFIfS/RELUXsZSBYK4= +github.com/cloudflare/cloudflare-go v0.10.2/go.mod h1:qhVI5MKwBGhdNU89ZRz2plgYutcJ5PCekLxXn56w6SY= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codegangsta/negroni v1.0.0 h1:+aYywywx4bnKXWvoWtRfJ91vC59NbEhEY03sZjQhbVY= @@ -113,6 +115,7 @@ github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+ github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpu/goacmedns v0.0.1 h1:GeIU5chKys9zmHgOAgP+bstRaLqcGQ6HJh/hLw9hrus= github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -178,8 +181,9 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 h1:df6OFl8WNXk82xxP3R9ZPZ5seOA8XZkwLdbEzZF1/xI= github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/go-acme/lego/v3 v3.0.2 h1:cnS+URiPzkt2pd7I2WlZtFyt2ihQ762nouBybY4djjw= -github.com/go-acme/lego/v3 v3.0.2/go.mod h1:sMoLjf8BUo4Jexg+6Xw5KeFx98KVZ7Nfczh9tzLyhJU= +github.com/go-acme/lego/v3 v3.1.0 h1:yanYFoYW8azFkCvJfIk7edWWfjkYkhDxe45ZsxoW4Xk= +github.com/go-acme/lego/v3 v3.1.0/go.mod h1:074uqt+JS6plx+c9Xaiz6+L+GBb+7itGtzfcDM2AhEE= +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= github.com/go-ini/ini v1.44.0 h1:8+SRbfpRFlIunpSum4BEf1ClTtVjOgKzgBv9pHFkI6w= @@ -226,6 +230,8 @@ github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASu github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -287,6 +293,8 @@ github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBv github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -304,11 +312,10 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/labbsr0x/bindman-dns-webhook v1.0.0 h1:gooRvyQtVOCtV/l9ZCI4CManZeVN/kUWG/vugRqHqv4= -github.com/labbsr0x/bindman-dns-webhook v1.0.0/go.mod h1:pn4jcNjxSywRWDPDyGkFzgSnwty18OFdiUFc6S6fpgc= -github.com/labbsr0x/goh v0.0.0-20190417202808-8b16b4848295/go.mod h1:RBxeaayaaMmp7GxwHiKANjkg9e+rxjOm4mB5vD5rt/I= -github.com/labbsr0x/goh v0.0.0-20190830205702-3d6988c73e10 h1:mrPTy7qNJPGHaUkkN301r8Y+13l2/vsiC8Lvi09e6sI= -github.com/labbsr0x/goh v0.0.0-20190830205702-3d6988c73e10/go.mod h1:RBxeaayaaMmp7GxwHiKANjkg9e+rxjOm4mB5vD5rt/I= +github.com/labbsr0x/bindman-dns-webhook v1.0.2 h1:I7ITbmQPAVwrDdhd6dHKi+MYJTJqPCK0jE6YNBAevnk= +github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA= +github.com/labbsr0x/goh v1.0.1 h1:97aBJkDjpyBZGPbQuOK5/gHcSFbcr5aRsq3RSRJFpPk= +github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w= github.com/libkermit/compose v0.0.0-20171122111507-c04e39c026ad h1:nTyRWZ864mnHUnusBCVA628AZFgfGHwRUpbHqGhRQr8= github.com/libkermit/compose v0.0.0-20171122111507-c04e39c026ad/go.mod h1:GyCk/ifDcqsU1tsRMMWqXANnTtxzcwEWscb7j5qmblM= github.com/libkermit/docker v0.0.0-20171122101128-e6674d32b807 h1:/7J1WDQd6Xn1Pr8KtE2I/7/cKw66AV3hBUOyxqyXo84= @@ -317,6 +324,8 @@ github.com/libkermit/docker-check v0.0.0-20171122104347-1113af38e591 h1:+zkZyvOy github.com/libkermit/docker-check v0.0.0-20171122104347-1113af38e591/go.mod h1:EBQ0jeOrBpOTkquwjmJl4W6z5xqlf5oA2LZfTqRNcO0= github.com/linode/linodego v0.10.0 h1:AMdb82HVgY8o3mjBXJcUv9B+fnJjfDMn2rNRGbX+jvM= github.com/linode/linodego v0.10.0/go.mod h1:cziNP7pbvE3mXIPneHj0oRY8L1WtGEIKlZ8LANE4eXA= +github.com/liquidweb/liquidweb-go v1.6.0 h1:vIj1I/Wf97fUnyirD+bi6Y63c0GiXk9nKI1+sFFl3G0= +github.com/liquidweb/liquidweb-go v1.6.0/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVLEIG/i5J9cyixzQ= github.com/looplab/fsm v0.1.0 h1:Qte7Zdn/5hBNbXzP7yxVU4OIFHWXBovyTT2LaBTyC20= github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= @@ -346,6 +355,7 @@ github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQz github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -414,6 +424,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE= @@ -432,10 +444,12 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhD github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sacloud/libsacloud v1.26.1 h1:td3Kd7lvpSAxxHEVpnaZ9goHmmhi0D/RfP0Rqqf/kek= github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ= github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= @@ -454,6 +468,8 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stvp/go-udp-testing v0.0.0-20171104055251-c4434f09ec13 h1:WYRIgR83bWdH2zjqXalfLuQYtgBG1KKxDRxinx2ygMI= github.com/stvp/go-udp-testing v0.0.0-20171104055251-c4434f09ec13/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7 h1:CpHxIaZzVy26GqJn8ptRyto8fuoYOd1v0fXm9bG3wQ8= @@ -472,9 +488,9 @@ github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6 github.com/ugorji/go v0.0.0-20171019201919-bdcc60b419d1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/unrolled/render v1.0.1 h1:VDDnQQVfBMsOsp3VaCJszSO0nkBIVEYoPWeRThk9spY= github.com/unrolled/render v1.0.1/go.mod h1:gN9T0NhL4Bfbwu8ann7Ry/TGHYfosul+J0obPf6NBdM= -github.com/unrolled/secure v1.0.1 h1:PZ79/VmnyIrDWRAUp9lWSwmckdf8H0v9djiqZxAb8Tc= -github.com/unrolled/secure v1.0.1/go.mod h1:R6rugAuzh4TQpbFAq69oqZggyBQxFRFQIewtz5z7Jsc= -github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= +github.com/unrolled/secure v1.0.4 h1:DksfKsRTyXP2R8quDdOOuRpRO45VprFL0X9t9+JX1PU= +github.com/unrolled/secure v1.0.4/go.mod h1:R6rugAuzh4TQpbFAq69oqZggyBQxFRFQIewtz5z7Jsc= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vdemeester/shakers v0.1.0 h1:K+n9sSyUCg2ywmZkv+3c7vsYZfivcfKhMh8kRxCrONM= github.com/vdemeester/shakers v0.1.0/go.mod h1:IZ1HHynUOQt32iQ3rvAeVddXLd19h/6LWiKsh9RZtAQ= github.com/vulcand/oxy v1.0.0 h1:7vL5/pjDFzHGbtBEhmlHITUi6KLH4xXTDF33/wrdRKw= @@ -537,6 +553,8 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3 h1:6KET3Sqa7fkVfD63QnAM81ZeYg5n4HwApOJkufONnHA= +golang.org/x/net v0.0.0-20190930134127-c5a3c61f89f3/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -563,6 +581,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b h1:ag/x1USPSsqHud38I9BAC88qdNLDHHtQ4mlgQIZPPNA= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -574,6 +593,8 @@ golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 h1:xQwXv67TxFo9nC1GJFyab5eq/5B590r6RlnL/G8Sz7w= +golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/integration/docker_compose_test.go b/integration/docker_compose_test.go index d499d2258..8fd14405a 100644 --- a/integration/docker_compose_test.go +++ b/integration/docker_compose_test.go @@ -77,7 +77,7 @@ func (s *DockerComposeSuite) TestComposeScale(c *check.C) { services := rtconf.Services c.Assert(services, checker.HasLen, 1) for k, v := range services { - c.Assert(k, checker.Equals, composeService+"_integrationtest"+composeProject+"@docker") + c.Assert(k, checker.Equals, composeService+"-integrationtest"+composeProject+"@docker") c.Assert(v.LoadBalancer.Servers, checker.HasLen, serviceCount) // We could break here, but we don't just to keep us honest. } diff --git a/integration/error_pages_test.go b/integration/error_pages_test.go index 5a4fd4afb..5b218bbe8 100644 --- a/integration/error_pages_test.go +++ b/integration/error_pages_test.go @@ -47,7 +47,6 @@ func (s *ErrorPagesSuite) TestSimpleConfiguration(c *check.C) { } func (s *ErrorPagesSuite) TestErrorPage(c *check.C) { - // error.toml contains a mis-configuration of the backend host file := s.adaptFile(c, "fixtures/error_pages/error.toml", struct { Server1 string diff --git a/integration/grpc_test.go b/integration/grpc_test.go index d79ed0009..074596e51 100644 --- a/integration/grpc_test.go +++ b/integration/grpc_test.go @@ -90,7 +90,6 @@ func getHelloClientGRPC() (helloworld.GreeterClient, func() error, error) { return nil, func() error { return nil }, err } return helloworld.NewGreeterClient(conn), conn.Close, nil - } func getHelloClientGRPCh2c() (helloworld.GreeterClient, func() error, error) { @@ -99,7 +98,6 @@ func getHelloClientGRPCh2c() (helloworld.GreeterClient, func() error, error) { return nil, func() error { return nil }, err } return helloworld.NewGreeterClient(conn), conn.Close, nil - } func callHelloClientGRPC(name string, secure bool) (string, error) { diff --git a/integration/healthcheck_test.go b/integration/healthcheck_test.go index 110ba08eb..999c69a9a 100644 --- a/integration/healthcheck_test.go +++ b/integration/healthcheck_test.go @@ -27,7 +27,6 @@ func (s *HealthCheckSuite) SetUpSuite(c *check.C) { } func (s *HealthCheckSuite) TestSimpleConfiguration(c *check.C) { - file := s.adaptFile(c, "fixtures/healthcheck/simple.toml", struct { Server1 string Server2 string @@ -166,7 +165,6 @@ func (s *HealthCheckSuite) TestMultipleEntrypoints(c *check.C) { } func (s *HealthCheckSuite) TestPortOverload(c *check.C) { - // Set one whoami health to 200 client := &http.Client{} statusInternalServerErrorReq, err := http.NewRequest(http.MethodPost, "http://"+s.whoami1IP+"/health", bytes.NewBuffer([]byte("200"))) @@ -206,5 +204,4 @@ func (s *HealthCheckSuite) TestPortOverload(c *check.C) { // Verify no backend service is available due to failing health checks err = try.Request(frontendHealthReq, 3*time.Second, try.StatusCodeIs(http.StatusServiceUnavailable)) c.Assert(err, checker.IsNil) - } diff --git a/integration/simple_test.go b/integration/simple_test.go index 55075163a..49c35d13f 100644 --- a/integration/simple_test.go +++ b/integration/simple_test.go @@ -193,7 +193,6 @@ func (s *SimpleSuite) TestStatsWithMultipleEntryPoint(c *check.C) { err = try.GetRequest("http://127.0.0.1:8080/health", 1*time.Second, try.BodyContains(`"total_status_code_count":{"200":2}`)) c.Assert(err, checker.IsNil) - } func (s *SimpleSuite) TestNoAuthOnPing(c *check.C) { @@ -301,7 +300,6 @@ func (s *SimpleSuite) TestMultipleProviderSameBackendName(c *check.C) { err = try.GetRequest("http://127.0.0.1:8000/file", 1*time.Second, try.BodyContains(ipWhoami02)) c.Assert(err, checker.IsNil) - } func (s *SimpleSuite) TestIPStrategyWhitelist(c *check.C) { @@ -449,7 +447,6 @@ func (s *SimpleSuite) TestMultiProvider(c *check.C) { err = try.GetRequest("http://127.0.0.1:8000/", 1*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("CustomValue")) c.Assert(err, checker.IsNil) - } func (s *SimpleSuite) TestSimpleConfigurationHostRequestTrailingPeriod(c *check.C) { @@ -625,8 +622,8 @@ func (s *SimpleSuite) TestWRRSticky(c *check.C) { repartition := map[string]int{} req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/whoami", nil) c.Assert(err, checker.IsNil) - for i := 0; i < 4; i++ { + for i := 0; i < 4; i++ { response, err := http.DefaultClient.Do(req) c.Assert(err, checker.IsNil) c.Assert(response.StatusCode, checker.Equals, http.StatusOK) diff --git a/integration/tcp_test.go b/integration/tcp_test.go index ba49b3fdb..75015df95 100644 --- a/integration/tcp_test.go +++ b/integration/tcp_test.go @@ -230,7 +230,6 @@ func guessWhoTLSMaxVersion(addr, serverName string, tlsCall bool, tlsMaxVersion var err error if tlsCall { - conn, err = tls.Dial("tcp", addr, &tls.Config{ ServerName: serverName, InsecureSkipVerify: true, diff --git a/integration/tracing_test.go b/integration/tracing_test.go index 0dbf009c5..07b1d3438 100644 --- a/integration/tracing_test.go +++ b/integration/tracing_test.go @@ -88,7 +88,6 @@ func (s *TracingSuite) TestZipkinRateLimit(c *check.C) { err = try.GetRequest("http://"+s.IP+":9411/api/v2/spans?serviceName=tracing", 20*time.Second, try.BodyContains("forward service1/router1@file", "ratelimit-1@file")) c.Assert(err, checker.IsNil) - } func (s *TracingSuite) TestZipkinRetry(c *check.C) { diff --git a/integration/websocket_test.go b/integration/websocket_test.go index e2c834cd4..99b0a77e5 100644 --- a/integration/websocket_test.go +++ b/integration/websocket_test.go @@ -177,7 +177,6 @@ func (s *WebsocketSuite) TestOrigin(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(n, checker.Equals, 2) c.Assert(string(msg), checker.Equals, "OK") - } func (s *WebsocketSuite) TestWrongOriginIgnoredByServer(c *check.C) { @@ -238,7 +237,6 @@ func (s *WebsocketSuite) TestWrongOriginIgnoredByServer(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(n, checker.Equals, 2) c.Assert(string(msg), checker.Equals, "OK") - } func (s *WebsocketSuite) TestSSLTermination(c *check.C) { @@ -389,7 +387,6 @@ func (s *WebsocketSuite) TestSpecificResponseFromBackend(c *check.C) { _, resp, err := gorillawebsocket.DefaultDialer.Dial("ws://127.0.0.1:8000/ws", nil) c.Assert(err, checker.NotNil) c.Assert(resp.StatusCode, check.Equals, http.StatusUnauthorized) - } func (s *WebsocketSuite) TestURLWithURLEncodedChar(c *check.C) { diff --git a/pkg/api/handler_http_test.go b/pkg/api/handler_http_test.go index 38286151f..b27d80d83 100644 --- a/pkg/api/handler_http_test.go +++ b/pkg/api/handler_http_test.go @@ -18,6 +18,8 @@ import ( "github.com/stretchr/testify/require" ) +func Bool(v bool) *bool { return &v } + func TestHandler_HTTP(t *testing.T) { type expected struct { statusCode int @@ -267,6 +269,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.1", @@ -283,6 +286,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.2", @@ -351,6 +355,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.1", @@ -367,6 +372,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.2", @@ -383,6 +389,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.3", @@ -412,6 +419,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.1", @@ -429,6 +437,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.2", @@ -459,6 +468,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.1", @@ -476,6 +486,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.2", @@ -506,6 +517,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.1", @@ -534,6 +546,7 @@ func TestHandler_HTTP(t *testing.T) { si := &runtime.ServiceInfo{ Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.1", diff --git a/pkg/api/handler_test.go b/pkg/api/handler_test.go index 3fe6d3649..972ebffa5 100644 --- a/pkg/api/handler_test.go +++ b/pkg/api/handler_test.go @@ -38,6 +38,7 @@ func TestHandler_RawData(t *testing.T) { "foo-service@myprovider": { Service: &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://127.0.0.1", diff --git a/pkg/api/testdata/getrawdata.json b/pkg/api/testdata/getrawdata.json index 7e1de0bbb..8ecf48483 100644 --- a/pkg/api/testdata/getrawdata.json +++ b/pkg/api/testdata/getrawdata.json @@ -65,7 +65,7 @@ "url": "http://127.0.0.1" } ], - "passHostHeader": false + "passHostHeader": true }, "status": "enabled", "usedBy": [ diff --git a/pkg/api/testdata/service-bar.json b/pkg/api/testdata/service-bar.json index 11e832136..e8370d9be 100644 --- a/pkg/api/testdata/service-bar.json +++ b/pkg/api/testdata/service-bar.json @@ -1,6 +1,6 @@ { "loadBalancer": { - "passHostHeader": false, + "passHostHeader": true, "servers": [ { "url": "http://127.0.0.1" diff --git a/pkg/api/testdata/services-filtered-search.json b/pkg/api/testdata/services-filtered-search.json index fd854ed72..27178e328 100644 --- a/pkg/api/testdata/services-filtered-search.json +++ b/pkg/api/testdata/services-filtered-search.json @@ -1,7 +1,7 @@ [ { "loadBalancer": { - "passHostHeader": false, + "passHostHeader": true, "servers": [ { "url": "http://127.0.0.2" diff --git a/pkg/api/testdata/services-filtered-status.json b/pkg/api/testdata/services-filtered-status.json index df1a52dcb..76d374b44 100644 --- a/pkg/api/testdata/services-filtered-status.json +++ b/pkg/api/testdata/services-filtered-status.json @@ -1,7 +1,7 @@ [ { "loadBalancer": { - "passHostHeader": false, + "passHostHeader": true, "servers": [ { "url": "http://127.0.0.1" diff --git a/pkg/api/testdata/services-page2.json b/pkg/api/testdata/services-page2.json index 9b8b5ce72..df65b3640 100644 --- a/pkg/api/testdata/services-page2.json +++ b/pkg/api/testdata/services-page2.json @@ -1,7 +1,7 @@ [ { "loadBalancer": { - "passHostHeader": false, + "passHostHeader": true, "servers": [ { "url": "http://127.0.0.2" diff --git a/pkg/api/testdata/services.json b/pkg/api/testdata/services.json index e96abc23b..856441e9b 100644 --- a/pkg/api/testdata/services.json +++ b/pkg/api/testdata/services.json @@ -1,7 +1,7 @@ [ { "loadBalancer": { - "passHostHeader": false, + "passHostHeader": true, "servers": [ { "url": "http://127.0.0.1" @@ -22,7 +22,7 @@ }, { "loadBalancer": { - "passHostHeader": false, + "passHostHeader": true, "servers": [ { "url": "http://127.0.0.2" diff --git a/pkg/cli/commands_test.go b/pkg/cli/commands_test.go index 3796369ea..a74a1d54a 100644 --- a/pkg/cli/commands_test.go +++ b/pkg/cli/commands_test.go @@ -82,7 +82,6 @@ func Test_execute(t *testing.T) { return nil }, } - }, expected: expected{result: "root"}, }, @@ -99,7 +98,6 @@ func Test_execute(t *testing.T) { return nil }, } - }, expected: expected{error: true}, }, diff --git a/pkg/cli/file_finder_test.go b/pkg/cli/file_finder_test.go index 53acfe382..c0b8971c1 100644 --- a/pkg/cli/file_finder_test.go +++ b/pkg/cli/file_finder_test.go @@ -85,7 +85,6 @@ func TestFinder_Find(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { - finder := Finder{ BasePaths: test.basePaths, Extensions: []string{"toml", "yaml", "yml"}, diff --git a/pkg/config/dynamic/http_config.go b/pkg/config/dynamic/http_config.go index ab56419bd..c98e10697 100644 --- a/pkg/config/dynamic/http_config.go +++ b/pkg/config/dynamic/http_config.go @@ -106,7 +106,7 @@ type ServersLoadBalancer struct { Sticky *Sticky `json:"sticky,omitempty" toml:"sticky,omitempty" yaml:"sticky,omitempty" label:"allowEmpty"` Servers []Server `json:"servers,omitempty" toml:"servers,omitempty" yaml:"servers,omitempty" label-slice-as-struct:"server"` HealthCheck *HealthCheck `json:"healthCheck,omitempty" toml:"healthCheck,omitempty" yaml:"healthCheck,omitempty"` - PassHostHeader bool `json:"passHostHeader" toml:"passHostHeader" yaml:"passHostHeader"` + PassHostHeader *bool `json:"passHostHeader" toml:"passHostHeader" yaml:"passHostHeader"` ResponseForwarding *ResponseForwarding `json:"responseForwarding,omitempty" toml:"responseForwarding,omitempty" yaml:"responseForwarding,omitempty"` } @@ -129,7 +129,8 @@ func (l *ServersLoadBalancer) Mergeable(loadBalancer *ServersLoadBalancer) bool // SetDefaults Default values for a ServersLoadBalancer. func (l *ServersLoadBalancer) SetDefaults() { - l.PassHostHeader = true + defaultPassHostHeader := true + l.PassHostHeader = &defaultPassHostHeader } // +k8s:deepcopy-gen=true diff --git a/pkg/config/dynamic/middlewares.go b/pkg/config/dynamic/middlewares.go index b8fb8df27..a627ce621 100644 --- a/pkg/config/dynamic/middlewares.go +++ b/pkg/config/dynamic/middlewares.go @@ -460,7 +460,6 @@ func (c *ClientTLS) CreateTLSConfig() (*tls.Config, error) { cert, err = tls.X509KeyPair([]byte(c.Cert), []byte(c.Key)) if err != nil { return nil, fmt.Errorf("failed to load TLS keypair: %v", err) - } } else { return nil, fmt.Errorf("TLS key is a file, but tls cert is not") diff --git a/pkg/config/file/raw_node.go b/pkg/config/file/raw_node.go index 135e9cd68..8b5509ad5 100644 --- a/pkg/config/file/raw_node.go +++ b/pkg/config/file/raw_node.go @@ -1,6 +1,7 @@ package file import ( + "fmt" "reflect" "sort" "strconv" @@ -15,12 +16,15 @@ func decodeRawToNode(data map[string]interface{}, rootName string, filters ...st } vData := reflect.ValueOf(data) - decodeRaw(root, vData, filters...) + err := decodeRaw(root, vData, filters...) + if err != nil { + return nil, err + } return root, nil } -func decodeRaw(node *parser.Node, vData reflect.Value, filters ...string) { +func decodeRaw(node *parser.Node, vData reflect.Value, filters ...string) error { sortedKeys := sortKeys(vData, filters) for _, key := range sortedKeys { @@ -38,7 +42,11 @@ func decodeRaw(node *parser.Node, vData reflect.Value, filters ...string) { case reflect.Bool: fallthrough case reflect.String: - child.Value = getSimpleValue(value) + value, err := getSimpleValue(value) + if err != nil { + return err + } + child.Value = value case reflect.Slice: var values []string @@ -63,40 +71,52 @@ func decodeRaw(node *parser.Node, vData reflect.Value, filters ...string) { } child.Children = append(child.Children, ch) - decodeRaw(ch, sValue) + err := decodeRaw(ch, sValue) + if err != nil { + return err + } } else { - values = append(values, getSimpleValue(sValue)) + val, err := getSimpleValue(sValue) + if err != nil { + return err + } + values = append(values, val) } default: - panic("Unsupported slice type: " + item.Kind().String()) + return fmt.Errorf("field %s uses unsupported slice type: %s", child.Name, item.Kind().String()) } } child.Value = strings.Join(values, ",") case reflect.Map: - decodeRaw(child, value) + err := decodeRaw(child, value) + if err != nil { + return err + } default: - panic("Unsupported type: " + value.Kind().String()) + return fmt.Errorf("field %s uses unsupported type: %s", child.Name, value.Kind().String()) } node.Children = append(node.Children, child) } + + return nil } -func getSimpleValue(item reflect.Value) string { +func getSimpleValue(item reflect.Value) (string, error) { switch item.Kind() { case reflect.String: - return item.String() + return item.String(), nil case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return strconv.FormatInt(item.Int(), 10) + return strconv.FormatInt(item.Int(), 10), nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return strconv.FormatUint(item.Uint(), 10) + return strconv.FormatUint(item.Uint(), 10), nil case reflect.Float32, reflect.Float64: - return strings.TrimSuffix(strconv.FormatFloat(item.Float(), 'f', 6, 64), ".000000") + return strings.TrimSuffix(strconv.FormatFloat(item.Float(), 'f', 6, 64), ".000000"), nil case reflect.Bool: - return strconv.FormatBool(item.Bool()) + return strconv.FormatBool(item.Bool()), nil default: - panic("Unsupported Simple value type: " + item.Kind().String()) + return "", fmt.Errorf("unsupported simple value type: %s", item.Kind().String()) } } diff --git a/pkg/config/file/raw_node_test.go b/pkg/config/file/raw_node_test.go index cd57c74bd..5b4ae64ae 100644 --- a/pkg/config/file/raw_node_test.go +++ b/pkg/config/file/raw_node_test.go @@ -538,3 +538,27 @@ func Test_decodeRawToNode(t *testing.T) { }) } } + +func Test_decodeRawToNode_errors(t *testing.T) { + testCases := []struct { + desc string + data map[string]interface{} + }{ + { + desc: "invalid type", + data: map[string]interface{}{ + "foo": struct{}{}, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + _, err := decodeRawToNode(test.data, parser.DefaultRootName) + require.Error(t, err) + }) + } +} diff --git a/pkg/config/label/label_test.go b/pkg/config/label/label_test.go index a88cb588d..63ac2f48f 100644 --- a/pkg/config/label/label_test.go +++ b/pkg/config/label/label_test.go @@ -544,7 +544,7 @@ func TestDecodeConfiguration(t *testing.T) { "name1": "foobar", }, }, - PassHostHeader: true, + PassHostHeader: func(v bool) *bool { return &v }(true), ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: "foobar", }, @@ -570,7 +570,7 @@ func TestDecodeConfiguration(t *testing.T) { "name1": "foobar", }, }, - PassHostHeader: true, + PassHostHeader: func(v bool) *bool { return &v }(true), ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: "foobar", }, @@ -946,7 +946,7 @@ func TestEncodeConfiguration(t *testing.T) { "name1": "foobar", }, }, - PassHostHeader: true, + PassHostHeader: func(v bool) *bool { return &v }(true), ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: "foobar", }, @@ -972,7 +972,7 @@ func TestEncodeConfiguration(t *testing.T) { "name1": "foobar", }, }, - PassHostHeader: true, + PassHostHeader: func(v bool) *bool { return &v }(true), ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: "foobar", }, diff --git a/pkg/config/parser/nodes_metadata.go b/pkg/config/parser/nodes_metadata.go index 170145caf..3ee3d0982 100644 --- a/pkg/config/parser/nodes_metadata.go +++ b/pkg/config/parser/nodes_metadata.go @@ -130,7 +130,6 @@ func findTypedField(rType reflect.Type, node *Node) (reflect.StructField, error) return cField, nil } } - } return reflect.StructField{}, fmt.Errorf("field not found, node: %s", node.Name) diff --git a/pkg/config/runtime/runtime_test.go b/pkg/config/runtime/runtime_test.go index 5ff0a97d6..1cdce84a6 100644 --- a/pkg/config/runtime/runtime_test.go +++ b/pkg/config/runtime/runtime_test.go @@ -687,5 +687,4 @@ func TestPopulateUsedBy(t *testing.T) { } }) } - } diff --git a/pkg/config/static/entrypoints.go b/pkg/config/static/entrypoints.go index 544bb8386..ff3088ad3 100644 --- a/pkg/config/static/entrypoints.go +++ b/pkg/config/static/entrypoints.go @@ -32,8 +32,8 @@ type EntryPoints map[string]*EntryPoint // EntryPointsTransport configures communication between clients and Traefik. type EntryPointsTransport struct { - LifeCycle *LifeCycle `description:"Timeouts influencing the server life cycle." json:"lifeCycle,omitempty" toml:"lifeCycle,omitempty" yaml:"lifeCycle,omitempty" export:"true" export:"true"` - RespondingTimeouts *RespondingTimeouts `description:"Timeouts for incoming requests to the Traefik instance." json:"respondingTimeouts,omitempty" toml:"respondingTimeouts,omitempty" yaml:"respondingTimeouts,omitempty" export:"true" export:"true"` + LifeCycle *LifeCycle `description:"Timeouts influencing the server life cycle." json:"lifeCycle,omitempty" toml:"lifeCycle,omitempty" yaml:"lifeCycle,omitempty" export:"true"` + RespondingTimeouts *RespondingTimeouts `description:"Timeouts for incoming requests to the Traefik instance." json:"respondingTimeouts,omitempty" toml:"respondingTimeouts,omitempty" yaml:"respondingTimeouts,omitempty" export:"true"` } // SetDefaults sets the default values. diff --git a/pkg/job/job_test.go b/pkg/job/job_test.go index 5e3c488e6..60e4086cb 100644 --- a/pkg/job/job_test.go +++ b/pkg/job/job_test.go @@ -33,13 +33,14 @@ func TestJobBackOff(t *testing.T) { // Assert that the next backoff falls in the expected range. var minInterval = expected - time.Duration(testRandomizationFactor*float64(expected)) var maxInterval = expected + time.Duration(testRandomizationFactor*float64(expected)) + if i < 3 || i == 8 { time.Sleep(2 * time.Second) } + var actualInterval = exp.NextBackOff() if !(minInterval <= actualInterval && actualInterval <= maxInterval) { t.Error("error") } - // assertEquals(t, expected, exp.currentInterval) } } diff --git a/pkg/log/log_test.go b/pkg/log/log_test.go index e4ce53221..c81724ff3 100644 --- a/pkg/log/log_test.go +++ b/pkg/log/log_test.go @@ -40,7 +40,6 @@ func TestLog(t *testing.T) { for _, test := range testCases { test := test t.Run(test.desc, func(t *testing.T) { - var buffer bytes.Buffer SetOutput(&buffer) diff --git a/pkg/metrics/influxdb_test.go b/pkg/metrics/influxdb_test.go index 10df13633..7ebc09997 100644 --- a/pkg/metrics/influxdb_test.go +++ b/pkg/metrics/influxdb_test.go @@ -60,7 +60,6 @@ func TestInfluxDB(t *testing.T) { influxDBRegistry.EntryPointReqsCounter().With("entrypoint", "test").Add(1) influxDBRegistry.EntryPointReqDurationHistogram().With("entrypoint", "test").Observe(10000) influxDBRegistry.EntryPointOpenConnsGauge().With("entrypoint", "test").Set(1) - }) assertMessage(t, msgEntrypoint, expectedEntrypoint) diff --git a/pkg/metrics/prometheus_test.go b/pkg/metrics/prometheus_test.go index 7c0c5ed02..13eb3e874 100644 --- a/pkg/metrics/prometheus_test.go +++ b/pkg/metrics/prometheus_test.go @@ -269,7 +269,6 @@ func TestPrometheus(t *testing.T) { } test.assert(family) }) - } } diff --git a/pkg/middlewares/accesslog/field_middleware.go b/pkg/middlewares/accesslog/field_middleware.go index f5007a1ca..19b455939 100644 --- a/pkg/middlewares/accesslog/field_middleware.go +++ b/pkg/middlewares/accesslog/field_middleware.go @@ -45,7 +45,6 @@ func AddServiceFields(rw http.ResponseWriter, req *http.Request, next http.Handl data.Core[ServiceAddr] = req.URL.Host next.ServeHTTP(rw, req) - } // AddOriginFields add origin fields diff --git a/pkg/middlewares/accesslog/logger_formatters.go b/pkg/middlewares/accesslog/logger_formatters.go index 554e709b3..5abb996d7 100644 --- a/pkg/middlewares/accesslog/logger_formatters.go +++ b/pkg/middlewares/accesslog/logger_formatters.go @@ -69,8 +69,8 @@ func toLog(fields logrus.Fields, key string, defaultValue string, quoted bool) i return v } } - return defaultValue + return defaultValue } func toLogEntry(s string, defaultValue string, quote bool) string { diff --git a/pkg/middlewares/accesslog/logger_formatters_test.go b/pkg/middlewares/accesslog/logger_formatters_test.go index 4817c26d9..ce3c6aec5 100644 --- a/pkg/middlewares/accesslog/logger_formatters_test.go +++ b/pkg/middlewares/accesslog/logger_formatters_test.go @@ -99,11 +99,9 @@ func TestCommonLogFormatter_Format(t *testing.T) { assert.Equal(t, test.expectedLog, string(raw)) }) } - } func Test_toLog(t *testing.T) { - testCases := []struct { desc string fields logrus.Fields diff --git a/pkg/middlewares/accesslog/logger_test.go b/pkg/middlewares/accesslog/logger_test.go index f133ae530..b93d8fdcd 100644 --- a/pkg/middlewares/accesslog/logger_test.go +++ b/pkg/middlewares/accesslog/logger_test.go @@ -527,7 +527,6 @@ func TestNewLogHandlerOutputStdout(t *testing.T) { for _, test := range testCases { test := test t.Run(test.desc, func(t *testing.T) { - // NOTE: It is not possible to run these cases in parallel because we capture Stdout file, restoreStdout := captureStdout(t) @@ -543,7 +542,6 @@ func TestNewLogHandlerOutputStdout(t *testing.T) { } func assertValidLogData(t *testing.T, expected string, logData []byte) { - if len(expected) == 0 { assert.Zero(t, len(logData)) t.Log(string(logData)) diff --git a/pkg/middlewares/auth/forward_test.go b/pkg/middlewares/auth/forward_test.go index a816fb813..20dfa6608 100644 --- a/pkg/middlewares/auth/forward_test.go +++ b/pkg/middlewares/auth/forward_test.go @@ -367,7 +367,6 @@ func Test_writeHeader(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - req := testhelpers.MustNewRequest(http.MethodGet, "http://foo.bar/path?q=1", nil) for key, value := range test.headers { req.Header.Set(key, value) diff --git a/pkg/middlewares/headers/headers_test.go b/pkg/middlewares/headers/headers_test.go index 592be7a02..21df2deff 100644 --- a/pkg/middlewares/headers/headers_test.go +++ b/pkg/middlewares/headers/headers_test.go @@ -327,7 +327,6 @@ func TestGetTracingInformation(t *testing.T) { assert.Equal(t, "testing", name) assert.Equal(t, tracing.SpanKindNoneEnum, trace) - } func TestCORSResponses(t *testing.T) { diff --git a/pkg/middlewares/metrics/recorder.go b/pkg/middlewares/metrics/recorder.go index 7e6991d47..7ada2d988 100644 --- a/pkg/middlewares/metrics/recorder.go +++ b/pkg/middlewares/metrics/recorder.go @@ -33,5 +33,7 @@ func (r *responseRecorder) CloseNotify() <-chan bool { // Flush sends any buffered data to the client. func (r *responseRecorder) Flush() { - r.ResponseWriter.(http.Flusher).Flush() + if f, ok := r.ResponseWriter.(http.Flusher); ok { + f.Flush() + } } diff --git a/pkg/middlewares/passtlsclientcert/pass_tls_client_cert_test.go b/pkg/middlewares/passtlsclientcert/pass_tls_client_cert_test.go index 5ba15c535..8bf5b2e50 100644 --- a/pkg/middlewares/passtlsclientcert/pass_tls_client_cert_test.go +++ b/pkg/middlewares/passtlsclientcert/pass_tls_client_cert_test.go @@ -360,7 +360,6 @@ WqeUSNGYV//RunTeuRDAf5OxehERb1srzBXhRZ3cZdzXbgR/`), require.Equal(t, test.expected, sanitize(test.toSanitize), "The sanitized certificates should be equal") }) } - } func TestTLSClientHeadersWithPEM(t *testing.T) { @@ -429,7 +428,6 @@ func TestTLSClientHeadersWithPEM(t *testing.T) { require.Empty(t, res.Header().Get(xForwardedTLSClientCert), "The response header should be always empty") }) } - } func TestGetSans(t *testing.T) { @@ -478,7 +476,6 @@ func TestGetSans(t *testing.T) { } }) } - } func TestTLSClientHeadersWithCertInfo(t *testing.T) { @@ -659,5 +656,4 @@ func TestTLSClientHeadersWithCertInfo(t *testing.T) { require.Empty(t, res.Header().Get(xForwardedTLSClientCertInfo), "The response header should be always empty") }) } - } diff --git a/pkg/middlewares/pipelining/pipelining.go b/pkg/middlewares/pipelining/pipelining.go index a4e14110a..4124b552f 100644 --- a/pkg/middlewares/pipelining/pipelining.go +++ b/pkg/middlewares/pipelining/pipelining.go @@ -35,7 +35,6 @@ func (p *pipelining) ServeHTTP(rw http.ResponseWriter, r *http.Request) { } else { p.next.ServeHTTP(&writerWithoutCloseNotify{rw}, r) } - } // writerWithoutCloseNotify helps to disable closeNotify diff --git a/pkg/middlewares/ratelimiter/rate_limiter_test.go b/pkg/middlewares/ratelimiter/rate_limiter_test.go index ad4474870..7136d7ca0 100644 --- a/pkg/middlewares/ratelimiter/rate_limiter_test.go +++ b/pkg/middlewares/ratelimiter/rate_limiter_test.go @@ -142,7 +142,6 @@ func TestRateLimit(t *testing.T) { for _, test := range testCases { test := test t.Run(test.desc, func(t *testing.T) { - t.Parallel() reqCount := 0 diff --git a/pkg/middlewares/redirect/redirect_regex_test.go b/pkg/middlewares/redirect/redirect_regex_test.go index 9a3882003..ca4edbb79 100644 --- a/pkg/middlewares/redirect/redirect_regex_test.go +++ b/pkg/middlewares/redirect/redirect_regex_test.go @@ -179,16 +179,13 @@ func TestRedirectRegexHandler(t *testing.T) { handler.ServeHTTP(recorder, r) assert.Equal(t, test.expectedStatus, recorder.Code) - if test.expectedStatus == http.StatusMovedPermanently || - test.expectedStatus == http.StatusFound || - test.expectedStatus == http.StatusTemporaryRedirect || - test.expectedStatus == http.StatusPermanentRedirect { - + switch test.expectedStatus { + case http.StatusMovedPermanently, http.StatusFound, http.StatusTemporaryRedirect, http.StatusPermanentRedirect: location, err := recorder.Result().Location() require.NoError(t, err) assert.Equal(t, test.expectedURL, location.String()) - } else { + default: location, err := recorder.Result().Location() require.Errorf(t, err, "Location %v", location) } diff --git a/pkg/middlewares/redirect/redirect_scheme_test.go b/pkg/middlewares/redirect/redirect_scheme_test.go index 7000912db..384780d53 100644 --- a/pkg/middlewares/redirect/redirect_scheme_test.go +++ b/pkg/middlewares/redirect/redirect_scheme_test.go @@ -206,16 +206,14 @@ func TestRedirectSchemeHandler(t *testing.T) { handler.ServeHTTP(recorder, r) assert.Equal(t, test.expectedStatus, recorder.Code) - if test.expectedStatus == http.StatusMovedPermanently || - test.expectedStatus == http.StatusFound || - test.expectedStatus == http.StatusTemporaryRedirect || - test.expectedStatus == http.StatusPermanentRedirect { + switch test.expectedStatus { + case http.StatusMovedPermanently, http.StatusFound, http.StatusTemporaryRedirect, http.StatusPermanentRedirect: location, err := recorder.Result().Location() require.NoError(t, err) assert.Equal(t, test.expectedURL, location.String()) - } else { + default: location, err := recorder.Result().Location() require.Errorf(t, err, "Location %v", location) } @@ -234,7 +232,6 @@ func TestRedirectSchemeHandler(t *testing.T) { test.expectedStatus == http.StatusFound || test.expectedStatus == http.StatusTemporaryRedirect || test.expectedStatus == http.StatusPermanentRedirect { - location, err := recorder.Result().Location() require.NoError(t, err) diff --git a/pkg/middlewares/replacepath/replace_path_test.go b/pkg/middlewares/replacepath/replace_path_test.go index ca9e03e81..65824dcde 100644 --- a/pkg/middlewares/replacepath/replace_path_test.go +++ b/pkg/middlewares/replacepath/replace_path_test.go @@ -23,7 +23,6 @@ func TestReplacePath(t *testing.T) { for _, path := range paths { t.Run(path, func(t *testing.T) { - var expectedPath, actualHeader, requestURI string next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { expectedPath = r.URL.Path diff --git a/pkg/middlewares/replacepathregex/replace_path_regex_test.go b/pkg/middlewares/replacepathregex/replace_path_regex_test.go index d865a5cc2..8215df968 100644 --- a/pkg/middlewares/replacepathregex/replace_path_regex_test.go +++ b/pkg/middlewares/replacepathregex/replace_path_regex_test.go @@ -74,7 +74,6 @@ func TestReplacePathRegex(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { - var actualPath, actualHeader, requestURI string next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { actualPath = r.URL.Path diff --git a/pkg/middlewares/tracing/entrypoint_test.go b/pkg/middlewares/tracing/entrypoint_test.go index 2fe090448..79bd89db6 100644 --- a/pkg/middlewares/tracing/entrypoint_test.go +++ b/pkg/middlewares/tracing/entrypoint_test.go @@ -65,7 +65,6 @@ func TestEntryPointMiddleware(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { - newTracing, err := tracing.NewTracing("", test.spanNameLimit, test.tracing) require.NoError(t, err) diff --git a/pkg/middlewares/tracing/forwarder_test.go b/pkg/middlewares/tracing/forwarder_test.go index 7bf911aa0..073df8ad4 100644 --- a/pkg/middlewares/tracing/forwarder_test.go +++ b/pkg/middlewares/tracing/forwarder_test.go @@ -109,7 +109,6 @@ func TestNewForwarder(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { - newTracing, err := tracing.NewTracing("", test.spanNameLimit, test.tracing) require.NoError(t, err) diff --git a/pkg/provider/acme/local_store.go b/pkg/provider/acme/local_store.go index e0786911b..0b76064e3 100644 --- a/pkg/provider/acme/local_store.go +++ b/pkg/provider/acme/local_store.go @@ -171,7 +171,6 @@ func NewLocalChallengeStore() *LocalChallengeStore { TLSChallenges: make(map[string]*Certificate), }, } - } // GetHTTPChallengeToken Get the http challenge token from the store diff --git a/pkg/provider/acme/provider.go b/pkg/provider/acme/provider.go index ecf28a363..300a81899 100644 --- a/pkg/provider/acme/provider.go +++ b/pkg/provider/acme/provider.go @@ -414,7 +414,6 @@ func (p *Provider) watchNewDomains(ctx context.Context) { } p.resolveDomains(ctxRouter, domains, tlsStore) } - } case <-stop: return diff --git a/pkg/provider/docker/config.go b/pkg/provider/docker/config.go index b0aeb4c5f..b2385a7e6 100644 --- a/pkg/provider/docker/config.go +++ b/pkg/provider/docker/config.go @@ -331,5 +331,5 @@ func getServiceName(container dockerData) string { serviceName = values[labelDockerComposeService] + "_" + values[labelDockerComposeProject] } - return serviceName + return provider.Normalize(serviceName) } diff --git a/pkg/provider/docker/config_test.go b/pkg/provider/docker/config_test.go index dcaa20d4a..1788757fe 100644 --- a/pkg/provider/docker/config_test.go +++ b/pkg/provider/docker/config_test.go @@ -13,7 +13,8 @@ import ( "github.com/stretchr/testify/require" ) -func Int(v int) *int { return &v } +func Int(v int) *int { return &v } +func Bool(v bool) *bool { return &v } func TestDefaultRule(t *testing.T) { testCases := []struct { @@ -64,7 +65,7 @@ func TestDefaultRule(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -113,7 +114,7 @@ func TestDefaultRule(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -164,7 +165,7 @@ func TestDefaultRule(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -208,7 +209,7 @@ func TestDefaultRule(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -252,7 +253,7 @@ func TestDefaultRule(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -301,7 +302,7 @@ func TestDefaultRule(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -384,7 +385,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -452,7 +453,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "Test2": { @@ -462,7 +463,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -531,7 +532,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -581,7 +582,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -633,7 +634,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -677,7 +678,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -734,7 +735,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -781,7 +782,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "Service2": { @@ -791,7 +792,58 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), + }, + }, + }, + }, + }, + }, + { + desc: "one router, one specified but undefined service -> specified one is assigned, but automatic is created instead", + containers: []dockerData{ + { + ServiceName: "Test", + Name: "Test", + Labels: map[string]string{ + "traefik.http.routers.Router1.rule": "Host(`foo.com`)", + "traefik.http.routers.Router1.service": "Service1", + }, + NetworkSettings: networkSettings{ + Ports: nat.PortMap{ + nat.Port("80/tcp"): []nat.PortBinding{}, + }, + Networks: map[string]*networkData{ + "bridge": { + Name: "bridge", + Addr: "127.0.0.1", + }, + }, + }, + }, + }, + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Services: map[string]*dynamic.TCPService{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "Router1": { + Service: "Service1", + Rule: "Host(`foo.com`)", + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "Test": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "http://127.0.0.1:80", + }, + }, + PassHostHeader: Bool(true), }, }, }, @@ -1001,7 +1053,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1050,7 +1102,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1142,7 +1194,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1215,7 +1267,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1310,7 +1362,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.3:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1378,7 +1430,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1468,7 +1520,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.3:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1541,7 +1593,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1604,7 +1656,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "Test2": { @@ -1614,7 +1666,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1664,7 +1716,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1715,7 +1767,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "h2c://127.0.0.1:8080", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1761,7 +1813,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "Service2": { @@ -1771,7 +1823,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:8080", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1986,7 +2038,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -2047,7 +2099,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -2297,7 +2349,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, diff --git a/pkg/provider/docker/docker.go b/pkg/provider/docker/docker.go index 9d3d4c038..534ee47c7 100644 --- a/pkg/provider/docker/docker.go +++ b/pkg/provider/docker/docker.go @@ -142,7 +142,12 @@ func (p *Provider) createClient() (client.APIClient, error) { apiVersion = SwarmAPIVersion } - return client.NewClient(p.Endpoint, apiVersion, httpClient, httpHeaders) + return client.NewClientWithOpts( + client.WithHost(p.Endpoint), + client.WithVersion(apiVersion), + client.WithHTTPClient(httpClient), + client.WithHTTPHeaders(httpHeaders), + ) } // Provide allows the docker provider to provide configurations to traefik using the given configuration channel. @@ -193,10 +198,11 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe. if p.Watch { if p.SwarmMode { errChan := make(chan error) + // TODO: This need to be change. Linked to Swarm events docker/docker#23827 ticker := time.NewTicker(time.Duration(p.SwarmModeRefreshSeconds)) - pool.GoCtx(func(ctx context.Context) { + pool.GoCtx(func(ctx context.Context) { ctx = log.With(ctx, log.Str(log.ProviderName, "docker")) logger := log.FromContext(ctx) @@ -229,7 +235,6 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe. return err } // channel closed - } else { f := filters.NewArgs() f.Add("type", "container") @@ -256,7 +261,6 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe. case configurationChan <- message: case <-ctx.Done(): } - } } diff --git a/pkg/provider/file/file.go b/pkg/provider/file/file.go index 667be1205..f8125349d 100644 --- a/pkg/provider/file/file.go +++ b/pkg/provider/file/file.go @@ -28,9 +28,9 @@ var _ provider.Provider = (*Provider)(nil) // Provider holds configurations of the provider. type Provider struct { - Directory string `description:"Load configuration from one or more .toml files in a directory." json:"directory,omitempty" toml:"directory,omitempty" yaml:"directory,omitempty" export:"true"` + Directory string `description:"Load dynamic configuration from one or more .toml or .yml files in a directory." json:"directory,omitempty" toml:"directory,omitempty" yaml:"directory,omitempty" export:"true"` Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"` - Filename string `description:"Override default configuration template. For advanced users :)" json:"filename,omitempty" toml:"filename,omitempty" yaml:"filename,omitempty" export:"true"` + Filename string `description:"Load dynamic configuration from a file." json:"filename,omitempty" toml:"filename,omitempty" yaml:"filename,omitempty" export:"true"` DebugLogGeneratedTemplate bool `description:"Enable debug logging of generated configuration template." json:"debugLogGeneratedTemplate,omitempty" toml:"debugLogGeneratedTemplate,omitempty" yaml:"debugLogGeneratedTemplate,omitempty" export:"true"` } diff --git a/pkg/provider/file/file_test.go b/pkg/provider/file/file_test.go index f4892823f..eef8452b3 100644 --- a/pkg/provider/file/file_test.go +++ b/pkg/provider/file/file_test.go @@ -250,7 +250,6 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) (*Provider, } if len(test.filePath) > 0 { - var file *os.File if watch { var err error diff --git a/pkg/provider/kubernetes/crd/client.go b/pkg/provider/kubernetes/crd/client.go index fd662019d..e0f29a193 100644 --- a/pkg/provider/kubernetes/crd/client.go +++ b/pkg/provider/kubernetes/crd/client.go @@ -233,11 +233,11 @@ func (c *clientWrapper) GetMiddlewares() []*v1alpha1.Middleware { var result []*v1alpha1.Middleware for ns, factory := range c.factoriesCrd { - ings, err := factory.Traefik().V1alpha1().Middlewares().Lister().List(c.labelSelector) + middlewares, err := factory.Traefik().V1alpha1().Middlewares().Lister().List(c.labelSelector) if err != nil { - log.Errorf("Failed to list ingresses in namespace %s: %s", ns, err) + log.Errorf("Failed to list middlewares in namespace %s: %s", ns, err) } - result = append(result, ings...) + result = append(result, middlewares...) } return result diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index 9e5f843a2..7c7d59a74 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -225,7 +225,6 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) PassTLSClientCert: middleware.Spec.PassTLSClientCert, Retry: middleware.Spec.Retry, } - } return conf diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go index b6835bce1..2a6f13b13 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_http.go +++ b/pkg/provider/kubernetes/crd/kubernetes_http.go @@ -164,8 +164,11 @@ func createLoadBalancerServerHTTP(client Client, namespace string, service v1alp lb.SetDefaults() lb.Servers = servers - if service.PassHostHeader != nil { - lb.PassHostHeader = *service.PassHostHeader + + lb.PassHostHeader = service.PassHostHeader + if lb.PassHostHeader == nil { + passHostHeader := true + lb.PassHostHeader = &passHostHeader } lb.ResponseForwarding = service.ResponseForwarding diff --git a/pkg/provider/kubernetes/crd/kubernetes_tcp.go b/pkg/provider/kubernetes/crd/kubernetes_tcp.go index a5a6b74e8..1a27885d4 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_tcp.go +++ b/pkg/provider/kubernetes/crd/kubernetes_tcp.go @@ -121,9 +121,7 @@ func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client } conf.Routers[serviceName].TLS.Options = tlsOptionsName - } - } } diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 28c04d5d8..142a99576 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -12,7 +12,8 @@ import ( var _ provider.Provider = (*Provider)(nil) -func Int(v int) *int { return &v } +func Int(v int) *int { return &v } +func Bool(v bool) *bool { return &v } func TestLoadIngressRouteTCPs(t *testing.T) { testCases := []struct { @@ -737,7 +738,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -786,7 +787,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -836,7 +837,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -878,7 +879,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "default-test.route-77c62dfe9517144aeeaa": { @@ -891,7 +892,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -943,7 +944,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "default-test.route-77c62dfe9517144aeeaa-whoami2-8080": { @@ -956,7 +957,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.4:8080", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1007,7 +1008,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "default-test.route-77c62dfe9517144aeeaa-whoami2-8080": { @@ -1020,7 +1021,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.4:8080", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1132,7 +1133,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1190,7 +1191,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1248,7 +1249,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1305,7 +1306,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1351,7 +1352,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1397,7 +1398,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1435,7 +1436,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1472,7 +1473,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "https://10.10.0.6:8443", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1509,7 +1510,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "https://10.10.0.8:8443", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1584,7 +1585,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1620,7 +1621,7 @@ func TestLoadIngressRoutes(t *testing.T) { URL: "http://10.10.0.2:80", }, }, - PassHostHeader: false, + PassHostHeader: Bool(false), ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: "10s"}, }, }, diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index 51c6257bd..863711cce 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -221,7 +221,6 @@ func loadService(client Client, namespace string, backend v1beta1.IngressBackend var port int32 for _, subset := range endpoints.Subsets { - for _, p := range subset.Ports { if portName == p.Name { port = p.Port @@ -249,7 +248,7 @@ func loadService(client Client, namespace string, backend v1beta1.IngressBackend return &dynamic.Service{ LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: servers, - PassHostHeader: true, + PassHostHeader: func(v bool) *bool { return &v }(true), }, }, nil } @@ -295,7 +294,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl continue } - conf.HTTP.Routers["/"] = &dynamic.Router{ + conf.HTTP.Routers["default-router"] = &dynamic.Router{ Rule: "PathPrefix(`/`)", Priority: math.MinInt32, Service: "default-backend", @@ -352,7 +351,6 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl Service: serviceName, TLS: &dynamic.RouterTLSConfig{}, } - } conf.HTTP.Services[serviceName] = service } diff --git a/pkg/provider/kubernetes/ingress/kubernetes_test.go b/pkg/provider/kubernetes/ingress/kubernetes_test.go index bcf2b0c13..a75c4356d 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes_test.go +++ b/pkg/provider/kubernetes/ingress/kubernetes_test.go @@ -19,6 +19,8 @@ import ( var _ provider.Provider = (*Provider)(nil) +func Bool(v bool) *bool { return &v } + func TestLoadConfigurationFromIngresses(t *testing.T) { testCases := []struct { desc string @@ -51,7 +53,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", @@ -85,7 +87,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", @@ -119,7 +121,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", @@ -149,7 +151,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", @@ -178,7 +180,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-example-com-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.11.0.1:80", @@ -209,7 +211,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", @@ -243,7 +245,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", @@ -277,7 +279,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", @@ -318,7 +320,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", @@ -363,7 +365,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", @@ -376,7 +378,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, "testing-service2-8082": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.2:8080", @@ -420,7 +422,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ - "/": { + "default-router": { Rule: "PathPrefix(`/`)", Service: "default-backend", Priority: math.MinInt32, @@ -429,7 +431,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "default-backend": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", @@ -459,7 +461,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8089", @@ -489,7 +491,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-tchouk": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8089", @@ -519,7 +521,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-tchouk": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8089", @@ -553,7 +555,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-tchouk": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8089", @@ -566,7 +568,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, "testing-service1-carotte": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8090", @@ -600,7 +602,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-tchouk": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8089", @@ -613,7 +615,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, "toto-service1-tchouk": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.11.0.1:8089", @@ -665,7 +667,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-8080": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://traefik.wtf:8080", @@ -697,7 +699,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-example-com-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.11.0.1:80", @@ -734,7 +736,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-443": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "https://10.10.0.1:8443", @@ -764,7 +766,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-8443": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "https://10.10.0.1:8443", @@ -795,7 +797,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-8443": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "https://10.10.0.1:8443", @@ -817,7 +819,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { HTTP: &dynamic.HTTPConfiguration{ Middlewares: map[string]*dynamic.Middleware{}, Routers: map[string]*dynamic.Router{ - "/": { + "default-router": { Rule: "PathPrefix(`/`)", Service: "default-backend", Priority: math.MinInt32, @@ -826,7 +828,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "default-backend": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.30.0.1:8080", @@ -856,7 +858,7 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { Services: map[string]*dynamic.Service{ "testing-service1-80": { LoadBalancer: &dynamic.ServersLoadBalancer{ - PassHostHeader: true, + PassHostHeader: Bool(true), Servers: []dynamic.Server{ { URL: "http://10.10.0.1:8080", diff --git a/pkg/provider/marathon/config_test.go b/pkg/provider/marathon/config_test.go index 83c25736c..e0da93e6b 100644 --- a/pkg/provider/marathon/config_test.go +++ b/pkg/provider/marathon/config_test.go @@ -11,7 +11,8 @@ import ( "github.com/stretchr/testify/require" ) -func Int(v int) *int { return &v } +func Int(v int) *int { return &v } +func Bool(v bool) *bool { return &v } func TestGetConfigurationAPIErrors(t *testing.T) { fakeClient := newFakeClient(true, marathon.Applications{}) @@ -64,7 +65,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }}, }, }, @@ -118,7 +119,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }}, }, }, @@ -164,7 +165,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }}, }, }, @@ -211,7 +212,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:8081", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }}, }, }, @@ -266,7 +267,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:8083", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }}, }, }, @@ -308,7 +309,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:8080", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }}, "bar": {LoadBalancer: &dynamic.ServersLoadBalancer{ Servers: []dynamic.Server{ @@ -316,7 +317,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:8081", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }}, }, }, @@ -354,7 +355,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:81", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -390,7 +391,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }}, }, }, @@ -428,7 +429,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -459,7 +460,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -503,7 +504,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -537,7 +538,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "Service2": { @@ -547,7 +548,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -639,7 +640,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "app2": { @@ -649,7 +650,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -696,7 +697,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "app2": { @@ -706,7 +707,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -744,7 +745,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "app2": { @@ -754,7 +755,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -802,7 +803,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -840,7 +841,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "app2": { @@ -850,7 +851,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -887,7 +888,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -925,7 +926,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "h2c://localhost:90", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -958,7 +959,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "Service2": { @@ -968,7 +969,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:8080", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1133,7 +1134,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1171,7 +1172,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1208,7 +1209,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -1417,7 +1418,7 @@ func TestBuildConfiguration(t *testing.T) { URL: "http://localhost:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, diff --git a/pkg/provider/marathon/marathon.go b/pkg/provider/marathon/marathon.go index adef44ab4..78213f8e7 100644 --- a/pkg/provider/marathon/marathon.go +++ b/pkg/provider/marathon/marathon.go @@ -111,7 +111,6 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe. logger := log.FromContext(ctx) operation := func() error { - confg := marathon.NewDefaultConfig() confg.URL = p.Endpoint confg.EventsTransport = marathon.EventsTransportSSE diff --git a/pkg/provider/rancher/config.go b/pkg/provider/rancher/config.go index b6bfa9ad8..6efc00173 100644 --- a/pkg/provider/rancher/config.go +++ b/pkg/provider/rancher/config.go @@ -92,7 +92,6 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, service ran } func (p *Provider) buildServiceConfiguration(ctx context.Context, service rancherData, configuration *dynamic.HTTPConfiguration) error { - serviceName := service.Name if len(configuration.Services) == 0 { @@ -181,7 +180,6 @@ func (p *Provider) addServerTCP(ctx context.Context, service rancherData, loadBa loadBalancer.Servers = servers return nil - } func (p *Provider) addServers(ctx context.Context, service rancherData, loadBalancer *dynamic.ServersLoadBalancer) error { diff --git a/pkg/provider/rancher/config_test.go b/pkg/provider/rancher/config_test.go index 0e771b190..aa20e87f0 100644 --- a/pkg/provider/rancher/config_test.go +++ b/pkg/provider/rancher/config_test.go @@ -9,7 +9,8 @@ import ( "github.com/stretchr/testify/require" ) -func Int(v int) *int { return &v } +func Int(v int) *int { return &v } +func Bool(v bool) *bool { return &v } func Test_buildConfiguration(t *testing.T) { testCases := []struct { @@ -51,7 +52,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -103,7 +104,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "Test2": { @@ -113,7 +114,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -168,7 +169,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, "Test2": { @@ -178,7 +179,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://128.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -222,7 +223,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -310,7 +311,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -380,7 +381,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -433,7 +434,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -475,7 +476,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.1:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, @@ -667,7 +668,7 @@ func Test_buildConfiguration(t *testing.T) { URL: "http://127.0.0.2:80", }, }, - PassHostHeader: true, + PassHostHeader: Bool(true), }, }, }, diff --git a/pkg/provider/rest/rest.go b/pkg/provider/rest/rest.go index ed62466de..5363c15a1 100644 --- a/pkg/provider/rest/rest.go +++ b/pkg/provider/rest/rest.go @@ -46,7 +46,6 @@ func (p *Provider) Append(systemRouter *mux.Router) { Methods(http.MethodPut). Path("/api/providers/{provider}"). HandlerFunc(func(response http.ResponseWriter, request *http.Request) { - vars := mux.Vars(request) if vars["provider"] != "rest" { response.WriteHeader(http.StatusBadRequest) diff --git a/pkg/safe/routine_test.go b/pkg/safe/routine_test.go index d44d03f58..f9e8a6ab9 100644 --- a/pkg/safe/routine_test.go +++ b/pkg/safe/routine_test.go @@ -12,6 +12,7 @@ import ( func TestNewPoolContext(t *testing.T) { type testKeyType string + testKey := testKeyType("test") ctx := context.WithValue(context.Background(), testKey, "test") diff --git a/pkg/server/middleware/middlewares.go b/pkg/server/middleware/middlewares.go index e13bee412..e38a97e92 100644 --- a/pkg/server/middleware/middlewares.go +++ b/pkg/server/middleware/middlewares.go @@ -142,9 +142,9 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string) ( return nil, badConf } - qualifiedNames := make([]string, len(config.Chain.Middlewares)) - for i, name := range config.Chain.Middlewares { - qualifiedNames[i] = internal.GetQualifiedName(ctx, name) + var qualifiedNames []string + for _, name := range config.Chain.Middlewares { + qualifiedNames = append(qualifiedNames, internal.GetQualifiedName(ctx, name)) } config.Chain.Middlewares = qualifiedNames middleware = func(next http.Handler) (http.Handler, error) { @@ -324,7 +324,7 @@ func (b *Builder) buildConstructor(ctx context.Context, middlewareName string) ( } if middleware == nil { - return nil, fmt.Errorf("middleware %q does not exist", middlewareName) + return nil, fmt.Errorf("invalid middleware %q configuration: invalid middleware type or middleware does not exist", middlewareName) } return tracing.Wrap(ctx, middleware), nil diff --git a/pkg/server/router/router.go b/pkg/server/router/router.go index c27d42229..f75a75e49 100644 --- a/pkg/server/router/router.go +++ b/pkg/server/router/router.go @@ -143,9 +143,9 @@ func (m *Manager) buildRouterHandler(ctx context.Context, routerName string, rou } func (m *Manager) buildHTTPHandler(ctx context.Context, router *runtime.RouterInfo, routerName string) (http.Handler, error) { - qualifiedNames := make([]string, len(router.Middlewares)) - for i, name := range router.Middlewares { - qualifiedNames[i] = internal.GetQualifiedName(ctx, name) + var qualifiedNames []string + for _, name := range router.Middlewares { + qualifiedNames = append(qualifiedNames, internal.GetQualifiedName(ctx, name)) } router.Middlewares = qualifiedNames rm := m.modifierBuilder.Build(ctx, qualifiedNames) diff --git a/pkg/server/router/router_test.go b/pkg/server/router/router_test.go index 36ee65a6e..654bde6d0 100644 --- a/pkg/server/router/router_test.go +++ b/pkg/server/router/router_test.go @@ -399,7 +399,6 @@ func TestAccessLog(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { - rtConf := runtime.NewConfig(dynamic.Configuration{ HTTP: &dynamic.HTTPConfiguration{ Services: test.serviceConfig, @@ -407,6 +406,7 @@ func TestAccessLog(t *testing.T) { Middlewares: test.middlewaresConfig, }, }) + serviceManager := service.NewManager(rtConf.Services, http.DefaultTransport, nil, nil, nil, nil) middlewaresBuilder := middleware.NewBuilder(rtConf.Middlewares, serviceManager) responseModifierFactory := responsemodifiers.NewBuilder(rtConf.Middlewares) @@ -722,7 +722,6 @@ func TestRuntimeConfiguration(t *testing.T) { assert.Equal(t, test.expectedError, allErrors) }) } - } func TestProviderOnMiddlewares(t *testing.T) { @@ -833,7 +832,6 @@ func BenchmarkRouterServe(b *testing.B) { for i := 0; i < b.N; i++ { reqHost.ServeHTTP(w, req, handlers["web"].ServeHTTP) } - } func BenchmarkService(b *testing.B) { @@ -868,5 +866,4 @@ func BenchmarkService(b *testing.B) { for i := 0; i < b.N; i++ { handler.ServeHTTP(w, req) } - } diff --git a/pkg/server/server_entrypoint_tcp_test.go b/pkg/server/server_entrypoint_tcp_test.go index 6bdce2a55..17ccd81a1 100644 --- a/pkg/server/server_entrypoint_tcp_test.go +++ b/pkg/server/server_entrypoint_tcp_test.go @@ -77,8 +77,8 @@ func TestShutdownHTTPHijacked(t *testing.T) { resp := http.Response{StatusCode: http.StatusOK} err = resp.Write(conn) require.NoError(t, err) - })) + entryPoint.switchRouter(router) conn, err := net.Dial("tcp", entryPoint.listener.Addr().String()) diff --git a/pkg/server/service/loadbalancer/wrr/wrr_test.go b/pkg/server/service/loadbalancer/wrr/wrr_test.go index b2eb65e5a..b6e2761fa 100644 --- a/pkg/server/service/loadbalancer/wrr/wrr_test.go +++ b/pkg/server/service/loadbalancer/wrr/wrr_test.go @@ -19,7 +19,6 @@ type responseRecorder struct { func (r *responseRecorder) WriteHeader(statusCode int) { r.save[r.Header().Get("server")]++ r.ResponseRecorder.WriteHeader(statusCode) - } func TestBalancer(t *testing.T) { diff --git a/pkg/server/service/proxy.go b/pkg/server/service/proxy.go index c19bd124f..6da65d090 100644 --- a/pkg/server/service/proxy.go +++ b/pkg/server/service/proxy.go @@ -21,7 +21,7 @@ const StatusClientClosedRequest = 499 // StatusClientClosedRequestText non-standard HTTP status for client disconnection const StatusClientClosedRequestText = "Client Closed Request" -func buildProxy(passHostHeader bool, responseForwarding *dynamic.ResponseForwarding, defaultRoundTripper http.RoundTripper, bufferPool httputil.BufferPool, responseModifier func(*http.Response) error) (http.Handler, error) { +func buildProxy(passHostHeader *bool, responseForwarding *dynamic.ResponseForwarding, defaultRoundTripper http.RoundTripper, bufferPool httputil.BufferPool, responseModifier func(*http.Response) error) (http.Handler, error) { var flushInterval types.Duration if responseForwarding != nil { err := flushInterval.Set(responseForwarding.FlushInterval) @@ -53,7 +53,7 @@ func buildProxy(passHostHeader bool, responseForwarding *dynamic.ResponseForward outReq.ProtoMinor = 1 // Do not pass client Host header unless optsetter PassHostHeader is set. - if !passHostHeader { + if passHostHeader != nil && !*passHostHeader { outReq.Host = outReq.URL.Host } diff --git a/pkg/server/service/proxy_test.go b/pkg/server/service/proxy_test.go index 53d8b5d14..38966b509 100644 --- a/pkg/server/service/proxy_test.go +++ b/pkg/server/service/proxy_test.go @@ -28,7 +28,7 @@ func BenchmarkProxy(b *testing.B) { req := testhelpers.MustNewRequest(http.MethodGet, "http://foo.bar/", nil) pool := newBufferPool() - handler, _ := buildProxy(false, nil, &staticTransport{res}, pool, nil) + handler, _ := buildProxy(Bool(false), nil, &staticTransport{res}, pool, nil) b.ReportAllocs() for i := 0; i < b.N; i++ { diff --git a/pkg/server/service/proxy_websocket_test.go b/pkg/server/service/proxy_websocket_test.go index 6772b0e16..bbb0d1196 100644 --- a/pkg/server/service/proxy_websocket_test.go +++ b/pkg/server/service/proxy_websocket_test.go @@ -17,8 +17,10 @@ import ( "golang.org/x/net/websocket" ) +func Bool(v bool) *bool { return &v } + func TestWebSocketTCPClose(t *testing.T) { - f, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) errChan := make(chan error, 1) @@ -57,7 +59,7 @@ func TestWebSocketTCPClose(t *testing.T) { } func TestWebSocketPingPong(t *testing.T) { - f, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) @@ -123,7 +125,7 @@ func TestWebSocketPingPong(t *testing.T) { } func TestWebSocketEcho(t *testing.T) { - f, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) mux := http.NewServeMux() @@ -139,7 +141,6 @@ func TestWebSocketEcho(t *testing.T) { err = conn.Close() require.NoError(t, err) - })) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { @@ -169,7 +170,6 @@ func TestWebSocketEcho(t *testing.T) { err = conn.Close() require.NoError(t, err) - } func TestWebSocketPassHost(t *testing.T) { @@ -191,7 +191,7 @@ func TestWebSocketPassHost(t *testing.T) { for _, test := range testCases { t.Run(test.desc, func(t *testing.T) { - f, err := buildProxy(test.passHost, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(test.passHost), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) @@ -215,7 +215,6 @@ func TestWebSocketPassHost(t *testing.T) { err = conn.Close() require.NoError(t, err) - })) srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { @@ -246,13 +245,12 @@ func TestWebSocketPassHost(t *testing.T) { err = conn.Close() require.NoError(t, err) - }) } } func TestWebSocketServerWithoutCheckOrigin(t *testing.T) { - f, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) upgrader := gorillawebsocket.Upgrader{CheckOrigin: func(r *http.Request) bool { @@ -293,7 +291,7 @@ func TestWebSocketServerWithoutCheckOrigin(t *testing.T) { } func TestWebSocketRequestWithOrigin(t *testing.T) { - f, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) upgrader := gorillawebsocket.Upgrader{} @@ -339,7 +337,7 @@ func TestWebSocketRequestWithOrigin(t *testing.T) { } func TestWebSocketRequestWithQueryParams(t *testing.T) { - f, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) upgrader := gorillawebsocket.Upgrader{} @@ -379,7 +377,7 @@ func TestWebSocketRequestWithQueryParams(t *testing.T) { } func TestWebSocketRequestWithHeadersInResponseWriter(t *testing.T) { - f, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) mux := http.NewServeMux() @@ -411,7 +409,7 @@ func TestWebSocketRequestWithHeadersInResponseWriter(t *testing.T) { } func TestWebSocketRequestWithEncodedChar(t *testing.T) { - f, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) upgrader := gorillawebsocket.Upgrader{} @@ -451,7 +449,7 @@ func TestWebSocketRequestWithEncodedChar(t *testing.T) { } func TestWebSocketUpgradeFailed(t *testing.T) { - f, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) mux := http.NewServeMux() @@ -501,7 +499,7 @@ func TestWebSocketUpgradeFailed(t *testing.T) { } func TestForwardsWebsocketTraffic(t *testing.T) { - f, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + f, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) mux := http.NewServeMux() @@ -557,7 +555,7 @@ func TestWebSocketTransferTLSConfig(t *testing.T) { srv := createTLSWebsocketServer() defer srv.Close() - forwarderWithoutTLSConfig, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + forwarderWithoutTLSConfig, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) proxyWithoutTLSConfig := createProxyWithForwarder(t, forwarderWithoutTLSConfig, srv.URL) @@ -576,7 +574,7 @@ func TestWebSocketTransferTLSConfig(t *testing.T) { transport := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } - forwarderWithTLSConfig, err := buildProxy(true, nil, transport, nil, nil) + forwarderWithTLSConfig, err := buildProxy(Bool(true), nil, transport, nil, nil) require.NoError(t, err) proxyWithTLSConfig := createProxyWithForwarder(t, forwarderWithTLSConfig, srv.URL) @@ -595,7 +593,7 @@ func TestWebSocketTransferTLSConfig(t *testing.T) { http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - forwarderWithTLSConfigFromDefaultTransport, err := buildProxy(true, nil, http.DefaultTransport, nil, nil) + forwarderWithTLSConfigFromDefaultTransport, err := buildProxy(Bool(true), nil, http.DefaultTransport, nil, nil) require.NoError(t, err) proxyWithTLSConfigFromDefaultTransport := createProxyWithForwarder(t, forwarderWithTLSConfigFromDefaultTransport, srv.URL) diff --git a/pkg/server/service/service.go b/pkg/server/service/service.go index b138eaf17..9c000b171 100644 --- a/pkg/server/service/service.go +++ b/pkg/server/service/service.go @@ -176,6 +176,11 @@ func (m *Manager) getLoadBalancerServiceHandler( service *dynamic.ServersLoadBalancer, responseModifier func(*http.Response) error, ) (http.Handler, error) { + if service.PassHostHeader == nil { + defaultPassHostHeader := true + service.PassHostHeader = &defaultPassHostHeader + } + fwd, err := buildProxy(service.PassHostHeader, service.ResponseForwarding, m.defaultRoundTripper, m.bufferPool, responseModifier) if err != nil { return nil, err diff --git a/pkg/server/service/service_test.go b/pkg/server/service/service_test.go index 9fb0edd09..6090266c0 100644 --- a/pkg/server/service/service_test.go +++ b/pkg/server/service/service_test.go @@ -221,7 +221,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { serviceName: "test", service: &dynamic.ServersLoadBalancer{ Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}}, - PassHostHeader: true, + PassHostHeader: func(v bool) *bool { return &v }(true), Servers: []dynamic.Server{ { URL: serverPassHost.URL, @@ -239,7 +239,8 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { desc: "PassHost doesn't passe the host instead of the IP", serviceName: "test", service: &dynamic.ServersLoadBalancer{ - Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}}, + PassHostHeader: Bool(false), + Sticky: &dynamic.Sticky{Cookie: &dynamic.Cookie{}}, Servers: []dynamic.Server{ { URL: serverPassHostFalse.URL, @@ -258,7 +259,6 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { for _, test := range testCases { test := test t.Run(test.desc, func(t *testing.T) { - handler, err := sm.getLoadBalancerServiceHandler(context.Background(), test.serviceName, test.service, test.responseModifier) assert.NoError(t, err) diff --git a/pkg/server/service/tcp/service.go b/pkg/server/service/tcp/service.go index ca52ad72a..072ffbd12 100644 --- a/pkg/server/service/tcp/service.go +++ b/pkg/server/service/tcp/service.go @@ -85,5 +85,4 @@ func (m *Manager) BuildTCP(rootCtx context.Context, serviceName string) (tcp.Han conf.AddError(err, true) return nil, err } - } diff --git a/pkg/tls/certificate.go b/pkg/tls/certificate.go index 7f739e38b..4a43f2a2c 100644 --- a/pkg/tls/certificate.go +++ b/pkg/tls/certificate.go @@ -140,7 +140,6 @@ func (c *Certificates) isEmpty() bool { // AppendCertificate appends a Certificate to a certificates map keyed by entrypoint. func (c *Certificate) AppendCertificate(certs map[string]map[string]*tls.Certificate, ep string) error { - certContent, err := c.CertFile.Read() if err != nil { return fmt.Errorf("unable to read CertFile : %v", err) @@ -168,7 +167,6 @@ func (c *Certificate) AppendCertificate(certs map[string]map[string]*tls.Certifi SANs = append(SANs, strings.ToLower(dnsName)) } } - } if parsedCert.IPAddresses != nil { for _, ip := range parsedCert.IPAddresses { @@ -176,7 +174,6 @@ func (c *Certificate) AppendCertificate(certs map[string]map[string]*tls.Certifi SANs = append(SANs, strings.ToLower(ip.String())) } } - } certKey := strings.Join(SANs, ",") diff --git a/pkg/tls/certificate_store.go b/pkg/tls/certificate_store.go index da16472b3..4c4ac2fc2 100644 --- a/pkg/tls/certificate_store.go +++ b/pkg/tls/certificate_store.go @@ -56,7 +56,6 @@ func (c CertificateStore) getDefaultCertificateDomains() []string { // GetAllDomains return a slice with all the certificate domain func (c CertificateStore) GetAllDomains() []string { - allCerts := c.getDefaultCertificateDomains() // Get dynamic certificates diff --git a/pkg/tracing/tracing.go b/pkg/tracing/tracing.go index 82d5f2226..2d19aa7da 100644 --- a/pkg/tracing/tracing.go +++ b/pkg/tracing/tracing.go @@ -91,10 +91,7 @@ func (t *Tracing) Extract(format interface{}, carrier interface{}) (opentracing. // IsEnabled determines if tracing was successfully activated. func (t *Tracing) IsEnabled() bool { - if t == nil || t.tracer == nil { - return false - } - return true + return t != nil && t.tracer != nil } // Close tracer @@ -169,9 +166,7 @@ func StartSpan(r *http.Request, operationName string, spanKind ext.SpanKindEnum, } r = r.WithContext(ctx) - return span, r, func() { - span.Finish() - } + return span, r, func() { span.Finish() } } // SetError flags the span associated with this request as in error. diff --git a/pkg/types/logs.go b/pkg/types/logs.go index 7c9f82906..f561effc6 100644 --- a/pkg/types/logs.go +++ b/pkg/types/logs.go @@ -64,7 +64,7 @@ type FieldHeaders struct { // AccessLogFields holds configuration for access log fields type AccessLogFields struct { DefaultMode string `description:"Default mode for fields: keep | drop" json:"defaultMode,omitempty" toml:"defaultMode,omitempty" yaml:"defaultMode,omitempty" export:"true"` - Names map[string]string `json:"names,omitempty" description:"Override mode for fields" json:"names,omitempty" toml:"names,omitempty" yaml:"names,omitempty" export:"true"` + Names map[string]string `description:"Override mode for fields" json:"names,omitempty" toml:"names,omitempty" yaml:"names,omitempty" export:"true"` Headers *FieldHeaders `description:"Headers to keep, drop or redact" json:"headers,omitempty" toml:"headers,omitempty" yaml:"headers,omitempty" export:"true"` } diff --git a/script/validate-misspell b/script/validate-misspell index c29770eac..1fb9c8c9d 100755 --- a/script/validate-misspell +++ b/script/validate-misspell @@ -2,8 +2,7 @@ SCRIPT_DIR="$( cd "$( dirname "${0}" )" && pwd -P)" files=() -while IFS='' read -r line; do files+=("$line"); done < <(git ls-files "${SCRIPT_DIR}"/../'docs/*.md' "${SCRIPT_DIR}"/../*.md) - +while IFS='' read -r line; do files+=("$line"); done < <(git ls-files "${SCRIPT_DIR}"/../'docs/*.md' "${SCRIPT_DIR}"/../*.md | grep -v "CHANGELOG.md") errors=() for f in "${files[@]}"; do diff --git a/webui/src/components/_commons/PanelServiceDetails.vue b/webui/src/components/_commons/PanelServiceDetails.vue index 7acfe1045..9bde9603d 100644 --- a/webui/src/components/_commons/PanelServiceDetails.vue +++ b/webui/src/components/_commons/PanelServiceDetails.vue @@ -54,37 +54,8 @@ - - -
-
Sticky: Cookie
-
-
- -
-
-
NAME
- - {{ data.weighted.sticky.cookie.name }} - -
-
-
- -
-
-
SECURE
- -
- -
-
HTTP Only
- -
-
-
+ + @@ -92,17 +63,30 @@ +