1
0
mirror of https://github.com/containous/traefik.git synced 2025-09-16 17:44:30 +03:00

Compare commits

..

51 Commits

Author SHA1 Message Date
Kevin Pollet
76e35a09b7 Prepare release v2.3.4 2020-11-24 17:06:04 +01:00
SkapiN
d2c1d39d42 Fix clusters option in ECS provider documentation 2020-11-24 14:50:03 +01:00
Harold Ozouf
e9cccf6504 Do not evaluate templated URL in redirectRegex middleware 2020-11-24 14:16:03 +01:00
Ludovic Fernandez
1c505903ff fix: invalid slice parsing. 2020-11-24 09:40:03 +01:00
Ludovic Fernandez
53ed8e04ae Update go-acme/lego to v4.1.2 2020-11-23 12:00:03 +01:00
Romain
be0845af02 Apply labelSelector as a TweakListOptions for Kubernetes informers 2020-11-20 00:18:04 +01:00
Ludovic Fernandez
f83a57b3da Prepare release v2.3.3 2020-11-19 18:31:09 +01:00
Kevin Pollet
08264749f0 Update Yaegi to v0.9.7 2020-11-19 17:56:03 +01:00
Harold Ozouf
a75819cae3 Filter out Helm secrets from informer caches
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2020-11-19 14:32:03 +01:00
Ivor Scott
9fb32a47ca Fix grammar in kubernetes ingress controller documentation 2020-11-19 10:04:04 +01:00
Harold Ozouf
4f43c9ebb4 Fix missing allow-empty tag on ECS and Consul Catalog providers
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2020-11-19 00:12:03 +01:00
Harold Ozouf
9177982334 Fix consul catalog panic when health and services are not in sync
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2020-11-17 17:30:03 +01:00
Yoan Blanc
52eeff9f9f fix: consulcatalog to update before the first interval 2020-11-16 20:44:04 +01:00
Petyo Kunchev
0fcccd35ff /bin/bash replaced with /usr/bin/env bash to match other scripts 2020-11-16 15:38:04 +01:00
Douglas De Toni Machado
598dcf6b62 Improve service name lookup on TCP routers 2020-11-13 12:48:04 +01:00
Alexander Wellbrock
459200dd01 Forwardauth headers 2020-11-10 17:50:04 +01:00
james426759
af22cabc6f Fix docs for TLS 2020-11-10 17:28:04 +01:00
Alessandro Chitolina
920e82f11a fix: translate configured server port into correct mapped host port 2020-11-09 17:12:05 +01:00
Ludovic Fernandez
9bdf9e1e02 Update Yaegi to v0.9.5 2020-11-08 23:42:03 +01:00
Ludovic Fernandez
3a45f05e36 Update go-acme/lego to v4.1.0 2020-11-08 23:24:04 +01:00
Neil McAllister
8e3e387be7 Fix Traefik Proxy product nav in docs 2020-11-06 21:56:03 +01:00
Ludovic Fernandez
267d0b7b5a chore: update linter. 2020-11-06 09:26:03 +01:00
Kevin Pollet
f5b290b093 Add ECS menu to dynamic config reference 2020-11-03 17:40:04 +01:00
Michael
4ea1c98ac9 Improve anonymize configuration 2020-10-30 12:44:05 +01:00
Tristan Weil
db007efe00 Ignore errors when setting keepalive period is not supported by the system 2020-10-28 15:32:04 +01:00
Jean-Baptiste Doumenjou
a0c02f62a3 fix: exclude protected link from doc verify 2020-10-27 18:34:04 +01:00
Jean-Baptiste Doumenjou
ff7b814edc fix documentation 2020-10-27 12:46:04 +01:00
Ludovic Fernandez
ea459e9af0 fix: update Yaegi to v0.9.4 2020-10-23 11:30:04 +02:00
Andrii Dembitskyi
2dd5a53db2 Add missed tls config for yaml example 2020-10-23 11:00:05 +02:00
Romain
fc97ea7ee0 Use timezone without daylight saving time for logger formatter tests
Co-authored-by: jbdoumenjou <925513+jbdoumenjou@users.noreply.github.com>
2020-10-22 19:52:04 +02:00
Kevin Crawley
582d2540af add links to contributors guide 2020-10-22 12:08:05 +02:00
Tom Matthews
6ad79dcd45 Clarify time-based field units 2020-10-22 11:36:03 +02:00
Tom Matthews
721896ba70 Resolve broken URLs causing make docs to fail 2020-10-20 23:02:04 +02:00
Yeri Pratama
228270414c fix typo in providers overview documentation 2020-10-20 19:02:04 +02:00
Romain
2683df7b5b Fix ingress documentation 2020-10-20 14:16:04 +02:00
Romain
3e61d1f233 Prepare release v2.3.2 2020-10-19 20:22:04 +02:00
Ludovic Fernandez
04c07227f2 fix: Consul Catalog address documentation. 2020-10-19 10:28:03 +02:00
Neil McAllister
2e8d99c5b8 Revise Traefik Pilot documentation section 2020-10-16 11:20:05 +02:00
Ludovic Fernandez
c07301473b fix: update Yaegi to v0.9.4 2020-10-16 11:02:03 +02:00
Andrew Savinykh
b1ba42410b Moving Provider Namespace documentation topic to Configuration Discovery section 2020-10-15 14:54:04 +02:00
Andrew Savinykh
b80f89e3db Adding details about the default TLS options to the documentation 2020-10-15 14:12:04 +02:00
Ludovic Fernandez
5c853766e8 fix: flaky integration tests 2020-10-09 09:32:03 +02:00
Ludovic Fernandez
d2435cf43b fix: restrict protocol for TLS Challenge. 2020-10-08 13:34:04 +02:00
Michael
556f7608db fix: use provider keytype instead of account keytype. 2020-10-08 12:58:04 +02:00
Jean-Baptiste Doumenjou
a4df4b028e fix: pilot static configuration documentation 2020-10-08 11:36:03 +02:00
Ludovic Fernandez
63683d35fc doc: add YAML sample. 2020-10-08 10:38:05 +02:00
Ludovic Fernandez
495344591f fix: versions in the PR template. 2020-10-08 00:48:03 +02:00
Kevin Pollet
4e508499da Fix containous links in readme 2020-10-07 18:02:04 +02:00
Benjamin Durham
e4a3df3516 Fix broken logo 2020-10-07 10:46:04 +02:00
Matthias Schneider
3506cbd5e9 fix: udp json struct tag 2020-10-02 17:38:04 +02:00
Anton Popovichenko
ab13019bde acme: Fix race condition in LocalStore during saving. 2020-09-30 12:04:04 +02:00
148 changed files with 3192 additions and 1229 deletions

View File

@@ -3,11 +3,11 @@ PLEASE READ THIS MESSAGE.
Documentation fixes or enhancements:
- for Traefik v1: use branch v1.7
- for Traefik v2: use branch v2.2
- for Traefik v2: use branch v2.3
Bug fixes:
- for Traefik v1: use branch v1.7
- for Traefik v2: use branch v2.2
- for Traefik v2: use branch v2.3
Enhancements:
- for Traefik v1: we only accept bug fixes

1
.gitignore vendored
View File

@@ -17,3 +17,4 @@
cover.out
vendor/
plugins-storage/
traefik_changelog.md

View File

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

View File

