mirror of
https://github.com/containous/traefik.git
synced 2025-09-16 17:44:30 +03:00
Compare commits
51 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
76e35a09b7 | ||
|
d2c1d39d42 | ||
|
e9cccf6504 | ||
|
1c505903ff | ||
|
53ed8e04ae | ||
|
be0845af02 | ||
|
f83a57b3da | ||
|
08264749f0 | ||
|
a75819cae3 | ||
|
9fb32a47ca | ||
|
4f43c9ebb4 | ||
|
9177982334 | ||
|
52eeff9f9f | ||
|
0fcccd35ff | ||
|
598dcf6b62 | ||
|
459200dd01 | ||
|
af22cabc6f | ||
|
920e82f11a | ||
|
9bdf9e1e02 | ||
|
3a45f05e36 | ||
|
8e3e387be7 | ||
|
267d0b7b5a | ||
|
f5b290b093 | ||
|
4ea1c98ac9 | ||
|
db007efe00 | ||
|
a0c02f62a3 | ||
|
ff7b814edc | ||
|
ea459e9af0 | ||
|
2dd5a53db2 | ||
|
fc97ea7ee0 | ||
|
582d2540af | ||
|
6ad79dcd45 | ||
|
721896ba70 | ||
|
228270414c | ||
|
2683df7b5b | ||
|
3e61d1f233 | ||
|
04c07227f2 | ||
|
2e8d99c5b8 | ||
|
c07301473b | ||
|
b1ba42410b | ||
|
b80f89e3db | ||
|
5c853766e8 | ||
|
d2435cf43b | ||
|
556f7608db | ||
|
a4df4b028e | ||
|
63683d35fc | ||
|
495344591f | ||
|
4e508499da | ||
|
e4a3df3516 | ||
|
3506cbd5e9 | ||
|
ab13019bde |
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -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
1
.gitignore
vendored
@@ -17,3 +17,4 @@
|
||||
cover.out
|
||||
vendor/
|
||||
plugins-storage/
|
||||
traefik_changelog.md
|
||||
|
@@ -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]
|
||||
|
64
CHANGELOG.md
64
CHANGELOG.md
@@ -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)
|
||||
|
||||
|
@@ -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/
|
||||
|
14
README.md
14
README.md
@@ -8,7 +8,7 @@
|
||||
[](https://goreportcard.com/report/traefik/traefik)
|
||||
[](https://microbadger.com/images/traefik)
|
||||
[](https://github.com/traefik/traefik/blob/master/LICENSE.md)
|
||||
[](https://community.containo.us/)
|
||||
[](https://community.traefik.io/)
|
||||
[](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: [](https://community.containo.us/)
|
||||
- join the Traefik community forum: [](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 .
|
||||
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/).
|
||||
|
@@ -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
|
||||
|
@@ -20,5 +20,5 @@
|
||||
|
||||
.product-switcher .nav-dropdown-menu--products .nav-dropdown-menu-wrapper {
|
||||
width: auto;
|
||||
height: auto;
|
||||
height: 335px;
|
||||
}
|
||||
|
@@ -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 it’s 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
|
||||
|
||||
|
@@ -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 you’re 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).
|
||||
|
@@ -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 \
|
||||
|
@@ -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:
|
||||
|
@@ -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
|
||||
|
@@ -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`
|
||||
|
@@ -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 |
|
||||
|
@@ -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
|
||||
|
49
docs/content/plugins/index.md
Normal file
49
docs/content/plugins/index.md
Normal 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/).
|
@@ -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).
|
@@ -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
|
||||
```
|
@@ -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
|
||||
# ...
|
||||
```
|
||||
|
||||
|
@@ -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 [...]
|
||||
|
@@ -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"]
|
||||
# ...
|
||||
```
|
||||
|
||||
|
@@ -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_
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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"
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
```
|
||||
|
@@ -228,6 +228,7 @@ http:
|
||||
to-whoami-tcp:
|
||||
service: whoami-tcp
|
||||
rule: HostSNI(`whoami-tcp.example.com`)
|
||||
tls: {}
|
||||
|
||||
services:
|
||||
whoami-tcp:
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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"
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -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'
|
||||
|
@@ -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
|
||||
|
||||
|
2
docs/theme/partials/company-header.html
vendored
2
docs/theme/partials/company-header.html
vendored
@@ -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
|
||||
|
12
docs/theme/partials/product-switcher.html
vendored
12
docs/theme/partials/product-switcher.html
vendored
@@ -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
6
go.mod
@@ -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
13
go.sum
@@ -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=
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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")
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
|
@@ -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"
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
|
@@ -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))
|
||||
|
@@ -3,6 +3,8 @@ kind: Ingress
|
||||
metadata:
|
||||
name: test.ingress
|
||||
namespace: default
|
||||
labels:
|
||||
app: traefik
|
||||
|
||||
spec:
|
||||
rules:
|
||||
|
@@ -3,6 +3,8 @@ kind: IngressRoute
|
||||
metadata:
|
||||
name: test.route
|
||||
namespace: default
|
||||
labels:
|
||||
app: traefik
|
||||
|
||||
spec:
|
||||
entryPoints:
|
||||
|
@@ -3,6 +3,8 @@ kind: TLSOption
|
||||
metadata:
|
||||
name: mytlsoption
|
||||
namespace: default
|
||||
labels:
|
||||
app: traefik
|
||||
|
||||
spec:
|
||||
minVersion: VersionTLS12
|
||||
|
@@ -3,6 +3,8 @@ kind: TLSStore
|
||||
metadata:
|
||||
name: mytlsstore
|
||||
namespace: default
|
||||
labels:
|
||||
app: traefik
|
||||
|
||||
spec:
|
||||
defaultCertificate:
|
||||
|
@@ -50,6 +50,8 @@ kind: IngressRoute
|
||||
metadata:
|
||||
name: api.route
|
||||
namespace: default
|
||||
labels:
|
||||
app: traefik
|
||||
|
||||
spec:
|
||||
entryPoints:
|
||||
|
19
integration/fixtures/k8s_crd_label_selector.toml
Normal file
19
integration/fixtures/k8s_crd_label_selector.toml
Normal 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"
|
16
integration/fixtures/k8s_ingress_label_selector.toml
Normal file
16
integration/fixtures/k8s_ingress_label_selector.toml
Normal 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"
|
@@ -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`)"))
|
||||
|
@@ -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()
|
||||
|
@@ -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`)"))
|
||||
|
@@ -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
|
||||
|
@@ -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))
|
||||
|
@@ -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`)"))
|
||||
|
@@ -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) {
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
||||
|
@@ -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))
|
||||
|
@@ -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))
|
||||
|
@@ -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),
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -1,5 +1,5 @@
|
||||
haproxy:
|
||||
image: haproxy
|
||||
image: haproxy:2.2
|
||||
volumes:
|
||||
- ../haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
|
||||
|
||||
|
@@ -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))
|
||||
|
@@ -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)
|
||||
|
@@ -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"))
|
||||
|
@@ -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)
|
||||
|
65
integration/testdata/rawdata-crd-label-selector.json
vendored
Normal file
65
integration/testdata/rawdata-crd-label-selector.json
vendored
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
106
integration/testdata/rawdata-ingress-label-selector.json
vendored
Normal file
106
integration/testdata/rawdata-ingress-label-selector.json
vendored
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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"))
|
||||
|
@@ -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)
|
||||
|
@@ -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"))
|
||||
|
@@ -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,
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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) {
|
||||
|
@@ -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"},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
454
pkg/anonymize/testdata/anonymized-static-config.json
vendored
Normal file
454
pkg/anonymize/testdata/anonymized-static-config.json
vendored
Normal 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
82
pkg/anonymize/testdata/example.json
vendored
Normal 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
82
pkg/anonymize/testdata/expected.json
vendored
Normal 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"
|
||||
}
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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"`
|
||||
}
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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
Reference in New Issue
Block a user