@@ -1,3 +1,67 @@
## [v2.3.4](https://github.com/traefik/traefik/tree/v2.3.4) (2020-11-24)
[All Commits](https://github.com/traefik/traefik/compare/v2.3.3...v2.3.4)
**Bug fixes:**
- **[acme]** Update go-acme/lego to v4.1.2 ([#7577](https://github.com/traefik/traefik/pull/7577) by [ldez](https://github.com/ldez))
- **[k8s,k8s/crd,k8s/ingress]** Apply labelSelector as a TweakListOptions for Kubernetes informers ([#7521](https://github.com/traefik/traefik/pull/7521) by [rtribotte](https://github.com/rtribotte))
- **[middleware]** Do not evaluate templated URL in redirectRegex middleware ([#7573](https://github.com/traefik/traefik/pull/7573) by [jspdown](https://github.com/jspdown))
- **[provider]** fix: invalid slice parsing. ([#7583](https://github.com/traefik/traefik/pull/7583) by [ldez](https://github.com/ldez))
**Documentation:**
- **[ecs]** Fix clusters option in ECS provider documentation ([#7586](https://github.com/traefik/traefik/pull/7586) by [skapin](https://github.com/skapin))
## [v2.3.3](https://github.com/traefik/traefik/tree/v2.3.3) (2020-11-19)
[All Commits](https://github.com/traefik/traefik/compare/v2.3.2...v2.3.3)
**Bug fixes:**
- **[acme]** Update go-acme/lego to v4.1.0 ([#7526](https://github.com/traefik/traefik/pull/7526) by [ldez](https://github.com/ldez))
- **[consulcatalog,ecs]** Fix missing allow-empty tag on ECS and Consul Catalog providers ([#7561](https://github.com/traefik/traefik/pull/7561) by [jspdown](https://github.com/jspdown))
- **[consulcatalog]** consulcatalog to update before the first interval ([#7514](https://github.com/traefik/traefik/pull/7514) by [greut](https://github.com/greut))
- **[consulcatalog]** Fix consul catalog panic when health and services are not in sync ([#7558](https://github.com/traefik/traefik/pull/7558) by [jspdown](https://github.com/jspdown))
- **[ecs]** Translate configured server port into correct mapped host port ([#7480](https://github.com/traefik/traefik/pull/7480) by [alekitto](https://github.com/alekitto))
- **[k8s,k8s/crd,k8s/ingress]** Filter out Helm secrets from informer caches ([#7562](https://github.com/traefik/traefik/pull/7562) by [jspdown](https://github.com/jspdown))
- **[plugins]** Update Yaegi to v0.9.5 ([#7527](https://github.com/traefik/traefik/pull/7527) by [ldez](https://github.com/ldez))
- **[plugins]** Update Yaegi to v0.9.7 ([#7569](https://github.com/traefik/traefik/pull/7569) by [kevinpollet](https://github.com/kevinpollet))
- **[plugins]** Update Yaegi to v0.9.4 ([#7451](https://github.com/traefik/traefik/pull/7451) by [ldez](https://github.com/ldez))
- **[tcp]** Ignore errors when setting keepalive period is not supported by the system ([#7410](https://github.com/traefik/traefik/pull/7410) by [tristan-weil](https://github.com/tristan-weil))
- **[tcp]** Improve service name lookup on TCP routers ([#7370](https://github.com/traefik/traefik/pull/7370) by [ddtmachado](https://github.com/ddtmachado))
- Improve anonymize configuration ([#7482](https://github.com/traefik/traefik/pull/7482) by [mmatur](https://github.com/mmatur))
**Documentation:**
- **[ecs]** Add ECS menu to dynamic config reference ([#7501](https://github.com/traefik/traefik/pull/7501) by [kevinpollet](https://github.com/kevinpollet))
- **[k8s,k8s/ingress]** Fix ingress documentation ([#7424](https://github.com/traefik/traefik/pull/7424) by [rtribotte](https://github.com/rtribotte))
- **[k8s]** fix documentation ([#7469](https://github.com/traefik/traefik/pull/7469) by [jbdoumenjou](https://github.com/jbdoumenjou))
- **[k8s]** Fix grammar in kubernetes ingress controller documentation ([#7565](https://github.com/traefik/traefik/pull/7565) by [ivorscott](https://github.com/ivorscott))
- **[logs]** Clarify time-based field units ([#7447](https://github.com/traefik/traefik/pull/7447) by [tomtastic](https://github.com/tomtastic))
- **[middleware]** Forwardauth headers ([#7506](https://github.com/traefik/traefik/pull/7506) by [w4tsn](https://github.com/w4tsn))
- **[provider]** fix typo in providers overview documentation ([#7441](https://github.com/traefik/traefik/pull/7441) by [pirey](https://github.com/pirey))
- **[tls]** Fix docs for TLS ([#7541](https://github.com/traefik/traefik/pull/7541) by [james426759](https://github.com/james426759))
- fix: exclude protected link from doc verify ([#7477](https://github.com/traefik/traefik/pull/7477) by [jbdoumenjou](https://github.com/jbdoumenjou))
- Add missed tls config for yaml example ([#7450](https://github.com/traefik/traefik/pull/7450) by [andrew-demb](https://github.com/andrew-demb))
- Resolve broken URLs causing make docs to fail ([#7444](https://github.com/traefik/traefik/pull/7444) by [tomtastic](https://github.com/tomtastic))
- Fix Traefik Proxy product nav in docs ([#7523](https://github.com/traefik/traefik/pull/7523) by [PCM2](https://github.com/PCM2))
- add links to contributors guide ([#7435](https://github.com/traefik/traefik/pull/7435) by [notsureifkevin](https://github.com/notsureifkevin))
## [v2.3.2](https://github.com/traefik/traefik/tree/v2.3.2) (2020-10-19)
[All Commits](https://github.com/traefik/traefik/compare/v2.3.1...v2.3.2)
**Bug fixes:**
- **[acme]** fix: restrict protocol for TLS Challenge. ([#7400](https://github.com/traefik/traefik/pull/7400) by [ldez](https://github.com/ldez))
- **[acme]** fix: use provider keytype instead of account keytype. ([#7387](https://github.com/traefik/traefik/pull/7387) by [mmatur](https://github.com/mmatur))
- **[acme]** acme: Fix race condition in LocalStore during saving. ([#7355](https://github.com/traefik/traefik/pull/7355) by [walkline](https://github.com/walkline))
- **[plugins]** fix: update Yaegi to v0.9.4 ([#7426](https://github.com/traefik/traefik/pull/7426) by [ldez](https://github.com/ldez))
- **[udp]** fix: udp json struct tag ([#7375](https://github.com/traefik/traefik/pull/7375) by [mschneider82](https://github.com/mschneider82))
**Documentation:**
- **[consulcatalog]** fix: Consul Catalog address documentation. ([#7429](https://github.com/traefik/traefik/pull/7429) by [ldez](https://github.com/ldez))
- **[middleware]** Moving Provider Namespace documentation topic to Configuration Discovery section ([#7423](https://github.com/traefik/traefik/pull/7423) by [AndrewSav](https://github.com/AndrewSav))
- **[pilot]** fix: pilot static configuration documentation ([#7399](https://github.com/traefik/traefik/pull/7399) by [jbdoumenjou](https://github.com/jbdoumenjou))
- **[plugins]** Revise Traefik Pilot documentation section ([#7427](https://github.com/traefik/traefik/pull/7427) by [PCM2](https://github.com/PCM2))
- **[tls]** Adding details about the default TLS options to the documentation ([#7422](https://github.com/traefik/traefik/pull/7422) by [AndrewSav](https://github.com/AndrewSav))
- doc: add YAML sample. ([#7397](https://github.com/traefik/traefik/pull/7397) by [ldez](https://github.com/ldez))
- Fix containous links in readme ([#7394](https://github.com/traefik/traefik/pull/7394) by [kevinpollet](https://github.com/kevinpollet))
- Fix broken logo ([#7390](https://github.com/traefik/traefik/pull/7390) by [Bencey](https://github.com/Bencey))
## [v2.3.1](https://github.com/traefik/traefik/tree/v2.3.1) (2020-09-28)
[All Commits](https://github.com/traefik/traefik/compare/v2.3.0...v2.3.1)

View File

@@ -36,7 +36,7 @@ Representation of a project may be further defined and clarified by project main
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@containo.us
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at contact@traefik.io
All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
The project team is obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
@@ -48,4 +48,4 @@ Project maintainers who do not follow or enforce the Code of Conduct in good fai
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/
[version]: http://contributor-covenant.org/version/1/4/

View File

@@ -8,7 +8,7 @@
[![Go Report Card](https://goreportcard.com/badge/traefik/traefik)](https://goreportcard.com/report/traefik/traefik)
[![](https://images.microbadger.com/badges/image/traefik.svg)](https://microbadger.com/images/traefik)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/traefik/traefik/blob/master/LICENSE.md)
[![Join the community support forum at https://community.containo.us/](https://img.shields.io/badge/style-register-green.svg?style=social&label=Discourse)](https://community.containo.us/)
[![Join the community support forum at https://community.traefik.io/](https://img.shields.io/badge/style-register-green.svg?style=social&label=Discourse)](https://community.traefik.io/)
[![Twitter](https://img.shields.io/twitter/follow/traefik.svg?style=social)](https://twitter.com/intent/follow?screen_name=traefik)
@@ -96,9 +96,9 @@ A collection of contributions around Traefik can be found at [https://awesome.tr
## Support
To get community support, you can:
- join the Traefik community forum: [![Join the chat at https://community.containo.us/](https://img.shields.io/badge/style-register-green.svg?style=social&label=Discourse)](https://community.containo.us/)
- join the Traefik community forum: [![Join the chat at https://community.traefik.io/](https://img.shields.io/badge/style-register-green.svg?style=social&label=Discourse)](https://community.traefik.io/)
If you need commercial support, please contact [Containo.us](https://containo.us) by mail: <mailto:support@containo.us>.
If you need commercial support, please contact [Traefik.io](https://traefik.io) by mail: <mailto:support@traefik.io>.
## Download
@@ -122,7 +122,7 @@ git clone https://github.com/traefik/traefik
## Introductory Videos
You can find high level and deep dive videos on [videos.containo.us](https://videos.containo.us).
You can find high level and deep dive videos on [videos.traefik.io](https://videos.traefik.io).
## Maintainers
@@ -152,9 +152,9 @@ We use [Semantic Versioning](https://semver.org/).
## Credits
Kudos to [Peka](http://peka.byethost11.com/photoblog/) for his awesome work on the logo ![logo](docs/content/assets/img/traefik.icon.png).
Kudos to [Peka](http://peka.byethost11.com/photoblog/) for his awesome work on the gopher's logo!.
Traefik's logo is licensed under the Creative Commons 3.0 Attributions license.
The gopher's logo of Traefik is licensed under the Creative Commons 3.0 Attributions license.
Traefik's logo was inspired by the gopher stickers made by [Takuya Ueda](https://twitter.com/tenntenn).
The gopher's logo of Traefik was inspired by the gopher stickers made by [Takuya Ueda](https://twitter.com/tenntenn).
The original Go gopher was designed by [Renee French](https://reneefrench.blogspot.com/).

View File

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

View File

@@ -20,5 +20,5 @@
.product-switcher .nav-dropdown-menu--products .nav-dropdown-menu-wrapper {
width: auto;
height: auto;
height: 335px;
}

View File

@@ -11,75 +11,20 @@
* Ludovic Fernandez [@ldez](https://github.com/ldez)
* Julien Salleyron [@juliens](https://github.com/juliens)
* Nicolas Mengin [@nmengin](https://github.com/nmengin)
* Marco Jantke [@marco-jantke](https://github.com/marco-jantke)
* Marco Jantke [@mjantke](https://github.com/mjeri)
* Michaël Matur [@mmatur](https://github.com/mmatur)
* Gérald Croës [@geraldcroes](https://github.com/geraldcroes)
* Jean-Baptiste Doumenjou [@jbdoumenjou](https://github.com/jbdoumenjou)
* Mathieu Lonjaret [@mpl](https://github.com/mpl)
* Romain Tribotté [@rtribotte](https://github.com/rtribotte)
## Contributions Daily Meeting
## Issue Triage
* 3 Maintainers should attend to a Contributions Daily Meeting where we sort and label new issues ([is:issue label:status/0-needs-triage](https://github.com/traefik/traefik/issues?utf8=%E2%9C%93&q=is%3Aissue+label%3Astatus%2F0-needs-triage+)), and review every Pull Requests
* Every pull request should be checked during the Contributions Daily Meeting
* Even if its already assigned
* Even PR labelled with `contributor/waiting-for-corrections` or `contributor/waiting-for-feedback`
* Issues labeled with `priority/P0` and `priority/P1` should be assigned.
* Modifying an issue or a pull request (labels, assignees, milestone) is only possible:
* During the Contributions Daily Meeting
* By an assigned maintainer
* In case of emergency, if a change proposal is approved by 2 other maintainers (on Slack, Discord, Discourse, etc)
Issues and PRs are triaged daily and the process for triaging may be found under [triaging issues](https://github.com/traefik/contributors-guide/blob/master/issue_triage.md) in our [contributors guide repository](https://github.com/traefik/contributors-guide).
## PR review process:
* The status `needs-design-review` is only used in complex/heavy/tricky PRs.
* From `1` to `2`: 1 comment that says “design LGTM” (by a senior maintainer).
* From `2` to `3`: 3 LGTM approvals by any maintainer.
* If needed, a specific maintainer familiar with a particular domain can be requested for the review.
* If a PR has been implemented in pair programming, one peer's LGTM goes into the review for free
* Amending someone else's pull request is authorized only in emergency, if a rebase is needed, or if the initial contributor is silent
We use [PRM](https://github.com/ldez/prm) to manage locally pull requests.
## Bots
### [Myrmica Lobicornis](https://github.com/traefik/lobicornis/)
Update and Merge Pull Request.
The maintainer giving the final LGTM must add the `status/3-needs-merge` label to trigger the merge bot.
By default, a squash-rebase merge will be carried out.
To preserve commits, add `bot/merge-method-rebase` before `status/3-needs-merge`.
The status `status/4-merge-in-progress` is only used by the bot.
If the bot is not able to perform the merge, the label `bot/need-human-merge` is added.
In such a situation, solve the conflicts/CI/... and then remove the label `bot/need-human-merge`.
To prevent the bot from automatically merging a PR, add the label `bot/no-merge`.
The label `bot/light-review` decreases the number of required LGTM from 3 to 1.
This label is used when:
* Updating the vendors from previously reviewed PRs
* Merging branches into the master
* Preparing the release
### [Myrmica Bibikoffi](https://github.com/traefik/bibikoffi/)
* closes stale issues [cron]
* use some criterion as number of days between creation, last update, labels, ...
### [Myrmica Aloba](https://github.com/traefik/aloba)
Manage GitHub labels.
* Add labels on new PR [GitHub WebHook]
* Add milestone to a new PR based on a branch version (1.4, 1.3, ...) [GitHub WebHook]
* Add and remove `contributor/waiting-for-corrections` label when a review request changes [GitHub WebHook]
* Weekly report of PR status on Slack (CaptainPR) [cron]
The process for reviewing PRs may be found under [review guidelines](https://github.com/traefik/contributors-guide/blob/master/review_guidelines.md) in our contributors guide repository.
## Labels

View File

@@ -5,41 +5,5 @@ A Quick Guide for Efficient Contributions
So you've decided to improve Traefik?
Thank You!
Now the last step is to submit your Pull Request in a way that makes sure it gets the attention it deserves.
Let's go through the classic pitfalls to make sure everything is right.
## Title
The title must be short and descriptive. (~60 characters)
## Description
Follow the [pull request template](https://github.com/traefik/traefik/blob/master/.github/PULL_REQUEST_TEMPLATE.md) as much as possible.
Explain the conditions which led you to write this PR: give us context.
The context should lead to something, an idea or a problem that youre facing.
Remain clear and concise.
Take time to polish the format of your message so we'll enjoy reading it and working on it.
Help the readers focus on what matters, and help them understand the structure of your message (see the [Github Markdown Syntax](https://help.github.com/articles/github-flavored-markdown)).
## PR Content
- Make it small.
- One feature per Pull Request.
- Write useful descriptions and titles.
- Avoid re-formatting code that is not on the path of your PR.
- Make sure the [code builds](building-testing.md).
- Make sure [all tests pass](building-testing.md).
- Add tests.
- Address review comments in terms of additional commits (and don't amend/squash existing ones unless the PR is trivial).
!!! note "Third-Party Dependencies"
If a PR involves changes to third-party dependencies, the commits pertaining to the vendor folder and the manifest/lock file(s) should be committed separated.
!!! tip "10 Tips for Better Pull Requests"
We enjoyed this article, maybe you will too! [10 tips for better pull requests](https://blog.ploeh.dk/2015/01/15/10-tips-for-better-pull-requests/).
Please review the [guidelines on creating PRs](https://github.com/traefik/contributors-guide/blob/master/pr_guidelines.md) for Traefik in our [contributors guide repository](https://github.com/traefik/contributors-guide).

View File

@@ -9,7 +9,10 @@ You can install Traefik with the following flavors:
## Use the Official Docker Image
Choose one of the [official Docker images](https://hub.docker.com/_/traefik) and run it with the [sample configuration file](https://raw.githubusercontent.com/traefik/traefik/v2.3/traefik.sample.toml):
Choose one of the [official Docker images](https://hub.docker.com/_/traefik) and run it with one sample configuration file:
* [TOML](https://raw.githubusercontent.com/traefik/traefik/v2.3/traefik.sample.toml)
* [YAML](https://raw.githubusercontent.com/traefik/traefik/v2.3/traefik.sample.yml)
```bash
docker run -d -p 8080:8080 -p 80:80 \

View File

@@ -322,8 +322,9 @@ For complete details, refer to your provider's _Additional configuration_ link.
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) |
| [HyperOne](https://www.hyperone.com) | `hyperone` | `HYPERONE_PASSPORT_LOCATION`, `HYPERONE_LOCATION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/hyperone) |
| [IIJ](https://www.iij.ad.jp/) | `iij` | `IIJ_API_ACCESS_KEY`, `IIJ_API_SECRET_KEY`, `IIJ_DO_SERVICE_CODE` | [Additional configuration](https://go-acme.github.io/lego/dns/iij) |
| [Infomaniak](https://www.infomaniak.com) | `infomaniak` | `INFOMANIAK_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/infomaniak) |
| [INWX](https://www.inwx.de/en) | `inwx` | `INWX_USERNAME`, `INWX_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/inwx) |
| [Joker.com](https://joker.com) | `joker` | `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) |
| [Joker.com](https://joker.com) | `joker` | `JOKER_API_MODE` with `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) |
| [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) |
| [Linode v4](https://www.linode.com) | `linode` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) |
| [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) |
@@ -516,6 +517,34 @@ certificatesResolvers:
# ...
```
### `keyType`
_Optional, Default="RSA4096"_
KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'.
```toml tab="File (TOML)"
[certificatesResolvers.myresolver.acme]
# ...
keyType = "RSA4096"
# ...
```
```yaml tab="File (YAML)"
certificatesResolvers:
myresolver:
acme:
# ...
keyType: 'RSA4096'
# ...
```
```bash tab="CLI"
# ...
--certificatesresolvers.myresolver.acme.keyType="RSA4096"
# ...
```
## Fallback
If Let's Encrypt is not reachable, the following certificates will apply:

View File

@@ -64,7 +64,7 @@ tls:
!!! important "Restriction"
Any store definition other than the default one (named `default`) will be ignored,
and there is thefore only one globally available TLS store.
and there is therefore only one globally available TLS store.
In the `tls.certificates` section, a list of stores can then be specified to indicate where the certificates should be stored:
@@ -134,14 +134,23 @@ If no default certificate is provided, Traefik generates and uses a self-signed
The TLS options allow one to configure some parameters of the TLS connection.
!!! important "'default' TLS Option"
The `default` option is special.
When no tls options are specified in a tls router, the `default` option is used.
When specifying the `default` option explicitly, make sure not to specify provider namespace as the `default` option does not have one.
Conversely, for cross-provider references, for example, when referencing the file provider from a docker label,
you must specify the provider namespace, for example:
`traefik.http.routers.myrouter.tls.options=myoptions@file`
!!! important "TLSOptions in Kubernetes"
When using the TLSOptions-CRD in Kubernetes, one might setup a default set of options that,
if not explicitly overwritten, should apply to all ingresses. To achieve that, you'll have to
create a TLSOptions CR with the name `default`. There may exist only one TLSOption with the
name `default` (across all namespaces) - otherwise they will be dropped.
To explicitly use a different TLSOption (and using the Kubernetes Ingress resources) you'll
have to add an annotation to the Ingress in the following form:
if not explicitly overwritten, should apply to all ingresses.
To achieve that, you'll have to create a TLSOptions CR with the name `default`.
There may exist only one TLSOption with the name `default` (across all namespaces) - otherwise they will be dropped.
To explicitly use a different TLSOption (and using the Kubernetes Ingress resources)
you'll have to add an annotation to the Ingress in the following form:
`traefik.ingress.kubernetes.io/router.tls.options: <resource-namespace>-<resource-name>@kubernetescrd`
### Minimum TLS Version

View File

@@ -61,6 +61,18 @@ http:
address: "https://example.com/auth"
```
## Forward-Request Headers
The following request properties are provided to the forward-auth target endpoint as `X-Forwarded-` headers.
| Property | Forward-Request Header |
|-------------------|------------------------|
| HTTP Method | X-Forwarded-Method |
| Protocol | X-Forwarded-Proto |
| Host | X-Forwarded-Host |
| Request URI | X-Forwarded-Uri |
| Source IP-Address | X-Forwarded-For |
## Configuration Options
### `address`

View File

@@ -11,6 +11,11 @@ There are several available middleware in Traefik, some can modify the request,
Pieces of middleware can be combined in chains to fit every scenario.
!!! warning "Provider Namespace"
Be aware of the concept of Providers Namespace described in the [Configuration Discovery](../providers/overview.md#provider-namespace) section.
It also applies to Middlewares.
## Configuration Example
```yaml tab="Docker"
@@ -128,106 +133,6 @@ http:
- url: "http://127.0.0.1:80"
```
## Provider Namespace
When you declare a middleware, it lives in its provider's namespace.
For example, if you declare a middleware using a Docker label, under the hoods, it will reside in the docker provider namespace.
If you use multiple providers and wish to reference a middleware declared in another provider
(aka referencing a cross-provider middleware),
then you'll have to append to the middleware name, the `@` separator, followed by the provider name.
```text
<resource-name>@<provider-name>
```
!!! important "Kubernetes Namespace"
As Kubernetes also has its own notion of namespace, one should not confuse the "provider namespace"
with the "kubernetes namespace" of a resource when in the context of a cross-provider usage.
In this case, since the definition of the middleware is not in kubernetes,
specifying a "kubernetes namespace" when referring to the resource does not make any sense,
and therefore this specification would be ignored even if present.
On the other hand, if you declare the middleware as a Custom Resource in Kubernetes and use the
non-crd Ingress objects, you'll have to add the kubernetes namespace of the middleware to the
annotation like this `<middleware-namespace>-<middleware-name>@kubernetescrd`.
!!! abstract "Referencing a Middleware from Another Provider"
Declaring the add-foo-prefix in the file provider.
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.add-foo-prefix.addPrefix]
prefix = "/foo"
```
```yaml tab="File (YAML)"
http:
middlewares:
add-foo-prefix:
addPrefix:
prefix: "/foo"
```
Using the add-foo-prefix middleware from other providers:
```yaml tab="Docker"
your-container: #
image: your-docker-image
labels:
# Attach add-foo-prefix@file middleware (declared in file)
- "traefik.http.routers.my-container.middlewares=add-foo-prefix@file"
```
```yaml tab="Kubernetes Ingress Route"
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutestripprefix
spec:
entryPoints:
- web
routes:
- match: Host(`example.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.
```
```yaml tab="Kubernetes Ingress"
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: stripprefix
namespace: appspace
spec:
stripPrefix:
prefixes:
- /stripit
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
namespace: appspace
annotations:
# referencing a middleware from Kubernetes CRD provider:
# <middleware-namespace>-<middleware-name>@kubernetescrd
"traefik.ingress.kubernetes.io/router.middlewares": appspace-stripprefix@kubernetescrd
spec:
# ... regular ingress definition
```
## Available Middlewares
| Middleware | Purpose | Area |

View File

@@ -74,7 +74,7 @@ The available filters are:
- `statusCodes`, to limit the access logs to requests with a status codes in the specified range
- `retryAttempts`, to keep the access logs when at least one retry has happened
- `minDuration`, to keep access logs when requests take longer than the specified duration
- `minDuration`, to keep access logs when requests take longer than the specified duration (provided in seconds or as a valid duration format, see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration))
```toml tab="File (TOML)"
# Configuring Multiple Filters
@@ -198,7 +198,7 @@ accessLog:
| `RequestScheme` | The HTTP scheme requested `http` or `https`. |
| `RequestLine` | `RequestMethod` + `RequestPath` + `RequestProtocol` |
| `RequestContentSize` | The number of bytes in the request entity (a.k.a. body) sent by the client. |
| `OriginDuration` | The time taken by the origin server ('upstream') to return its response. |
| `OriginDuration` | The time taken (in nanoseconds) by the origin server ('upstream') to return its response. |
| `OriginContentSize` | The content length specified by the origin server, or 0 if unspecified. |
| `OriginStatus` | The HTTP status code returned by the origin server. If the request was handled by this Traefik instance (e.g. with a redirect), then this value will be absent. |
| `OriginStatusLine` | `OriginStatus` + Status code explanation |
@@ -207,7 +207,7 @@ accessLog:
| `DownstreamContentSize` | The number of bytes in the response entity returned to the client. This is in addition to the "Content-Length" header, which may be present in the origin response. |
| `RequestCount` | The number of requests received since the Traefik instance started. |
| `GzipRatio` | The response body compression ratio achieved. |
| `Overhead` | The processing time overhead caused by Traefik. |
| `Overhead` | The processing time overhead (in nanoseconds) caused by Traefik. |
| `RetryAttempts` | The amount of attempts the request was retried. |
## Log Rotation

View File

@@ -0,0 +1,49 @@
# Plugins and Traefik Pilot
Traefik Pilot is a software-as-a-service (SaaS) platform that connects to Traefik to extend its capabilities.
It offers a number of features to enhance observability and control of Traefik through a global control plane and dashboard, including:
* Metrics for network activity of Traefik proxies and groups of proxies
* Alerts for service health issues and security vulnerabilities
* Plugins that extend the functionality of Traefik
!!! important "Learn More About Traefik Pilot"
This section is intended only as a brief overview for Traefik users who are not familiar with Traefik Pilot.
To explore all that Traefik Pilot has to offer, please consult the [Traefik Pilot Documentation](https://doc.traefik.io/traefik-pilot/)
!!! Note "Prerequisites"
Traefik Pilot is compatible with Traefik Proxy 2.3 or later.
## Connecting to Traefik Pilot
To connect your Traefik proxies to Traefik Pilot, login or create an account at the [Traefik Pilot homepage](https://pilot.traefik.io) and choose **Register New Traefik Instance**.
To complete the connection, Traefik Pilot will issue a token that must be added to your Traefik static configuration, according to the instructions provided by the Traefik Pilot dashboard.
For more information, consult the [Quick Start Guide](https://doc.traefik.io/traefik-pilot/connecting/)
Health and security alerts for registered Traefik instances can be enabled from the Preferences in your [Traefik Pilot Profile](https://pilot.traefik.io/profile).
## Plugins
Plugins are available to any Traefik proxies that are connected to Traefik Pilot.
They are a powerful feature for extending Traefik with custom features and behaviors.
You can browse community-contributed plugins from the catalog in the [Traefik Pilot Dashboard](https://pilot.traefik.io/plugins).
To add a new plugin to a Traefik instance, you must modify that instance's static configuration.
The code to be added is provided for you when you choose **Install the Plugin** from the Traefik Pilot dashboard.
To learn more about Traefik plugins, consult the [documentation](https://doc.traefik.io/traefik-pilot/plugins/overview/).
!!! danger "Experimental Features"
Plugins can potentially modify the behavior of Traefik in unforeseen ways.
Exercise caution when adding new plugins to production Traefik instances.
## Build Your Own Plugins
Traefik users can create their own plugins and contribute them to the Traefik Pilot catalog to share them with the community.
Traefik plugins are loaded dynamically.
They need not be compiled, and no complex toolchain is necessary to build them.
The experience of implementing a Traefik plugin is comparable to writing a web browser extension.
To learn more and see code for example Traefik plugins, please see the [developer documentation](https://doc.traefik.io/traefik-pilot/plugins/plugin-dev/).

View File

@@ -1,38 +0,0 @@
# Plugins and Traefik Pilot
Overview
{: .subtitle}
Traefik Pilot is a software-as-a-service (SaaS) platform that connects to Traefik to extend its capabilities.
It does this through *plugins*, which are dynamically loaded components that enable new features.
For example, Traefik plugins can add features to modify requests or headers, issue redirects, add authentication, and so on, providing similar functionality to Traefik [middlewares](https://doc.traefik.io/traefik/middlewares/overview/).
Traefik Pilot can also monitor connected Traefik instances and issue alerts when one is not responding, or when it is subject to security vulnerabilities.
!!! note "Availability"
Plugins are available for Traefik v2.3.0-rc1 and later.
!!! danger "Experimental Features"
Plugins can potentially modify the behavior of Traefik in unforeseen ways.
Exercise caution when adding new plugins to production Traefik instances.
## Connecting to Traefik Pilot
Plugins are available when a Traefik instance is connected to Traefik Pilot.
To register a new instance and begin working with plugins, login or create an account at the [Traefik Pilot homepage](https://pilot.traefik.io) and choose **Register New Instance**.
To complete the connection, Traefik Pilot will issue a token that must be added to your Traefik static configuration by following the instructions provided.
!!! note "Enabling Alerts"
Health and security alerts for registered Traefik instances can be enabled from the Preferences in your [Traefik Pilot Profile](https://pilot.traefik.io/profile).
## Creating Plugins
Traefik users can create their own plugins and contribute them to the Traefik Pilot catalog to share them with the community.
Plugins are written in [Go](https://golang.org/) and their code is executed by an [embedded Go interpreter](https://github.com/traefik/yaegi).
There is no need to compile binaries and all plugins are 100% cross-platform.
To learn more and see code for example Traefik plugins, please see the [developer documentation](https://github.com/traefik/plugindemo).

View File

@@ -1,122 +0,0 @@
# Using Plugins
Plugins are available to any instance of Traefik v2.3 or later that is [registered](overview.md#connecting-to-traefik-pilot) with Traefik Pilot.
Plugins are hosted on GitHub, but you can browse plugins to add to your registered Traefik instances from the Traefik Pilot UI.
!!! danger "Experimental Features"
Plugins can potentially modify the behavior of Traefik in unforeseen ways.
Exercise caution when adding new plugins to production Traefik instances.
## Add a Plugin
To add a new plugin to a Traefik instance, you must modify that instance's static configuration.
The code to be added is provided by the Traefik Pilot UI when you choose **Install the Plugin**.
In the example below, we add the [`blockpath`](http://github.com/traefik/plugin-blockpath) and [`rewritebody`](https://github.com/traefik/plugin-rewritebody) plugins:
```toml tab="File (TOML)"
[entryPoints]
[entryPoints.web]
address = ":80"
[pilot]
token = "xxxxxxxxx"
[experimental.plugins]
[experimental.plugins.block]
modulename = "github.com/traefik/plugin-blockpath"
version = "v0.2.0"
[experimental.plugins.rewrite]
modulename = "github.com/traefik/plugin-rewritebody"
version = "v0.3.0"
```
```yaml tab="File (YAML)"
entryPoints:
web:
address: :80
pilot:
token: xxxxxxxxx
experimental:
plugins:
block:
modulename: github.com/traefik/plugin-blockpath
version: v0.2.0
rewrite:
modulename: github.com/traefik/plugin-rewritebody
version: v0.3.0
```
```bash tab="CLI"
--entryPoints.web.address=:80
--pilot.token=xxxxxxxxx
--experimental.plugins.block.modulename=github.com/traefik/plugin-blockpath
--experimental.plugins.block.version=v0.2.0
--experimental.plugins.rewrite.modulename=github.com/traefik/plugin-rewritebody
--experimental.plugins.rewrite.version=v0.3.0
```
## Configuring Plugins
Some plugins will need to be configured by adding a dynamic configuration.
For the `bodyrewrite` plugin, for example:
```yaml tab="Docker"
labels:
- "traefik.http.middlewares.my-rewritebody.plugin.rewrite.rewrites[0].regex=example"
- "traefik.http.middlewares.my-rewritebody.plugin.rewrite.rewrites[0].replacement=test"
```
```yaml tab="Kubernetes"
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: my-rewritebody
spec:
plugin:
rewrite:
rewrites:
- regex: example
replacement: test
```
```yaml tab="Consul Catalog"
- "traefik.http.middlewares.my-rewritebody.plugin.rewrite.rewrites[0].regex=example"
- "traefik.http.middlewares.my-rewritebody.plugin.rewrite.rewrites[0].replacement=test"
```
```json tab="Marathon"
"labels": {
"traefik.http.middlewares.my-rewritebody.plugin.rewrite.rewrites[0].regex": "example",
"traefik.http.middlewares.my-rewritebody.plugin.rewrite.rewrites[0].replacement": "test"
}
```
```yaml tab="Rancher"
labels:
- "traefik.http.middlewares.my-rewritebody.plugin.rewrite.rewrites[0].regex=example"
- "traefik.http.middlewares.my-rewritebody.plugin.rewrite.rewrites[0].replacement=test"
```
```toml tab="File (TOML)"
[http.middlewares]
  [http.middlewares.my-rewritebody.plugin.rewrite]
lastModified = true
[[http.middlewares.my-rewritebody.plugin.rewrite.rewrites]]
    regex = "example"
replacement = "test"
```
```yaml tab="File (YAML)"
http:
middlewares:
my-rewritebody:
plugin:
rewrite:
rewrites:
- regex: example
replacement: test
```

View File

@@ -164,12 +164,12 @@ Defines the Consul server endpoint.
#### `address`
_Optional, Default="http://127.0.0.1:8500"_
_Optional, Default="127.0.0.1:8500"_
```toml tab="File (TOML)"
[providers.consulCatalog]
[providers.consulCatalog.endpoint]
address = "http://127.0.0.1:8500"
address = "127.0.0.1:8500"
# ...
```
@@ -177,12 +177,12 @@ _Optional, Default="http://127.0.0.1:8500"_
providers:
consulCatalog:
endpoint:
address: http://127.0.0.1:8500
address: 127.0.0.1:8500
# ...
```
```bash tab="CLI"
--providers.consulcatalog.endpoint.address=http://127.0.0.1:8500
--providers.consulcatalog.endpoint.address=127.0.0.1:8500
# ...
```

View File

@@ -144,8 +144,8 @@ You can specify which Docker API Endpoint to use with the directive [`endpoint`]
Accessing the Docker API without any restriction is a security concern:
If Traefik is attacked, then the attacker might get access to the underlying host.
{: #security-note }
As explained in the Docker documentation: ([Docker Daemon Attack Surface page](https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface)):
As explained in the Docker documentation: ([Docker Daemon Attack Surface page](https://docs.docker.com/engine/security/#docker-daemon-attack-surface)):
!!! quote
[...] only **trusted** users should be allowed to control your Docker daemon [...]

View File

@@ -13,18 +13,15 @@ Attach labels to your ECS containers and let Traefik do the rest!
```toml tab="File (TOML)"
[providers.ecs]
clusters = ["default"]
```
```yaml tab="File (YAML)"
providers:
ecs:
clusters:
- default
ecs: {}
```
```bash tab="CLI"
--providers.ecs.clusters=default
--providers.ecs=true
```
## Policy
@@ -90,7 +87,7 @@ _Optional, Default=["default"]_
```toml tab="File (TOML)"
[providers.ecs]
cluster = ["default"]
clusters = ["default"]
# ...
```

View File

@@ -177,26 +177,32 @@ _Optional,Default: empty (process all resources)_
```toml tab="File (TOML)"
[providers.kubernetesCRD]
labelselector = "A and not B"
labelselector = "app=traefik"
# ...
```
```yaml tab="File (YAML)"
providers:
kubernetesCRD:
labelselector: "A and not B"
labelselector: "app=traefik"
# ...
```
```bash tab="CLI"
--providers.kubernetescrd.labelselector="A and not B"
--providers.kubernetescrd.labelselector="app=traefik"
```
By default, Traefik processes all resource objects in the configured namespaces.
A label selector can be defined to filter on specific resource objects only.
A label selector can be defined to filter on specific resource objects only,
this will apply only on Traefik [Custom Resources](../routing/providers/kubernetes-crd.md#custom-resource-definition-crd)
and has no effect on Kubernetes `Secrets`, `Endpoints` and `Services`.
See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details.
!!! warning
As the LabelSelector is applied to all Traefik Custom Resources, they all must match the filter.
### `ingressClass`
_Optional, Default: empty_

View File

@@ -4,7 +4,7 @@ The Kubernetes Ingress Controller.
{: .subtitle }
The Traefik Kubernetes Ingress provider is a Kubernetes Ingress controller; that is to say,
it manages access to a cluster services by supporting the [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) specification.
it manages access to cluster services by supporting the [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) specification.
## Routing Configuration
@@ -212,23 +212,23 @@ _Optional,Default: empty (process all Ingresses)_
```toml tab="File (TOML)"
[providers.kubernetesIngress]
labelSelector = "A and not B"
labelSelector = "app=traefik"
# ...
```
```yaml tab="File (YAML)"
providers:
kubernetesIngress:
labelselector: "A and not B"
labelselector: "app=traefik"
# ...
```
```bash tab="CLI"
--providers.kubernetesingress.labelselector="A and not B"
--providers.kubernetesingress.labelselector="app=traefik"
```
By default, Traefik processes all Ingress objects in the configured namespaces.
A label selector can be defined to filter on specific Ingress objects only.
By default, Traefik processes all `Ingress` objects in the configured namespaces.
A label selector can be defined to filter on specific `Ingress` objects only.
See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors) for details.

View File

@@ -22,6 +22,106 @@ Even if each provider is different, we can categorize them in four groups:
- Annotation based (a separate object, with annotations, defines the characteristics of the container)
- File based (the good old configuration file)
## Provider Namespace
When you declare certain objects, in Traefik dynamic configuration,
such as middleware, service, TLS options or servers transport, they live in its provider's namespace.
For example, if you declare a middleware using a Docker label, under the hoods, it will reside in the docker provider namespace.
If you use multiple providers and wish to reference such an object declared in another provider
(aka referencing a cross-provider object, e.g. middleware), then you'll have to append the `@` separator,
followed by the provider name to the object name.
```text
<resource-name>@<provider-name>
```
!!! important "Kubernetes Namespace"
As Kubernetes also has its own notion of namespace,
one should not confuse the "provider namespace" with the "kubernetes namespace" of a resource when in the context of a cross-provider usage.
In this case, since the definition of a traefik dynamic configuration object is not in kubernetes,
specifying a "kubernetes namespace" when referring to the resource does not make any sense,
and therefore this specification would be ignored even if present.
On the other hand, if you, say, declare a middleware as a Custom Resource in Kubernetes and use the non-crd Ingress objects,
you'll have to add the Kubernetes namespace of the middleware to the annotation like this `<middleware-namespace>-<middleware-name>@kubernetescrd`.
!!! abstract "Referencing a Traefik dynamic configuration object from Another Provider"
Declaring the add-foo-prefix in the file provider.
```toml tab="File (TOML)"
[http.middlewares]
[http.middlewares.add-foo-prefix.addPrefix]
prefix = "/foo"
```
```yaml tab="File (YAML)"
http:
middlewares:
add-foo-prefix:
addPrefix:
prefix: "/foo"
```
Using the add-foo-prefix middleware from other providers:
```yaml tab="Docker"
your-container: #
image: your-docker-image
labels:
# Attach add-foo-prefix@file middleware (declared in file)
- "traefik.http.routers.my-container.middlewares=add-foo-prefix@file"
```
```yaml tab="Kubernetes Ingress Route"
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: ingressroutestripprefix
spec:
entryPoints:
- web
routes:
- match: Host(`example.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.
```
```yaml tab="Kubernetes Ingress"
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: stripprefix
namespace: appspace
spec:
stripPrefix:
prefixes:
- /stripit
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress
namespace: appspace
annotations:
# referencing a middleware from Kubernetes CRD provider:
# <middleware-namespace>-<middleware-name>@kubernetescrd
"traefik.ingress.kubernetes.io/router.middlewares": appspace-stripprefix@kubernetescrd
spec:
# ... regular ingress definition
```
## Supported Providers
Below is the list of the currently supported providers in Traefik.

View File

@@ -330,6 +330,9 @@ TLS key
`--providers.consul.username`:
KV Username
`--providers.consulcatalog`:
Enable ConsulCatalog backend with default settings. (Default: ```false```)
`--providers.consulcatalog.cache`:
Use local agent caching for catalog reads. (Default: ```false```)
@@ -340,7 +343,7 @@ Constraints is an expression that Traefik matches against the container's labels
Default rule. (Default: ```Host(`{{ normalize .Name }}`)```)
`--providers.consulcatalog.endpoint.address`:
The address of the Consul server (Default: ```http://127.0.0.1:8500```)
The address of the Consul server (Default: ```127.0.0.1:8500```)
`--providers.consulcatalog.endpoint.datacenter`:
Data center to use. If not provided, the default agent data center is used
@@ -435,6 +438,9 @@ Use the ip address from the bound port, rather than from the inner network. (Def
`--providers.docker.watch`:
Watch Docker Swarm events. (Default: ```true```)
`--providers.ecs`:
Enable AWS ECS backend with default settings. (Default: ```false```)
`--providers.ecs.accesskeyid`:
The AWS credentials access key to use for making requests

View File

@@ -303,6 +303,9 @@ Terminating status code (Default: ```503```)
`TRAEFIK_PROVIDERS_CONSUL`:
Enable Consul backend with default settings. (Default: ```false```)
`TRAEFIK_PROVIDERS_CONSULCATALOG`:
Enable ConsulCatalog backend with default settings. (Default: ```false```)
`TRAEFIK_PROVIDERS_CONSULCATALOG_CACHE`:
Use local agent caching for catalog reads. (Default: ```false```)
@@ -313,7 +316,7 @@ Constraints is an expression that Traefik matches against the container's labels
Default rule. (Default: ```Host(`{{ normalize .Name }}`)```)
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_ADDRESS`:
The address of the Consul server (Default: ```http://127.0.0.1:8500```)
The address of the Consul server (Default: ```127.0.0.1:8500```)
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_DATACENTER`:
Data center to use. If not provided, the default agent data center is used
@@ -435,6 +438,9 @@ Use the ip address from the bound port, rather than from the inner network. (Def
`TRAEFIK_PROVIDERS_DOCKER_WATCH`:
Watch Docker Swarm events. (Default: ```true```)
`TRAEFIK_PROVIDERS_ECS`:
Enable AWS ECS backend with default settings. (Default: ```false```)
`TRAEFIK_PROVIDERS_ECS_ACCESSKEYID`:
The AWS credentials access key to use for making requests

View File

@@ -250,6 +250,9 @@
addEntryPointsLabels = true
addServicesLabels = true
[pilot]
token = "foobar"
[ping]
entryPoint = "foobar"
manualRouting = true
@@ -364,8 +367,6 @@
[certificatesResolvers.CertificateResolver1.acme.tlsChallenge]
[experimental]
[experimental.pilot]
token = "foobar"
[experimental.plugins]
[experimental.plugins.Descriptor0]
moduleName = "foobar"

View File

@@ -269,6 +269,8 @@ metrics:
password: foobar
addEntryPointsLabels: true
addServicesLabels: true
pilot:
token: foobar
ping:
entryPoint: foobar
manualRouting: true
@@ -383,8 +385,6 @@ certificatesResolvers:
entryPoint: foobar
tlsChallenge: {}
experimental:
pilot:
token: foobar
plugins:
Descriptor0:
moduleName: foobar

View File

@@ -212,8 +212,8 @@ If both TCP and UDP are wanted for the same port, two entryPoints definitions ar
```
```bash tab="CLI"
entrypoints.specificIPv4.address=192.168.2.7:8888
entrypoints.specificIPv6.address=[2001:db8::1]:8888
--entrypoints.specificIPv4.address=192.168.2.7:8888
--entrypoints.specificIPv6.address=[2001:db8::1]:8888
```
Full details for how to specify `address` can be found in [net.Listen](https://golang.org/pkg/net/#Listen) (and [net.Dial](https://golang.org/pkg/net/#Dial)) of the doc for go.
@@ -745,8 +745,8 @@ entryPoints:
```
```bash tab="CLI"
entrypoints.websecure.address=:443
entrypoints.websecure.http.middlewares=auth@file,strip@file
--entrypoints.websecure.address=:443
--entrypoints.websecure.http.middlewares=auth@file,strip@file
```
### TLS
@@ -792,13 +792,13 @@ entryPoints:
```
```bash tab="CLI"
entrypoints.websecure.address=:443
entrypoints.websecure.http.tls.options=foobar
entrypoints.websecure.http.tls.certResolver=leresolver
entrypoints.websecure.http.tls.domains[0].main=example.com
entrypoints.websecure.http.tls.domains[0].sans=foo.example.com,bar.example.com
entrypoints.websecure.http.tls.domains[1].main=test.com
entrypoints.websecure.http.tls.domains[1].sans=foo.test.com,bar.test.com
--entrypoints.websecure.address=:443
--entrypoints.websecure.http.tls.options=foobar
--entrypoints.websecure.http.tls.certResolver=leresolver
--entrypoints.websecure.http.tls.domains[0].main=example.com
--entrypoints.websecure.http.tls.domains[0].sans=foo.example.com,bar.example.com
--entrypoints.websecure.http.tls.domains[1].main=test.com
--entrypoints.websecure.http.tls.domains[1].sans=foo.test.com,bar.test.com
```
??? example "Let's Encrypt"
@@ -821,6 +821,6 @@ entrypoints.websecure.http.tls.domains[1].sans=foo.test.com,bar.test.com
```
```bash tab="CLI"
entrypoints.websecure.address=:443
entrypoints.websecure.http.tls.certResolver=leresolver
--entrypoints.websecure.address=:443
--entrypoints.websecure.http.tls.certResolver=leresolver
```

View File

@@ -228,6 +228,7 @@ http:
to-whoami-tcp:
service: whoami-tcp
rule: HostSNI(`whoami-tcp.example.com`)
tls: {}
services:
whoami-tcp:

View File

@@ -10,7 +10,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/ecs.md)
- The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/ecs.md).
### General

View File

@@ -619,7 +619,7 @@ Register the `Middleware` [kind](../../reference/dynamic-configuration/kubernete
!!! 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),
(in the reference to the middleware) with the [provider namespace](../../providers/overview.md#provider-namespace),
when the definition of the middleware comes from another provider.
In this context, specifying a namespace when referring to the resource does not make any sense, and will be ignored.
Additionally, when you want to reference a Middleware from the CRD Provider,
@@ -1456,8 +1456,7 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre
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).
the cross-provider [syntax](../../providers/overview.md#provider-namespace) (`middlewarename@provider`) should be used to refer to the TLS option.
Specifying a namespace attribute in this case would not make any sense, and will be ignored.
### Kind: `TLSStore`
@@ -1490,7 +1489,7 @@ or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`Ingres
| Ref | Attribute | Purpose |
|-----|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [1] | `secretName` | The name of the referenced Kubernetes [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) that holds the default certificate for the store. |
| [1] | `secretName` | The name of the referenced Kubernetes [Secret](https://kubernetes.io/docs/concepts/configuration/secret/) that holds the default certificate for the store. |
??? example "Declaring and referencing a TLSStore"

View File

@@ -114,16 +114,11 @@ which in turn will create the resulting routers, services, handlers, etc.
- name: traefik
image: traefik:v2.3
args:
- --log.level=DEBUG
- --api
- --api.insecure
- --entrypoints.web.address=:80
- --providers.kubernetesingress
ports:
- name: web
containerPort: 80
- name: admin
containerPort: 8080
---
apiVersion: v1
@@ -139,10 +134,6 @@ which in turn will create the resulting routers, services, handlers, etc.
port: 80
name: web
targetPort: 80
- protocol: TCP
port: 8080
name: admin
targetPort: 8080
```
```yaml tab="Whoami"
@@ -340,27 +331,380 @@ Please see [this documentation](https://kubernetes.io/docs/concepts/services-net
## TLS
### Communication Between Traefik and Pods
### Enabling TLS via HTTP Options on Entrypoint
Traefik automatically requests endpoint information based on the service provided in the ingress spec.
Although Traefik will connect directly to the endpoints (pods),
it still checks the service port to see if TLS communication is required.
TLS can be enabled through the [HTTP options](../entrypoints.md#tls) of an Entrypoint:
There are 3 ways to configure Traefik to use https to communicate with pods:
```bash tab="CLI"
# Static configuration
--entrypoints.websecure.address=:443
--entrypoints.websecure.http.tls
```
1. If the service port defined in the ingress spec is `443` (note that you can still use `targetPort` to use a different port on your pod).
1. If the service port defined in the ingress spec has a name that starts with https (such as `https-api`, `https-web` or just `https`).
1. If the ingress spec includes the annotation `traefik.ingress.kubernetes.io/service.serversscheme: https`.
```toml tab="File (TOML)"
# Static configuration
[entryPoints.websecure]
address = ":443"
If either of those configuration options exist, then the backend communication protocol is assumed to be TLS,
and will connect via TLS automatically.
[entryPoints.websecure.http.tls]
```
!!! info
```yaml tab="File (YAML)"
# Static configuration
entryPoints:
websecure:
address: ':443'
http:
tls: {}
```
This way, any Ingress attached to this Entrypoint will have TLS termination by default.
??? example "Configuring Kubernetes Ingress Controller with TLS on Entrypoint"
Please note that by enabling TLS communication between traefik and your pods,
you will have to have trusted certificates that have the proper trust chain and IP subject name.
If this is not an option, you may need to skip TLS certificate verification.
See the [insecureSkipVerify](../../routing/overview.md#insecureskipverify) setting for more details.
```yaml tab="RBAC"
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: default
```
```yaml tab="Ingress"
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: myingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
rules:
- host: example.com
http:
paths:
- path: /bar
backend:
serviceName: whoami
servicePort: 80
- path: /foo
backend:
serviceName: whoami
servicePort: 80
```
```yaml tab="Traefik"
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.3
args:
- --entrypoints.websecure.address=:443
- --entrypoints.websecure.http.tls
- --providers.kubernetesingress
ports:
- name: websecure
containerPort: 443
---
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: TCP
port: 443
name: websecure
targetPort: 443
```
```yaml tab="Whoami"
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoami
labels:
app: traefiklabs
name: whoami
spec:
replicas: 2
selector:
matchLabels:
app: traefiklabs
task: whoami
template:
metadata:
labels:
app: traefiklabs
task: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- name: http
port: 80
selector:
app: traefiklabs
task: whoami
```
### Enabling TLS via Annotations
To enable TLS on the underlying router created from an Ingress, one should configure it through annotations:
```yaml
traefik.ingress.kubernetes.io/router.tls: "true"
```
For more options, please refer to the available [annotations](#on-ingress).
??? example "Configuring Kubernetes Ingress Controller with TLS"
```yaml tab="RBAC"
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io
resources:
- ingresses
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: default
```
```yaml tab="Ingress"
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: myingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: true
spec:
rules:
- host: example.com
http:
paths:
- path: /bar
backend:
serviceName: whoami
servicePort: 80
- path: /foo
backend:
serviceName: whoami
servicePort: 80
```
```yaml tab="Traefik"
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.3
args:
- --entrypoints.websecure.address=:443
- --providers.kubernetesingress
ports:
- name: websecure
containerPort: 443
---
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: TCP
port: 443
name: websecure
targetPort: 443
```
```yaml tab="Whoami"
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoami
labels:
app: traefiklabs
name: whoami
spec:
replicas: 2
selector:
matchLabels:
app: traefiklabs
task: whoami
template:
metadata:
labels:
app: traefiklabs
task: whoami
spec:
containers:
- name: whoami
image: traefik/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- name: http
port: 80
selector:
app: traefiklabs
task: whoami
```
### Certificates Management
@@ -382,7 +726,9 @@ and will connect via TLS automatically.
backend:
serviceName: service1
servicePort: 80
# Only selects which certificate(s) should be loaded from the secret, in order to terminate TLS.
# Doesn't enable TLS for that ingress (hence for the underlying router).
# Please see the TLS annotations on ingress made for that purpose.
tls:
- secretName: supersecret
```
@@ -405,6 +751,28 @@ TLS certificates can be managed in Secrets objects.
Only TLS certificates provided by users can be stored in Kubernetes Secrets.
[Let's Encrypt](../../https/acme.md) certificates cannot be managed in Kubernetes Secrets yet.
### Communication Between Traefik and Pods
Traefik automatically requests endpoint information based on the service provided in the ingress spec.
Although Traefik will connect directly to the endpoints (pods),
it still checks the service port to see if TLS communication is required.
There are 3 ways to configure Traefik to use https to communicate with pods:
1. If the service port defined in the ingress spec is `443` (note that you can still use `targetPort` to use a different port on your pod).
1. If the service port defined in the ingress spec has a name that starts with https (such as `https-api`, `https-web` or just `https`).
1. If the ingress spec includes the annotation `traefik.ingress.kubernetes.io/service.serversscheme: https`.
If either of those configuration options exist, then the backend communication protocol is assumed to be TLS,
and will connect via TLS automatically.
!!! info
Please note that by enabling TLS communication between traefik and your pods,
you will have to have trusted certificates that have the proper trust chain and IP subject name.
If this is not an option, you may need to skip TLS certificate verification.
See the [insecureSkipVerify](../../routing/overview.md#insecureskipverify) setting for more details.
## Global Default Backend Ingresses
Ingresses can be created that look like the following:

View File

@@ -133,9 +133,7 @@ nav:
- 'Retry': 'middlewares/retry.md'
- 'StripPrefix': 'middlewares/stripprefix.md'
- 'StripPrefixRegex': 'middlewares/stripprefixregex.md'
- 'Plugins & Traefik Pilot':
- 'Overview': 'plugins/overview.md'
- 'Using Plugins': 'plugins/using-plugins.md'
- 'Plugins & Traefik Pilot': 'plugins/index.md'
- 'Operations':
- 'CLI': 'operations/cli.md'
- 'Dashboard' : 'operations/dashboard.md'
@@ -193,6 +191,7 @@ nav:
- 'Docker': 'reference/dynamic-configuration/docker.md'
- 'Kubernetes CRD': 'reference/dynamic-configuration/kubernetes-crd.md'
- 'Consul Catalog': 'reference/dynamic-configuration/consul-catalog.md'
- 'ECS': 'reference/dynamic-configuration/ecs.md'
- 'KV': 'reference/dynamic-configuration/kv.md'
- 'Marathon': 'reference/dynamic-configuration/marathon.md'
- 'Rancher': 'reference/dynamic-configuration/rancher.md'
- 'KV': 'reference/dynamic-configuration/kv.md'

View File

@@ -22,7 +22,7 @@ find "${PATH_TO_SITE}" -type f -not -path "/app/site/theme/*" \
--alt_ignore="/traefikproxy-vertical-logo-color.svg/" \
--http_status_ignore="0,500,501,503" \
--file_ignore="/404.html/" \
--url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/" \
--url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/" \
'{}' 1>/dev/null
## HTML-proofer options at https://github.com/gjtorikian/html-proofer#configuration

View File

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

View File

@@ -43,6 +43,18 @@
</a>
</div>
<div class="dm-item">
<div class="dmi-image pilot">
<img src="{{ 'assets/images/traefik-pilot-logo.svg' | url }}" alt="Traefik Pilot Documentation" />
</div>
<a class="dmi-details" href="https://doc.traefik.io/traefik-pilot/">
<div class="dmi-title">Traefik Pilot</div>
<div class="dmi-description">
Monitor and Manage your Traefik Instances
</div>
</a>
</div>
</div>
</div>
</div>

6
go.mod
View File

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

13
go.sum
View File

@@ -275,8 +275,8 @@ github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLy
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-acme/lego/v4 v4.0.1 h1:vPwbTYfw5+fOaON9rWCN43iNrPw5cdJBhNMnA8oxBTM=
github.com/go-acme/lego/v4 v4.0.1/go.mod h1:pIFm5tWkXSgiAEfJ/XQCQIvX1cEvHFwbgLZyx8OVSUE=
github.com/go-acme/lego/v4 v4.1.2 h1:1zROppXkTbAIh7J7AydGD3dFICLIocucJY1NTH/wB64=
github.com/go-acme/lego/v4 v4.1.2/go.mod h1:pIFm5tWkXSgiAEfJ/XQCQIvX1cEvHFwbgLZyx8OVSUE=
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=
@@ -764,10 +764,10 @@ github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDW
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/traefik/paerser v0.1.0 h1:B4v1tbvd8YnHsA7spwHKEWJoGrRP+2jYpIozsCMHhl0=
github.com/traefik/paerser v0.1.0/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE=
github.com/traefik/yaegi v0.9.0 h1:v9of1gq/5gR/XeohnboeCNGSJnw1CqiYf6xyBwQSNqI=
github.com/traefik/yaegi v0.9.0/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk=
github.com/traefik/paerser v0.1.1 h1:Suj0iA4hTAV6E4Dh5/++TXAj5u6iTwydBlFssIUz+9w=
github.com/traefik/paerser v0.1.1/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE=
github.com/traefik/yaegi v0.9.7 h1:CbeKjEhy3DoSC8xC4TQF2Mhmd7u3Cjqluz1//x6Vtcs=
github.com/traefik/yaegi v0.9.7/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk=
github.com/transip/gotransip/v6 v6.2.0 h1:0Z+qVsyeiQdWfcAUeJyF0IEKAPvhJwwpwPi2WGtBIiE=
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
@@ -1108,6 +1108,7 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=

View File

@@ -65,7 +65,7 @@ func (s *AccessLogSuite) TestAccessLog(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
waitForTraefik(c, "server1")
@@ -133,7 +133,7 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontend(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
checkStatsForLogFile(c)
@@ -204,7 +204,7 @@ func (s *AccessLogSuite) TestAccessLogDigestAuthMiddleware(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
checkStatsForLogFile(c)
@@ -319,7 +319,7 @@ func (s *AccessLogSuite) TestAccessLogFrontendRedirect(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
checkStatsForLogFile(c)
@@ -372,7 +372,7 @@ func (s *AccessLogSuite) TestAccessLogRateLimit(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
checkStatsForLogFile(c)
@@ -423,7 +423,7 @@ func (s *AccessLogSuite) TestAccessLogBackendNotFound(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
waitForTraefik(c, "server1")
@@ -468,7 +468,7 @@ func (s *AccessLogSuite) TestAccessLogFrontendWhitelist(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
checkStatsForLogFile(c)
@@ -515,7 +515,7 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontendSuccess(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
checkStatsForLogFile(c)

View File

@@ -410,7 +410,7 @@ func (s *AcmeSuite) TestNoValidLetsEncryptServer(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Expected traefik works
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.StatusCodeIs(http.StatusOK))
@@ -440,7 +440,7 @@ func (s *AcmeSuite) retrieveAcmeCertificate(c *check.C, testCase acmeTestCase) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// A real file is needed to have the right mode on acme.json file
defer os.Remove("/tmp/acme.json")

View File

@@ -122,7 +122,7 @@ func (s *ConsulCatalogSuite) TestWithNotExposedByDefaultAndDefaultsSettings(c *c
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
c.Assert(err, checker.IsNil)
@@ -181,7 +181,7 @@ func (s *ConsulCatalogSuite) TestByLabels(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8000/whoami", 2*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContainsOr("Hostname: whoami1", "Hostname: whoami2", "Hostname: whoami3"))
c.Assert(err, checker.IsNil)
@@ -216,7 +216,7 @@ func (s *ConsulCatalogSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
c.Assert(err, checker.IsNil)
@@ -255,7 +255,7 @@ func (s *ConsulCatalogSuite) TestRegisterServiceWithoutIP(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080/api/http/services", nil)
c.Assert(err, checker.IsNil)
@@ -294,7 +294,7 @@ func (s *ConsulCatalogSuite) TestDefaultConsulService(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
c.Assert(err, checker.IsNil)
@@ -340,7 +340,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithTCPLabels(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`my.super.host`)"))
c.Assert(err, checker.IsNil)
@@ -398,7 +398,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithLabels(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
c.Assert(err, checker.IsNil)
@@ -465,7 +465,7 @@ func (s *ConsulCatalogSuite) TestSameServiceIDOnDifferentConsulAgent(c *check.C)
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
c.Assert(err, checker.IsNil)
@@ -520,7 +520,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithOneMissingLabels(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil)
c.Assert(err, checker.IsNil)
@@ -572,7 +572,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithHealthCheck(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8000/whoami", 2*time.Second, try.StatusCodeIs(http.StatusNotFound))
c.Assert(err, checker.IsNil)

View File

@@ -118,7 +118,7 @@ func (s *ConsulSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second,

View File

@@ -55,7 +55,7 @@ func (s *DockerComposeSuite) TestComposeScale(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req := testhelpers.MustNewRequest(http.MethodGet, "http://127.0.0.1:8000/whoami", nil)
req.Host = "my.super.host"

View File

@@ -98,7 +98,7 @@ func (s *DockerSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// TODO validate : run on 80
// Expected a 404 as we did not configure anything
@@ -125,7 +125,7 @@ func (s *DockerSuite) TestDefaultDockerContainers(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil)
c.Assert(err, checker.IsNil)
@@ -170,7 +170,7 @@ func (s *DockerSuite) TestDockerContainersWithTCPLabels(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`my.super.host`)"))
c.Assert(err, checker.IsNil)
@@ -210,7 +210,7 @@ func (s *DockerSuite) TestDockerContainersWithLabels(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil)
c.Assert(err, checker.IsNil)
@@ -260,7 +260,7 @@ func (s *DockerSuite) TestDockerContainersWithOneMissingLabels(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil)
c.Assert(err, checker.IsNil)
@@ -297,7 +297,7 @@ func (s *DockerSuite) TestRestartDockerContainers(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil)
c.Assert(err, checker.IsNil)

View File

@@ -36,7 +36,7 @@ func (s *ErrorPagesSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
frontendReq, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080", nil)
c.Assert(err, checker.IsNil)
@@ -58,7 +58,7 @@ func (s *ErrorPagesSuite) TestErrorPage(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
frontendReq, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080", nil)
c.Assert(err, checker.IsNil)

View File

@@ -118,7 +118,7 @@ func (s *EtcdSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second,

View File

@@ -25,7 +25,7 @@ func (s *FileSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Expected a 404 as we did not configure anything
err = try.GetRequest("http://127.0.0.1:8000/", 1000*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))
@@ -38,7 +38,7 @@ func (s *FileSuite) TestSimpleConfigurationNoPanic(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Expected a 404 as we did not configure anything
err = try.GetRequest("http://127.0.0.1:8000/", 1000*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))
@@ -50,7 +50,7 @@ func (s *FileSuite) TestDirectoryConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Expected a 404 as we did not configure anything at /test
err = try.GetRequest("http://127.0.0.1:8000/test", 1000*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))

View File

@@ -3,6 +3,8 @@ kind: Ingress
metadata:
name: test.ingress
namespace: default
labels:
app: traefik
spec:
rules:

View File

@@ -3,6 +3,8 @@ kind: IngressRoute
metadata:
name: test.route
namespace: default
labels:
app: traefik
spec:
entryPoints:

View File

@@ -3,6 +3,8 @@ kind: TLSOption
metadata:
name: mytlsoption
namespace: default
labels:
app: traefik
spec:
minVersion: VersionTLS12

View File

@@ -3,6 +3,8 @@ kind: TLSStore
metadata:
name: mytlsstore
namespace: default
labels:
app: traefik
spec:
defaultCertificate:

View File

@@ -50,6 +50,8 @@ kind: IngressRoute
metadata:
name: api.route
namespace: default
labels:
app: traefik
spec:
entryPoints:

View File

@@ -0,0 +1,19 @@
[global]
checkNewVersion = false
sendAnonymousUsage = false
[log]
level = "DEBUG"
[api]
[entryPoints]
[entryPoints.footcp]
address = ":8093"
[entryPoints.fooudp]
address = ":8090/udp"
[entryPoints.web]
address = ":8000"
[providers.kubernetesCRD]
labelSelector = "app=traefik"

View File

@@ -0,0 +1,16 @@
[global]
checkNewVersion = false
sendAnonymousUsage = false
[log]
level = "DEBUG"
[api]
insecure = true
[entryPoints]
[entryPoints.web]
address = ":8000"
[providers.kubernetesIngress]
labelSelector = "app=traefik"

View File

@@ -164,7 +164,7 @@ func (s *GRPCSuite) TestGRPC(c *check.C) {
err = cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)"))
@@ -202,7 +202,7 @@ func (s *GRPCSuite) TestGRPCh2c(c *check.C) {
err = cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)"))
@@ -244,7 +244,7 @@ func (s *GRPCSuite) TestGRPCh2cTermination(c *check.C) {
err = cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)"))
@@ -286,7 +286,7 @@ func (s *GRPCSuite) TestGRPCInsecure(c *check.C) {
err = cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)"))
@@ -333,7 +333,7 @@ func (s *GRPCSuite) TestGRPCBuffer(c *check.C) {
err = cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)"))
@@ -392,7 +392,7 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)"))
@@ -450,7 +450,7 @@ func (s *GRPCSuite) TestGRPCWithRetry(c *check.C) {
err = cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`127.0.0.1`)"))

View File

@@ -18,7 +18,7 @@ func (s *HeadersSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Expected a 404 as we did not configure anything
err = try.GetRequest("http://127.0.0.1:8000/", 1000*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))
@@ -33,7 +33,7 @@ func (s *HeadersSuite) TestCorsResponses(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
backend := startTestServer("9000", http.StatusOK, "")
defer backend.Close()
@@ -122,7 +122,7 @@ func (s *HeadersSuite) TestSecureHeadersResponses(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
backend := startTestServer("9000", http.StatusOK, "")
defer backend.Close()
@@ -171,7 +171,7 @@ func (s *HeadersSuite) TestMultipleSecureHeadersResponses(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
backend := startTestServer("9000", http.StatusOK, "")
defer backend.Close()

View File

@@ -37,7 +37,7 @@ func (s *HealthCheckSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("Host(`test.localhost`)"))
@@ -105,7 +105,7 @@ func (s *HealthCheckSuite) TestMultipleEntrypoints(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Wait for traefik
err = try.GetRequest("http://localhost:8080/api/rawdata", 60*time.Second, try.BodyContains("Host(`test.localhost`)"))
@@ -181,7 +181,7 @@ func (s *HealthCheckSuite) TestPortOverload(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("Host(`test.localhost`)"))
@@ -217,7 +217,7 @@ func (s *HealthCheckSuite) TestMultipleRoutersOnSameService(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("Host(`test.localhost`)"))

View File

@@ -24,7 +24,7 @@ func (s *HostResolverSuite) TestSimpleConfig(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
testCase := []struct {
desc string

View File

@@ -22,7 +22,7 @@ func (s *HTTPSuite) TestSimpleConfiguration(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Expect a 404 as we configured nothing.
err = try.GetRequest("http://127.0.0.1:8000/", time.Second, try.StatusCodeIs(http.StatusNotFound))

View File

@@ -31,7 +31,7 @@ func (s *HTTPSSuite) TestWithSNIConfigHandshake(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.org`)"))
@@ -67,7 +67,7 @@ func (s *HTTPSSuite) TestWithSNIConfigRoute(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`snitest.org`)"))
@@ -123,7 +123,7 @@ func (s *HTTPSSuite) TestWithTLSOptions(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`snitest.org`)"))
@@ -209,7 +209,7 @@ func (s *HTTPSSuite) TestWithConflictingTLSOptions(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`snitest.net`)"))
@@ -279,7 +279,7 @@ func (s *HTTPSSuite) TestWithSNIStrictNotMatchedRequest(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)"))
@@ -305,7 +305,7 @@ func (s *HTTPSSuite) TestWithDefaultCertificate(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)"))
@@ -341,7 +341,7 @@ func (s *HTTPSSuite) TestWithDefaultCertificateNoSNI(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)"))
@@ -377,7 +377,7 @@ func (s *HTTPSSuite) TestWithOverlappingStaticCertificate(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)"))
@@ -414,7 +414,7 @@ func (s *HTTPSSuite) TestWithOverlappingDynamicCertificate(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.com`)"))
@@ -449,7 +449,7 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthentication(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`snitest.org`)"))
@@ -521,7 +521,7 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipleCAs(c *check
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`snitest.org`)"))
@@ -617,7 +617,7 @@ func (s *HTTPSSuite) TestWithClientCertificateAuthenticationMultipleCAsMultipleF
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("Host(`snitest.org`)"))
@@ -701,7 +701,7 @@ func (s *HTTPSSuite) TestWithRootCAsContentForHTTPSOnBackend(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains(backend.URL))
@@ -723,7 +723,7 @@ func (s *HTTPSSuite) TestWithRootCAsFileForHTTPSOnBackend(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains(backend.URL))
@@ -770,7 +770,7 @@ func (s *HTTPSSuite) TestWithSNIDynamicConfigRouteWithNoChange(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
tr1 := &http.Transport{
TLSClientConfig: &tls.Config{
@@ -839,7 +839,7 @@ func (s *HTTPSSuite) TestWithSNIDynamicConfigRouteWithChange(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
tr1 := &http.Transport{
TLSClientConfig: &tls.Config{
@@ -909,7 +909,7 @@ func (s *HTTPSSuite) TestWithSNIDynamicConfigRouteWithTlsConfigurationDeletion(c
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
tr2 := &http.Transport{
TLSClientConfig: &tls.Config{
@@ -986,7 +986,7 @@ func (s *HTTPSSuite) TestEntryPointHttpsRedirectAndPathModification(c *check.C)
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.BodyContains("Host(`example.com`)"))
@@ -1089,7 +1089,7 @@ func (s *HTTPSSuite) TestWithSNIDynamicCaseInsensitive(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("HostRegexp(`{subdomain:[a-z1-9-]+}.www.snitest.com`)"))
@@ -1130,7 +1130,7 @@ func (s *HTTPSSuite) TestWithDomainFronting(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 500*time.Millisecond, try.BodyContains("Host(`site1.www.snitest.com`)"))

View File

@@ -13,6 +13,7 @@ import (
"strings"
"testing"
"text/template"
"time"
"github.com/fatih/structs"
"github.com/go-check/check"
@@ -120,6 +121,15 @@ func (s *BaseSuite) cmdTraefik(args ...string) (*exec.Cmd, *bytes.Buffer) {
return cmd, &out
}
func (s *BaseSuite) killCmd(cmd *exec.Cmd) {
err := cmd.Process.Kill()
if err != nil {
log.WithoutContext().Errorf("Kill: %v", err)
}
time.Sleep(100 * time.Millisecond)
}
func (s *BaseSuite) traefikCmd(args ...string) (*exec.Cmd, func(*check.C)) {
cmd, out := s.cmdTraefik(args...)
return cmd, func(c *check.C) {

View File

@@ -69,22 +69,44 @@ func (s *K8sSuite) TestIngressConfiguration(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
testConfiguration(c, "testdata/rawdata-ingress.json", "8080")
}
func (s *K8sSuite) TestIngressLabelSelector(c *check.C) {
cmd, display := s.traefikCmd(withConfigFile("fixtures/k8s_ingress_label_selector.toml"))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
testConfiguration(c, "testdata/rawdata-ingress-label-selector.json", "8080")
}
func (s *K8sSuite) TestCRDConfiguration(c *check.C) {
cmd, display := s.traefikCmd(withConfigFile("fixtures/k8s_crd.toml"))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
testConfiguration(c, "testdata/rawdata-crd.json", "8000")
}
func (s *K8sSuite) TestCRDLabelSelector(c *check.C) {
cmd, display := s.traefikCmd(withConfigFile("fixtures/k8s_crd_label_selector.toml"))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
testConfiguration(c, "testdata/rawdata-crd-label-selector.json", "8000")
}
func testConfiguration(c *check.C, path, apiPort string) {
err := try.GetRequest("http://127.0.0.1:"+apiPort+"/api/entrypoints", 20*time.Second, try.BodyContains(`"name":"web"`))
c.Assert(err, checker.IsNil)

View File

@@ -95,7 +95,7 @@ func (s *KeepAliveSuite) TestShouldRespectConfiguredBackendHttpKeepAliveTime(c *
err := cmd.Start()
c.Check(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8000/keepalive", time.Duration(1)*time.Second, try.StatusCodeIs(200))
c.Check(err, checker.IsNil)

View File

@@ -34,7 +34,7 @@ func (s *LogRotationSuite) TestAccessLogRotation(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
defer os.Remove(traefikTestAccessLogFile)
@@ -93,7 +93,7 @@ func (s *LogRotationSuite) TestTraefikLogRotation(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
defer os.Remove(traefikTestAccessLogFile)

View File

@@ -79,7 +79,7 @@ func (s *MarathonSuite15) TestConfigurationUpdate(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Wait for Traefik to turn ready.
err = try.GetRequest("http://127.0.0.1:8000/", 2*time.Second, try.StatusCodeIs(http.StatusNotFound))

View File

@@ -91,7 +91,7 @@ func (s *MarathonSuite) TestConfigurationUpdate(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Wait for Traefik to turn ready.
err = try.GetRequest("http://127.0.0.1:8000/", 2*time.Second, try.StatusCodeIs(http.StatusNotFound))

View File

@@ -32,7 +32,7 @@ func (s *ProxyProtocolSuite) TestProxyProtocolTrusted(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://"+haproxyIP+"/whoami", 500*time.Millisecond,
try.StatusCodeIs(http.StatusOK),
@@ -55,7 +55,7 @@ func (s *ProxyProtocolSuite) TestProxyProtocolV2Trusted(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://"+haproxyIP+":81/whoami", 500*time.Millisecond,
try.StatusCodeIs(http.StatusOK),
@@ -77,7 +77,7 @@ func (s *ProxyProtocolSuite) TestProxyProtocolNotTrusted(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://"+haproxyIP+"/whoami", 500*time.Millisecond,
try.StatusCodeIs(http.StatusOK),
@@ -99,7 +99,7 @@ func (s *ProxyProtocolSuite) TestProxyProtocolV2NotTrusted(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://"+haproxyIP+":81/whoami", 500*time.Millisecond,
try.StatusCodeIs(http.StatusOK),

View File

@@ -32,7 +32,7 @@ func (s *RateLimitSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("ratelimit"))
c.Assert(err, checker.IsNil)

View File

@@ -118,7 +118,7 @@ func (s *RedisSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second,

View File

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

View File

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

View File

@@ -28,7 +28,7 @@ func (s *RestSuite) TestSimpleConfigurationInsecure(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for Traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1000*time.Millisecond, try.BodyContains("rest@internal"))
@@ -126,7 +126,7 @@ func (s *RestSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Expected a 404 as we did not configure anything.
err = try.GetRequest("http://127.0.0.1:8000/", 1000*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))

View File

@@ -29,7 +29,7 @@ func (s *RetrySuite) TestRetry(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)"))
c.Assert(err, checker.IsNil)
@@ -51,7 +51,7 @@ func (s *RetrySuite) TestRetryWebsocket(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("PathPrefix(`/`)"))
c.Assert(err, checker.IsNil)

View File

@@ -28,7 +28,7 @@ func (s *SimpleSuite) TestInvalidConfigShouldFail(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.Do(500*time.Millisecond, func() error {
expected := "Near line 0 (last key parsed ''): bare keys cannot contain '{'"
@@ -48,7 +48,7 @@ func (s *SimpleSuite) TestSimpleDefaultConfig(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// TODO validate : run on 80
// Expected a 404 as we did not configure anything
@@ -61,7 +61,7 @@ func (s *SimpleSuite) TestWithWebConfig(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
@@ -72,7 +72,7 @@ func (s *SimpleSuite) TestPrintHelp(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.Do(500*time.Millisecond, func() error {
expected := "Usage:"
@@ -106,7 +106,7 @@ func (s *SimpleSuite) TestRequestAcceptGraceTimeout(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Wait for Traefik to turn ready.
err = try.GetRequest("http://127.0.0.1:8000/", 2*time.Second, try.StatusCodeIs(http.StatusNotFound))
@@ -169,7 +169,7 @@ func (s *SimpleSuite) TestCustomPingTerminationStatusCode(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// Wait for Traefik to turn ready.
err = try.GetRequest("http://127.0.0.1:8001/", 2*time.Second, try.StatusCodeIs(http.StatusNotFound))
@@ -207,7 +207,7 @@ func (s *SimpleSuite) TestStatsWithMultipleEntryPoint(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
@@ -238,7 +238,7 @@ func (s *SimpleSuite) TestNoAuthOnPing(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8001/api/rawdata", 2*time.Second, try.StatusCodeIs(http.StatusUnauthorized))
c.Assert(err, checker.IsNil)
@@ -256,7 +256,7 @@ func (s *SimpleSuite) TestDefaultEntryPointHTTP(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix"))
c.Assert(err, checker.IsNil)
@@ -274,7 +274,7 @@ func (s *SimpleSuite) TestWithNonExistingEntryPoint(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix"))
c.Assert(err, checker.IsNil)
@@ -292,7 +292,7 @@ func (s *SimpleSuite) TestMetricsPrometheusDefaultEntryPoint(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix"))
c.Assert(err, checker.IsNil)
@@ -320,7 +320,7 @@ func (s *SimpleSuite) TestMultipleProviderSameBackendName(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix"))
c.Assert(err, checker.IsNil)
@@ -341,7 +341,7 @@ func (s *SimpleSuite) TestIPStrategyWhitelist(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second, try.BodyContains("override"))
c.Assert(err, checker.IsNil)
@@ -409,7 +409,7 @@ func (s *SimpleSuite) TestXForwardedHeaders(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second,
try.BodyContains("override.remoteaddr.whitelist.docker.local"))
@@ -444,7 +444,7 @@ func (s *SimpleSuite) TestMultiProvider(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1000*time.Millisecond, try.BodyContains("service"))
c.Assert(err, checker.IsNil)
@@ -495,7 +495,7 @@ func (s *SimpleSuite) TestSimpleConfigurationHostRequestTrailingPeriod(c *check.
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
testCases := []struct {
desc string
@@ -539,7 +539,7 @@ func (s *SimpleSuite) TestRouterConfigErrors(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// All errors
err = try.GetRequest("http://127.0.0.1:8080/api/http/routers", 1000*time.Millisecond, try.BodyContains(`["middleware \"unknown@file\" does not exist","found different TLS options for routers on the same host snitest.net, so using the default TLS options instead"]`))
@@ -567,7 +567,7 @@ func (s *SimpleSuite) TestServiceConfigErrors(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/http/services", 1000*time.Millisecond, try.BodyContains(`["the service \"service1@file\" does not have any type defined"]`))
c.Assert(err, checker.IsNil)
@@ -588,7 +588,7 @@ func (s *SimpleSuite) TestTCPRouterConfigErrors(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// router3 has an error because it uses an unknown entrypoint
err = try.GetRequest("http://127.0.0.1:8080/api/tcp/routers/router3@file", 1000*time.Millisecond, try.BodyContains(`entryPoint \"unknown-entrypoint\" doesn't exist`, "no valid entryPoint for this router"))
@@ -608,7 +608,7 @@ func (s *SimpleSuite) TestTCPServiceConfigErrors(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/tcp/services", 1000*time.Millisecond, try.BodyContains(`["the service \"service1@file\" does not have any type defined"]`))
c.Assert(err, checker.IsNil)
@@ -629,7 +629,7 @@ func (s *SimpleSuite) TestUDPRouterConfigErrors(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/udp/routers/router3@file", 1000*time.Millisecond, try.BodyContains(`entryPoint \"unknown-entrypoint\" doesn't exist`, "no valid entryPoint for this router"))
c.Assert(err, checker.IsNil)
@@ -644,7 +644,7 @@ func (s *SimpleSuite) TestUDPServiceConfigErrors(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/udp/services", 1000*time.Millisecond, try.BodyContains(`["the udp service \"service1@file\" does not have any type defined"]`))
c.Assert(err, checker.IsNil)
@@ -674,7 +674,7 @@ func (s *SimpleSuite) TestWRR(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/http/services", 1000*time.Millisecond, try.BodyContains("service1", "service2"))
c.Assert(err, checker.IsNil)
@@ -721,7 +721,7 @@ func (s *SimpleSuite) TestWRRSticky(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/http/services", 1000*time.Millisecond, try.BodyContains("service1", "service2"))
c.Assert(err, checker.IsNil)
@@ -785,7 +785,7 @@ func (s *SimpleSuite) TestMirror(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/http/services", 1000*time.Millisecond, try.BodyContains("mirror1", "mirror2", "service1"))
c.Assert(err, checker.IsNil)
@@ -865,7 +865,7 @@ func (s *SimpleSuite) TestMirrorWithBody(c *check.C) {
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/http/services", 1000*time.Millisecond, try.BodyContains("mirror1", "mirror2", "service1"))
c.Assert(err, checker.IsNil)
@@ -892,8 +892,8 @@ func (s *SimpleSuite) TestMirrorWithBody(c *check.C) {
atomic.StoreInt32(&countMirror2, 0)
req, err = http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/whoamiWithMaxBody", bytes.NewBuffer(body5))
req.Header.Set("Size", "5")
c.Assert(err, checker.IsNil)
req.Header.Set("Size", "5")
for i := 0; i < 10; i++ {
response, err := http.DefaultClient.Do(req)
c.Assert(err, checker.IsNil)
@@ -913,8 +913,8 @@ func (s *SimpleSuite) TestMirrorWithBody(c *check.C) {
atomic.StoreInt32(&countMirror2, 0)
req, err = http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/whoamiWithMaxBody", bytes.NewBuffer(body20))
req.Header.Set("Size", "20")
c.Assert(err, checker.IsNil)
req.Header.Set("Size", "20")
for i := 0; i < 10; i++ {
response, err := http.DefaultClient.Do(req)
c.Assert(err, checker.IsNil)
@@ -962,7 +962,7 @@ func (s *SimpleSuite) TestMirrorCanceled(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/http/services", 1000*time.Millisecond, try.BodyContains("mirror1", "mirror2", "service1"))
c.Assert(err, checker.IsNil)
@@ -998,7 +998,7 @@ func (s *SimpleSuite) TestSecureAPI(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8000/secure/api/rawdata", 1*time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
@@ -1030,10 +1030,10 @@ func (s *SimpleSuite) TestContentTypeDisableAutoDetect(c *check.C) {
rw.WriteHeader(http.StatusOK)
bytes, err := ioutil.ReadFile("fixtures/test.pdf")
data, err := ioutil.ReadFile("fixtures/test.pdf")
c.Assert(err, checker.IsNil)
_, err = rw.Write(bytes)
_, err = rw.Write(data)
c.Assert(err, checker.IsNil)
}
}))
@@ -1052,7 +1052,7 @@ func (s *SimpleSuite) TestContentTypeDisableAutoDetect(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))

View File

@@ -30,7 +30,7 @@ func (s *TCPSuite) TestMixed(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("Path(`/test`)"))
c.Assert(err, checker.IsNil)
@@ -80,7 +80,7 @@ func (s *TCPSuite) TestTLSOptions(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`whoami-c.test`)"))
c.Assert(err, checker.IsNil)
@@ -110,7 +110,7 @@ func (s *TCPSuite) TestNonTLSFallback(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`*`)"))
c.Assert(err, checker.IsNil)
@@ -144,7 +144,7 @@ func (s *TCPSuite) TestNonTlsTcp(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`*`)"))
c.Assert(err, checker.IsNil)
@@ -164,7 +164,7 @@ func (s *TCPSuite) TestCatchAllNoTLS(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`*`)"))
c.Assert(err, checker.IsNil)
@@ -184,7 +184,7 @@ func (s *TCPSuite) TestCatchAllNoTLSWithHTTPS(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`*`)"))
c.Assert(err, checker.IsNil)
@@ -276,7 +276,7 @@ func (s *TCPSuite) TestWRR(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI"))
c.Assert(err, checker.IsNil)

View File

@@ -0,0 +1,65 @@
{
"routers": {
"default-api-route-29f28a463fb5d5ba16d2@kubernetescrd": {
"entryPoints": [
"web"
],
"service": "api@internal",
"rule": "PathPrefix(`/api`)",
"status": "enabled",
"using": [
"web"
]
},
"default-test-route-6b204d94623b3df4370c@kubernetescrd": {
"entryPoints": [
"web"
],
"service": "default-test-route-6b204d94623b3df4370c",
"rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/bar`)",
"priority": 12,
"tls": {
"options": "default-mytlsoption"
},
"status": "enabled",
"using": [
"web"
]
}
},
"services": {
"api@internal": {
"status": "enabled",
"usedBy": [
"default-api-route-29f28a463fb5d5ba16d2@kubernetescrd"
]
},
"dashboard@internal": {
"status": "enabled"
},
"default-test-route-6b204d94623b3df4370c@kubernetescrd": {
"loadBalancer": {
"servers": [
{
"url": "http://10.42.0.3:80"
},
{
"url": "http://10.42.0.4:80"
}
],
"passHostHeader": true
},
"status": "enabled",
"usedBy": [
"default-test-route-6b204d94623b3df4370c@kubernetescrd"
],
"serverStatus": {
"http://10.42.0.3:80": "UP",
"http://10.42.0.4:80": "UP"
}
},
"noop@internal": {
"status": "enabled"
}
}
}

View File

@@ -0,0 +1,106 @@
{
"routers": {
"api@internal": {
"entryPoints": [
"traefik"
],
"service": "api@internal",
"rule": "PathPrefix(`/api`)",
"priority": 2147483646,
"status": "enabled",
"using": [
"traefik"
]
},
"dashboard@internal": {
"entryPoints": [
"traefik"
],
"middlewares": [
"dashboard_redirect@internal",
"dashboard_stripprefix@internal"
],
"service": "dashboard@internal",
"rule": "PathPrefix(`/`)",
"priority": 2147483645,
"status": "enabled",
"using": [
"traefik"
]
},
"test-ingress-default-whoami-test-whoami@kubernetes": {
"entryPoints": [
"web"
],
"service": "default-whoami-http",
"rule": "Host(`whoami.test`) \u0026\u0026 PathPrefix(`/whoami`)",
"status": "enabled",
"using": [
"web"
]
}
},
"middlewares": {
"dashboard_redirect@internal": {
"redirectRegex": {
"regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$",
"replacement": "${1}/dashboard/",
"permanent": true
},
"status": "enabled",
"usedBy": [
"dashboard@internal"
]
},
"dashboard_stripprefix@internal": {
"stripPrefix": {
"prefixes": [
"/dashboard/",
"/dashboard"
]
},
"status": "enabled",
"usedBy": [
"dashboard@internal"
]
}
},
"services": {
"api@internal": {
"status": "enabled",
"usedBy": [
"api@internal"
]
},
"dashboard@internal": {
"status": "enabled",
"usedBy": [
"dashboard@internal"
]
},
"default-whoami-http@kubernetes": {
"loadBalancer": {
"servers": [
{
"url": "http://10.42.0.2:80"
},
{
"url": "http://10.42.0.7:80"
}
],
"passHostHeader": true
},
"status": "enabled",
"usedBy": [
"test-ingress-default-whoami-test-whoami@kubernetes"
],
"serverStatus": {
"http://10.42.0.2:80": "UP",
"http://10.42.0.7:80": "UP"
}
},
"noop@internal": {
"status": "enabled"
}
}
}

View File

@@ -29,7 +29,7 @@ func (s *TimeoutSuite) TestForwardingTimeouts(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("Path(`/dialTimeout`)"))
c.Assert(err, checker.IsNil)

View File

@@ -48,7 +48,7 @@ func (s *TLSClientHeadersSuite) TestTLSClientHeaders(c *check.C) {
defer display(c)
err = cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second, try.BodyContains("PathPrefix(`/`)"))
c.Assert(err, checker.IsNil)

View File

@@ -55,7 +55,7 @@ func (s *TracingSuite) TestZipkinRateLimit(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
@@ -105,7 +105,7 @@ func (s *TracingSuite) TestZipkinRetry(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
@@ -132,7 +132,7 @@ func (s *TracingSuite) TestZipkinAuth(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
@@ -169,7 +169,7 @@ func (s *TracingSuite) TestJaegerRateLimit(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
@@ -219,7 +219,7 @@ func (s *TracingSuite) TestJaegerRetry(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
@@ -247,7 +247,7 @@ func (s *TracingSuite) TestJaegerAuth(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
@@ -275,7 +275,7 @@ func (s *TracingSuite) TestJaegerCustomHeader(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
@@ -302,7 +302,7 @@ func (s *TracingSuite) TestJaegerAuthCollector(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))

View File

@@ -70,7 +70,7 @@ func (s *UDPSuite) TestWRR(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContains("whoami-a"))
c.Assert(err, checker.IsNil)

View File

@@ -54,7 +54,7 @@ func (s *WebsocketSuite) TestBase(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))
@@ -104,7 +104,7 @@ func (s *WebsocketSuite) TestWrongOrigin(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))
@@ -154,7 +154,7 @@ func (s *WebsocketSuite) TestOrigin(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))
@@ -214,7 +214,7 @@ func (s *WebsocketSuite) TestWrongOriginIgnoredByServer(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))
@@ -271,7 +271,7 @@ func (s *WebsocketSuite) TestSSLTermination(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))
@@ -333,7 +333,7 @@ func (s *WebsocketSuite) TestBasicAuth(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))
@@ -377,7 +377,7 @@ func (s *WebsocketSuite) TestSpecificResponseFromBackend(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))
@@ -422,7 +422,7 @@ func (s *WebsocketSuite) TestURLWithURLEncodedChar(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))
@@ -477,7 +477,7 @@ func (s *WebsocketSuite) TestSSLhttp2(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))
@@ -536,7 +536,7 @@ func (s *WebsocketSuite) TestHeaderAreForwared(c *check.C) {
err := cmd.Start()
c.Assert(err, check.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))

View File

@@ -118,7 +118,7 @@ func (s *ZookeeperSuite) TestSimpleConfiguration(c *check.C) {
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
// wait for traefik
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 2*time.Second,

View File

@@ -80,6 +80,7 @@ func doOnStruct(field reflect.Value) error {
}
}
}
return nil
}
@@ -107,7 +108,16 @@ func reset(field reflect.Value, name string) error {
}
case reflect.Slice:
if field.Len() > 0 {
field.Set(reflect.MakeSlice(field.Type(), 0, 0))
switch field.Type().Elem().Kind() {
case reflect.String:
slice := reflect.MakeSlice(field.Type(), field.Len(), field.Len())
for j := 0; j < field.Len(); j++ {
slice.Index(j).SetString(maskShort)
}
field.Set(slice)
default:
field.Set(reflect.MakeSlice(field.Type(), 0, 0))
}
}
case reflect.Interface:
if !field.IsNil() {
@@ -130,7 +140,7 @@ func isExported(f reflect.StructField) bool {
func marshal(anomConfig interface{}, indent bool) ([]byte, error) {
if indent {
return json.MarshalIndent(anomConfig, "", " ")
return json.MarshalIndent(anomConfig, "", " ")
}
return json.Marshal(anomConfig)
}

View File

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

View File

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

View File

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

View File

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

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

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

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

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

View File

@@ -23,7 +23,7 @@ type Configuration struct {
TCPRouters map[string]*TCPRouterInfo `json:"tcpRouters,omitempty"`
TCPServices map[string]*TCPServiceInfo `json:"tcpServices,omitempty"`
UDPRouters map[string]*UDPRouterInfo `json:"udpRouters,omitempty"`
UDPServices map[string]*UDPServiceInfo `json:"updServices,omitempty"`
UDPServices map[string]*UDPServiceInfo `json:"udpServices,omitempty"`
}
// NewConfig returns a Configuration initialized with the given conf. It never returns nil.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -83,8 +83,8 @@ func TestCommonLogFormatter_Format(t *testing.T) {
},
}
// Set timezone to Alaska to have a constant behavior
os.Setenv("TZ", "US/Alaska")
// Set timezone to Etc/GMT+9 to have a constant behavior
os.Setenv("TZ", "Etc/GMT+9")
for _, test := range testCases {
test := test

View File

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

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