mirror of
https://github.com/containous/traefik.git
synced 2025-09-22 13:44:25 +03:00
Compare commits
75 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
47fb6e036a | ||
|
83fa3f4cc8 | ||
|
c24f75ce0b | ||
|
63929b0341 | ||
|
5d800ba5fe | ||
|
d4f0a9ff62 | ||
|
c4fa96c41e | ||
|
5dd1728bf8 | ||
|
544dc2eaa5 | ||
|
3ff83fc1f8 | ||
|
63f65e5b2a | ||
|
ac8e47579b | ||
|
5487015a83 | ||
|
418cccd307 | ||
|
2a0760412c | ||
|
42d8e6d60d | ||
|
7ba907f261 | ||
|
c72769e2ea | ||
|
02d856b8a5 | ||
|
0d15ac8861 | ||
|
134a767a7f | ||
|
7403b6fb82 | ||
|
121eaced49 | ||
|
512ed086bd | ||
|
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]
|
||||
|
@@ -25,6 +25,7 @@ before_deploy:
|
||||
sudo -E apt-get -yq update;
|
||||
sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install docker-ce=${DOCKER_VERSION}*;
|
||||
docker version;
|
||||
echo "${DOCKERHUB_PASSWORD}" | docker login -u "${DOCKERHUB_USERNAME}" --password-stdin;
|
||||
make build-image;
|
||||
if [ "$TRAVIS_TAG" ]; then
|
||||
make release-packages;
|
||||
@@ -54,4 +55,4 @@ deploy:
|
||||
skip_cleanup: true
|
||||
on:
|
||||
repo: traefik/traefik
|
||||
all_branches: true
|
||||
all_branches: true
|
||||
|
105
CHANGELOG.md
105
CHANGELOG.md
@@ -1,3 +1,108 @@
|
||||
## [v2.3.7](https://github.com/traefik/traefik/tree/v2.3.7) (2021-01-11)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.3.6...v2.3.7)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[k8s,k8s/ingress]** Fix wildcard hostname issue ([#7711](https://github.com/traefik/traefik/pull/7711) by [avdhoot](https://github.com/avdhoot))
|
||||
- **[k8s,k8s/ingress]** Compile kubernetes ingress annotation regex only once ([#7647](https://github.com/traefik/traefik/pull/7647) by [hensur](https://github.com/hensur))
|
||||
- **[middleware,webui]** webui: fix missing custom request and response header names ([#7706](https://github.com/traefik/traefik/pull/7706) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware]** Fix log level on error pages middleware ([#7737](https://github.com/traefik/traefik/pull/7737) by [Nowheresly](https://github.com/Nowheresly))
|
||||
|
||||
**Documentation:**
|
||||
- **[docker]** docs: fix broken links to docker-compose documentation ([#7702](https://github.com/traefik/traefik/pull/7702) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[ecs]** Add ECS to supported providers list ([#7714](https://github.com/traefik/traefik/pull/7714) by [anilmaurya](https://github.com/anilmaurya))
|
||||
- Update copyright year for 2021 ([#7734](https://github.com/traefik/traefik/pull/7734) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.3.6](https://github.com/traefik/traefik/tree/v2.3.6) (2020-12-17)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.3.5...v2.3.6)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[logs]** Update Logrus to v1.7.0 ([#7663](https://github.com/traefik/traefik/pull/7663) by [jspdown](https://github.com/jspdown))
|
||||
- **[plugins]** Update Yaegi to v0.9.8 ([#7659](https://github.com/traefik/traefik/pull/7659) by [ldez](https://github.com/ldez))
|
||||
- **[rules]** Disable router when a rule has an error ([#7680](https://github.com/traefik/traefik/pull/7680) by [ldez](https://github.com/ldez))
|
||||
|
||||
**Documentation:**
|
||||
- **[logs]** Add configuration example for access log filePath ([#7655](https://github.com/traefik/traefik/pull/7655) by [wernerfred](https://github.com/wernerfred))
|
||||
- **[middleware]** Add missing quotes in errorpages k8s example yaml ([#7675](https://github.com/traefik/traefik/pull/7675) by [icelynjennings](https://github.com/icelynjennings))
|
||||
|
||||
## [v2.3.5](https://github.com/traefik/traefik/tree/v2.3.5) (2020-12-10)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.3.4...v2.3.5)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Update go-acme/lego to v4.1.3 ([#7625](https://github.com/traefik/traefik/pull/7625) by [ldez](https://github.com/ldez))
|
||||
- **[k8s,k8s/crd]** IngressRoute: add an option to disable cross-namespace routing ([#7595](https://github.com/traefik/traefik/pull/7595) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[k8s/crd,k8s/ingress]** Fix concatenation of IPv6 addresses and ports ([#7620](https://github.com/traefik/traefik/pull/7620) by [jspdown](https://github.com/jspdown))
|
||||
- **[tcp,tls]** Fix TLS options fallback when domain and options are the same ([#7609](https://github.com/traefik/traefik/pull/7609) by [jspdown](https://github.com/jspdown))
|
||||
- **[webui]** Fix UI bug on long service name ([#7535](https://github.com/traefik/traefik/pull/7535) by [ipinak](https://github.com/ipinak))
|
||||
|
||||
**Documentation:**
|
||||
- **[docker]** Add example for multiple service per container ([#7610](https://github.com/traefik/traefik/pull/7610) by [notsureifkevin](https://github.com/notsureifkevin))
|
||||
- Documentation: Add spacing to sidebars so the last item is always visible ([#7616](https://github.com/traefik/traefik/pull/7616) by [paulocfjunior](https://github.com/paulocfjunior))
|
||||
- Fix typos in migration guide ([#7596](https://github.com/traefik/traefik/pull/7596) by [marsavela](https://github.com/marsavela))
|
||||
|
||||
## [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/
|
||||
|
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2020 Containous SAS; 2020 Traefik Labs
|
||||
Copyright (c) 2016-2020 Containous SAS; 2020-2021 Traefik Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
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
|
||||
|
@@ -35,6 +35,10 @@
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.md-sidebar__scrollwrap {
|
||||
max-height: calc(100% - 50px);
|
||||
}
|
||||
|
||||
.md-sidebar--secondary .md-sidebar__scrollwrap {
|
||||
border-radius: 8px;
|
||||
background-color: var(--light-blue) !important;
|
||||
|
@@ -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
|
||||
|
@@ -28,7 +28,7 @@ metadata:
|
||||
spec:
|
||||
errors:
|
||||
status:
|
||||
- 500-599
|
||||
- "500-599"
|
||||
query: /{status}.html
|
||||
service:
|
||||
name: whoami
|
||||
|
@@ -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 |
|
||||
|
@@ -385,7 +385,7 @@ To apply a redirection:
|
||||
|
||||
entryPoints:
|
||||
web:
|
||||
address: 80
|
||||
address: ":80"
|
||||
http:
|
||||
redirections:
|
||||
entrypoint:
|
||||
@@ -393,7 +393,7 @@ To apply a redirection:
|
||||
scheme: https
|
||||
|
||||
websecure:
|
||||
address: 443
|
||||
address: ":443"
|
||||
```
|
||||
|
||||
!!! example "HTTP to HTTPS redirection per domain"
|
||||
|
@@ -26,6 +26,20 @@ accessLog: {}
|
||||
By default access logs are written to the standard output.
|
||||
To write the logs into a log file, use the `filePath` option.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[accessLog]
|
||||
filePath = "/path/to/access.log"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
accessLog:
|
||||
filePath: "/path/to/access.log"
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--accesslog.filepath=/path/to/access.log
|
||||
```
|
||||
|
||||
### `format`
|
||||
|
||||
By default, logs are written using the Common Log Format (CLF).
|
||||
@@ -60,7 +74,6 @@ accessLog:
|
||||
|
||||
```bash tab="CLI"
|
||||
# Configuring a buffer of 100 lines
|
||||
--accesslog=true
|
||||
--accesslog.filepath=/path/to/access.log
|
||||
--accesslog.bufferingsize=100
|
||||
```
|
||||
@@ -74,7 +87,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
|
||||
@@ -103,7 +116,6 @@ accessLog:
|
||||
|
||||
```bash tab="CLI"
|
||||
# Configuring Multiple Filters
|
||||
--accesslog=true
|
||||
--accesslog.filepath=/path/to/access.log
|
||||
--accesslog.format=json
|
||||
--accesslog.filters.statuscodes=200,300-302
|
||||
@@ -163,7 +175,6 @@ accessLog:
|
||||
|
||||
```bash tab="CLI"
|
||||
# Limiting the Logs to Specific Fields
|
||||
--accesslog=true
|
||||
--accesslog.filepath=/path/to/access.log
|
||||
--accesslog.format=json
|
||||
--accesslog.fields.defaultmode=keep
|
||||
@@ -198,7 +209,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 +218,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
|
||||
@@ -238,7 +249,6 @@ services:
|
||||
environment:
|
||||
- TZ=US/Alaska
|
||||
command:
|
||||
- --accesslog
|
||||
- --accesslog.fields.names.StartUTC=drop
|
||||
- --providers.docker
|
||||
ports:
|
||||
|
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
|
||||
# ...
|
||||
```
|
||||
|
||||
|
@@ -98,8 +98,8 @@ See the list of labels in the dedicated [routing](../routing/providers/docker.md
|
||||
By default, Traefik watches for [container level labels](https://docs.docker.com/config/labels-custom-metadata/) on a standalone Docker Engine.
|
||||
|
||||
When using Docker Compose, labels are specified by the directive
|
||||
[`labels`](https://docs.docker.com/compose/compose-file/#labels) from the
|
||||
["services" objects](https://docs.docker.com/compose/compose-file/#service-configuration-reference).
|
||||
[`labels`](https://docs.docker.com/compose/compose-file/compose-file-v3/#labels) from the
|
||||
["services" objects](https://docs.docker.com/compose/compose-file/compose-file-v3/#service-configuration-reference).
|
||||
|
||||
!!! tip "Not Only Docker"
|
||||
Please note that any tool like Nomad, Terraform, Ansible, etc.
|
||||
@@ -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 [...]
|
||||
@@ -186,9 +186,9 @@ set the [`swarmMode`](#swarmmode) directive to `true`.
|
||||
While in Swarm Mode, Traefik uses labels found on services, not on individual containers.
|
||||
|
||||
Therefore, if you use a compose file with Swarm Mode, labels should be defined in the
|
||||
[`deploy`](https://docs.docker.com/compose/compose-file/#labels-1) part of your service.
|
||||
[`deploy`](https://docs.docker.com/compose/compose-file/compose-file-v3/#labels-1) part of your service.
|
||||
|
||||
This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file)).
|
||||
This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/compose-file-v3/)).
|
||||
|
||||
### Port Detection
|
||||
|
||||
|
@@ -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_
|
||||
@@ -244,6 +250,34 @@ providers:
|
||||
--providers.kubernetescrd.throttleDuration=10s
|
||||
```
|
||||
|
||||
### `allowCrossNamespace`
|
||||
|
||||
_Optional, Default: true_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.kubernetesCRD]
|
||||
allowCrossNamespace = false
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
kubernetesCRD:
|
||||
allowCrossNamespace: false
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.kubernetescrd.allowCrossNamespace=false
|
||||
```
|
||||
|
||||
If the parameter is set to `false`, an IngressRoute will not be able to reference any resources
|
||||
in another namespace than the IngressRoute namespace.
|
||||
|
||||
!!! warning "Deprecation"
|
||||
|
||||
Please notice that the default value for this option will be set to `false` in a future version.
|
||||
|
||||
## Further
|
||||
|
||||
Also see the [full example](../user-guides/crd-acme/index.md) with Let's Encrypt.
|
||||
|
@@ -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.
|
||||
@@ -31,13 +131,14 @@ Below is the list of the currently supported providers in Traefik.
|
||||
| [Docker](./docker.md) | Orchestrator | Label |
|
||||
| [Kubernetes](./kubernetes-crd.md) | Orchestrator | Custom Resource or Ingress |
|
||||
| [Consul Catalog](./consul-catalog.md) | Orchestrator | Label |
|
||||
| [ECS](./ecs.md) | Orchestrator | Label |
|
||||
| [Marathon](./marathon.md) | Orchestrator | Label |
|
||||
| [Rancher](./rancher.md) | Orchestrator | Label |
|
||||
| [File](./file.md) | Manual | TOML/YAML format |
|
||||
| [Consul](./consul.md) | KV | KV |
|
||||
| [Etcd](./etcd.md) | KV | KV |
|
||||
| [Redis](./redis.md) | KV | KV |
|
||||
| [ZooKeeper](./zookeeper.md) | KV | KV |
|
||||
| [Redis](./redis.md) | KV | KV |
|
||||
| [HTTP](./http.md) | Manual | JSON format |
|
||||
|
||||
!!! info "More Providers"
|
||||
|
@@ -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
|
||||
|
||||
@@ -534,6 +540,9 @@ TLS key
|
||||
`--providers.kubernetescrd`:
|
||||
Enable Kubernetes backend with default settings. (Default: ```false```)
|
||||
|
||||
`--providers.kubernetescrd.allowcrossnamespace`:
|
||||
Allow cross namespace resource reference. (Default: ```true```)
|
||||
|
||||
`--providers.kubernetescrd.certauthfilepath`:
|
||||
Kubernetes certificate authority file path (not needed for in-cluster client).
|
||||
|
||||
|
@@ -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
|
||||
|
||||
@@ -534,6 +540,9 @@ TLS key
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESCRD`:
|
||||
Enable Kubernetes backend with default settings. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESCRD_ALLOWCROSSNAMESPACE`:
|
||||
Allow cross namespace resource reference. (Default: ```true```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_KUBERNETESCRD_CERTAUTHFILEPATH`:
|
||||
Kubernetes certificate authority file path (not needed for in-cluster client).
|
||||
|
||||
|
@@ -113,6 +113,7 @@
|
||||
certAuthFilePath = "foobar"
|
||||
disablePassHostHeaders = true
|
||||
namespaces = ["foobar", "foobar"]
|
||||
allowCrossNamespace = true
|
||||
labelSelector = "foobar"
|
||||
ingressClass = "foobar"
|
||||
throttleDuration = 42
|
||||
@@ -250,6 +251,9 @@
|
||||
addEntryPointsLabels = true
|
||||
addServicesLabels = true
|
||||
|
||||
[pilot]
|
||||
token = "foobar"
|
||||
|
||||
[ping]
|
||||
entryPoint = "foobar"
|
||||
manualRouting = true
|
||||
@@ -364,8 +368,6 @@
|
||||
[certificatesResolvers.CertificateResolver1.acme.tlsChallenge]
|
||||
|
||||
[experimental]
|
||||
[experimental.pilot]
|
||||
token = "foobar"
|
||||
[experimental.plugins]
|
||||
[experimental.plugins.Descriptor0]
|
||||
moduleName = "foobar"
|
||||
|
@@ -123,6 +123,7 @@ providers:
|
||||
namespaces:
|
||||
- foobar
|
||||
- foobar
|
||||
allowCrossNamespace: true
|
||||
labelSelector: foobar
|
||||
ingressClass: foobar
|
||||
throttleDuration: 42s
|
||||
@@ -269,6 +270,8 @@ metrics:
|
||||
password: foobar
|
||||
addEntryPointsLabels: true
|
||||
addServicesLabels: true
|
||||
pilot:
|
||||
token: foobar
|
||||
ping:
|
||||
entryPoint: foobar
|
||||
manualRouting: true
|
||||
@@ -383,8 +386,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:
|
||||
|
@@ -58,6 +58,26 @@ Attach labels to your containers and let Traefik do the rest!
|
||||
Setting the label `traefik.http.services.xxx.loadbalancer.server.port`
|
||||
overrides that behavior.
|
||||
|
||||
??? example "Specifying more than one router and service per container"
|
||||
|
||||
Forwarding requests to more than one port on a container requires referencing the service loadbalancer port definition using the service parameter on the router.
|
||||
|
||||
In this example, requests are forwarded for `http://example-a.com` to `http://<private IP of container>:8000` in addition to `http://example-b.com` forwarding to `http://<private IP of container>:9000`:
|
||||
|
||||
```yaml
|
||||
version: "3"
|
||||
services:
|
||||
my-container:
|
||||
# ...
|
||||
labels:
|
||||
- traefik.http.routers.www-router.rule=Host(`example-a.com`)
|
||||
- traefik.http.routers.www-router.service=www-service
|
||||
- traefik.http.services.www-service.loadbalancer.server.port=8000
|
||||
- traefik.http.routers.admin-router.rule=Host(`example-b.com`)
|
||||
- traefik.http.routers.admin-router.service=admin-service
|
||||
- traefik.http.services.admin-service.loadbalancer.server.port=9000
|
||||
```
|
||||
|
||||
??? example "Configuring Docker Swarm & Deploying / Exposing Services"
|
||||
|
||||
Enabling the docker provider (Swarm Mode)
|
||||
@@ -104,7 +124,7 @@ Attach labels to your containers and let Traefik do the rest!
|
||||
!!! important "Labels in Docker Swarm Mode"
|
||||
While in Swarm Mode, Traefik uses labels found on services, not on individual containers.
|
||||
Therefore, if you use a compose file with Swarm Mode, labels should be defined in the `deploy` part of your service.
|
||||
This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/#labels-1)).
|
||||
This behavior is only enabled for docker-compose version 3+ ([Compose file reference](https://docs.docker.com/compose/compose-file/compose-file-v3/#labels-1)).
|
||||
|
||||
## Routing Configuration
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -26,7 +26,7 @@ theme:
|
||||
prev: 'Previous'
|
||||
next: 'Next'
|
||||
|
||||
copyright: "Copyright © 2016-2020 Containous; 2020 Traefik Labs"
|
||||
copyright: "Copyright © 2016-2020 Containous; 2020-2021 Traefik Labs"
|
||||
|
||||
extra_css:
|
||||
- assets/styles/root.css
|
||||
@@ -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>
|
||||
|
8
go.mod
8
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.3
|
||||
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
|
||||
@@ -68,12 +68,12 @@ require (
|
||||
github.com/prometheus/client_golang v1.3.0
|
||||
github.com/prometheus/client_model v0.1.0
|
||||
github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
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.8
|
||||
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
|
||||
|
16
go.sum
16
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.3 h1:D8nnzrijQFUAqdNPwnbvm6tJ3AJAzQAlnROeecUNG/4=
|
||||
github.com/go-acme/lego/v4 v4.1.3/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=
|
||||
@@ -725,6 +725,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@@ -764,10 +766,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.8 h1:sYGKV2d911B9olVsSO/nRmjIh+CQTffAUSzoyv4a4/4=
|
||||
github.com/traefik/yaegi v0.9.8/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=
|
||||
@@ -972,6 +974,7 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e h1:9vRrk9YW2BTzLP0VCB9ZDjU4cPqkg+IDWL7XgxA1yxQ=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1108,6 +1111,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:
|
||||
|
120
integration/fixtures/k8s/07-ingressroute-cross-namespace.yml
Normal file
120
integration/fixtures/k8s/07-ingressroute-cross-namespace.yml
Normal file
@@ -0,0 +1,120 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: other-ns
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: whoami
|
||||
namespace: other-ns
|
||||
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
selector:
|
||||
app: traefiklabs
|
||||
task: whoami
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: test6.route
|
||||
namespace: other-ns
|
||||
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
routes:
|
||||
- match: Host(`foo.com`) && PathPrefix(`/a`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: whoami
|
||||
namespace: default
|
||||
port: 80
|
||||
- match: Host(`foo.com`) && PathPrefix(`/b`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: wrr2
|
||||
namespace: default
|
||||
kind: TraefikService
|
||||
- match: Host(`foo.com`) && PathPrefix(`/c`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: wrr3
|
||||
kind: TraefikService
|
||||
- match: Host(`foo.com`) && PathPrefix(`/d`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: whoami
|
||||
namespace: other-ns
|
||||
port: 80
|
||||
middlewares:
|
||||
- name: stripprefix2
|
||||
namespace: default
|
||||
- match: Host(`foo.com`) && PathPrefix(`/e`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: whoami
|
||||
port: 80
|
||||
middlewares:
|
||||
- name: test-errorpage
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: wrr2
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
weighted:
|
||||
services:
|
||||
- name: whoami
|
||||
port: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: wrr3
|
||||
namespace: other-ns
|
||||
|
||||
spec:
|
||||
weighted:
|
||||
services:
|
||||
- name: whoami
|
||||
namespace: default
|
||||
port: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: stripprefix2
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
stripPrefix:
|
||||
prefixes:
|
||||
- /tobestripped
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-errorpage
|
||||
|
||||
spec:
|
||||
errors:
|
||||
status:
|
||||
- 500-599
|
||||
query: /{status}.html
|
||||
service:
|
||||
name: whoami
|
||||
namespace: other-ns
|
||||
port: 80
|
@@ -16,3 +16,4 @@
|
||||
address = ":8000"
|
||||
|
||||
[providers.kubernetesCRD]
|
||||
allowCrossNamespace = false
|
||||
|
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"
|
6
integration/fixtures/tlsclientheaders/readme.md
Normal file
6
integration/fixtures/tlsclientheaders/readme.md
Normal file
@@ -0,0 +1,6 @@
|
||||
```bash
|
||||
openssl req -new -newkey rsa:2048 -x509 -days 3650 -nodes -extensions v3_ca -keyout root.key -out root.pem
|
||||
openssl genrsa -out server.key 2048
|
||||
openssl req -nodes -key server.key -new -out server.csr
|
||||
openssl x509 -req -days 3650 -in server.csr -CA root.pem -CAkey root.key -CAcreateserial -out server.pem
|
||||
```
|
@@ -1,21 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDhDCCAmygAwIBAgIJAK4Ed0WF/YNQMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV
|
||||
BAYTAkZSMQ8wDQYDVQQIDAZGUkFOQ0UxETAPBgNVBAcMCFRPVUxPVVNFMRMwEQYD
|
||||
VQQKDApjb250YWlub3VzMQ8wDQYDVQQDDAZzZXJ2ZXIwHhcNMTgwMzIxMTMzOTM4
|
||||
WhcNMjEwMTA4MTMzOTM4WjBXMQswCQYDVQQGEwJGUjEPMA0GA1UECAwGRlJBTkNF
|
||||
MREwDwYDVQQHDAhUT1VMT1VTRTETMBEGA1UECgwKY29udGFpbm91czEPMA0GA1UE
|
||||
AwwGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2DfZMdW1
|
||||
QKmdOTPULt6WUMVFU3PUcovq4cVtvNAzAshduC/7nHZx60uFzVKLYnOfZ+5VYfOS
|
||||
zfVXPvltmBSWga1Yj6CuzfDZwY1nkcoL+22yBD6x4w2nB7aFaPNgj6M4ALVEZRKX
|
||||
lMow+a0c0mOr1kLHm99MT/oabcdI+wbAp8VnLz9DF6SD7iDjIOb4RjvmcyetBzwu
|
||||
1rQYti0bFHOnLCxiz0asXly0zspFajWkbGkvBdvEoP2qOHMeTV604PaBwpIMX/ly
|
||||
ymGgYUctHeC16ptDRDDj7Spmu7ec2NzjgNW+MOth6EkFlhYgg1OEIXP+IFJ5LbS8
|
||||
1t/Y+fDUoc6+IQIDAQABo1MwUTAdBgNVHQ4EFgQUYeZvrzWyLI3TjmTIJYpSTjTb
|
||||
/XUwHwYDVR0jBBgwFoAUYeZvrzWyLI3TjmTIJYpSTjTb/XUwDwYDVR0TAQH/BAUw
|
||||
AwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAYQL8d/WQxu7rE58GC7le53FNzujMNZ+h
|
||||
1kdS35LrTXPv5b6QTi5oUGi5LCesP4HnCpGdMFodyydhY8rhIDZWEFgkJZOLZhdt
|
||||
sAyRONdI/Ms/NGQO2oJD+TlV92e4k3ey4WJyXIFHXE2Apb77VlsiHp8pI/iF/R5t
|
||||
h4o4OADG7k6Fjf/wx7A18ru2eoH+PcwA8i6sQaQ1qEwxC0b3rh2TwaCpFQVcmMv5
|
||||
5jKPRBN0UC0PyHwqFZsSg1folhMAIBAjUsHgA6WleN9zMCyLAIn0LSai1CpFby6o
|
||||
d6xu6pp8pwot8YTL0yS5T0X9aNhK2/uDoP50ei6eWI3uuPa8NJxbyA==
|
||||
MIIDjTCCAnWgAwIBAgIUFrRUuadNNLpobPP9sEgenQ2MTF0wDQYJKoZIhvcNAQEL
|
||||
BQAwVjELMAkGA1UEBhMCRlIxDzANBgNVBAgMBkZyYW5jZTEVMBMGA1UECgwMVHJh
|
||||
ZWZpayBMYWJzMRAwDgYDVQQLDAd0cmFlZmlrMQ0wCwYDVQQDDARyb290MB4XDTIx
|
||||
MDEwODE3NDMxOVoXDTMxMDEwNjE3NDMxOVowVjELMAkGA1UEBhMCRlIxDzANBgNV
|
||||
BAgMBkZyYW5jZTEVMBMGA1UECgwMVHJhZWZpayBMYWJzMRAwDgYDVQQLDAd0cmFl
|
||||
ZmlrMQ0wCwYDVQQDDARyb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEA53rEBDuojC9xslsS6MP8lJvubNmSOqFsGS58KtuTP8bQcuuFuBJzk4HzXoqE
|
||||
k1KQqqeIHZfP11yuto14RGtiRMOSDEfwkNvbcKIqHFyrbaDjjOvkpWVGiVVRycM4
|
||||
59UzKMuv6GgkNQHQDqaKhkxt7GrjUJBNDj/Kg9+1jJz0k181Fz4JsNT0KJ3gdSd1
|
||||
nMggcx8MBZm9F7jFqxDt0xW41UNDLzDTctCFyHAdWzQvFZV5j8A/VLZyTLCAuVZt
|
||||
ljJ4AoO2C02dAxaPxy4gZ6eZYbuS2iHhhGDKwcXwmrwDcwyaWoqy1GKqyV4VhDg+
|
||||
Ue6fwUZvjAaob9oWynXMQoik8wIDAQABo1MwUTAdBgNVHQ4EFgQUxauRsdHLfK/X
|
||||
hb/uWhrmYEDd9VQwHwYDVR0jBBgwFoAUxauRsdHLfK/Xhb/uWhrmYEDd9VQwDwYD
|
||||
VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAmrDLgjgfJnrHKDBMGxcC
|
||||
2NhYrqoeJcGdIsW/TwjNaXaJZZpgAjmHObDR1+49UQhylUzB1a8jesSu2R+aBZXb
|
||||
/0Y9J19q8jbMKEQABqApvwrHLXe9xUVzRTxK3HPlnzSTinS2Il34jc/o3gaYmWuy
|
||||
i7KapY6fhkCivr0zTPXF2l8gLFesuQHkq2cYwZDOwgcaSCVoqeA0ldvo/Pmz2A6L
|
||||
3X4rfpXo10Dh9sClbO78eCxQp2RdtPBVPMqMG/2+sPu4qE/TYKttR0GseOMSYEju
|
||||
kCxmQBS8agUJEdrdFhsTR6Vq2uUO3Qx1r2Oz4xs/jfG/SjMVxcap38hf/QmEq0KA
|
||||
8Q==
|
||||
-----END CERTIFICATE-----
|
||||
|
@@ -1,27 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAo0eupztBxEchz/9BbegBzKX35YUt0S2Xzp/mFM+hXQylWDHB
|
||||
z3wED7R89v3sY6ePTk/tAT5l6uKjmQ/zRlQFf7QtVWKUtYq8rjuFn9/EeC+233mx
|
||||
kVP7QAcuT6T8PzoUgysW6Tx3zz18VDRMnPhx1fjA1jAq3+IU03BpbFz7CkYCxkG/
|
||||
1wWHmsB16LH2bMxJrzapph2nSDnUkoATugSJec+DxTtX1hdjAaJK/JsIwioA/Lyy
|
||||
6YgE2oX7uRZBou0bA3y0TDnFoIVAVqISYWfszTGDlwL+SD/P9GYa19GZk4imdp8j
|
||||
LD/+J9eLuHG75rkROvE4xbSPbGIGkZOEYTmjHwIDAQABAoIBAGok81kroHlkdIqu
|
||||
uW4lYOYVDq5agYp2RTXBpOTqhU/kJKjMz91+FXXQM1ytfbra9sJGGyCv27lyVD/w
|
||||
qomRnXGDQ+U6DMpnwnjRoPBpm2M2QX/NsK11FuRsxqJn8sN3klYi8OX2tTw4EFb9
|
||||
GMECkZ4z88hJz9VzN26sqRwU5e2qw45Fhk+Jl6RBsiBfMGNGsmI5n1yIgvQd2PoM
|
||||
wVxHI+bb3rWL7zE7wy2rb2c+J0P2gy7fZlFN2ZLkC5RjTqdzD2P4erp4gcpgffuO
|
||||
0Epu7ZzuJ0UKCBXJOkhjlM79opLK6IBpF1YgxVCoMPbQVYAHP9hSwuz6hgc0ocwa
|
||||
+6PqzSECgYEA1kTSFN8tHq2VMFgwPyguppSmeJJdIcnMYdicJNkv9YXeIt4mAk9c
|
||||
Qm5eMLoqRJL94fdRDGb7QIqcfSrQODHy5dmqrTZd+TeSc4VRC1gZ7RPg5ja8b0dR
|
||||
DoktPizIYzWrNEaEjhWojqYXT5DOOmNgDbOYrlR6Qdrd6VOmQkIgHz0CgYEAwxSf
|
||||
NMe6LasWg9PYgLeVBcNc9oOjGvczOmNULngte8LpiJm4yzI0gMer20VdCtXYsyR1
|
||||
Zs/rItzSQuvr+3v5qW2NfJ/TaJkZ+bcc/fGJ2LcnM2Kfjfih8DSy5/MBzNM4cqw2
|
||||
arHVvQlAvfOSB8WoFzdXOS41Z+BumLsZE3/mMYsCgYBGNTKpCB+ep730o1DbwOzY
|
||||
RGjvpPXDNn4zqWgwYsHmL0EEJ8pIg3x1f/h4+ucSpR9vRTxXVf8JvOFd2gN0BlnS
|
||||
mqnkK6ZLHLxuAcb2cp28IwFULac8xx92JdifQMlASLuaW2jfrZUXeLC2r3oDg8Bb
|
||||
fPeQV7nfjjmcVH5rw4MG+QKBgQCi4RH4oJZLUSEQWo3XEvDjCfYRgWFqv2FPa+W6
|
||||
ku7u+ZPBURAg4D9EEvLjtmt0A47WLCe1+v3JcvQ/mfnDVQTkOKs8lbmPCN3OSNx1
|
||||
DvnYLzwUxFCR2jljdKy3y4cCPI1R+YXJ2ceq+RHMR5Ty1k59a+BwxqsimxncfcL3
|
||||
K//H9wKBgQChT3kvF9Igcdna8g+JneGD6RHXJX1o80QrO+eWma4NozEOmXqA7R7r
|
||||
+GwAyqy9GFM7pwUhHmhJAxILMBxR84EY7kCBvi1VlZ3JbT7w0gjjOqPHklvbsPj9
|
||||
BruA5xPMq1gzCOgejQIRoODtpH1S6Fi/YMTO6eq75qw6minHWi4dPw==
|
||||
MIIEpAIBAAKCAQEAvYK2z8gLPOfFLgXNWP2460aeJ9vrH47x/lhKLlv4amSDHDx8
|
||||
Cmz/6blOUM8XOfMRW1xx++AgChWN9dx/kf7G2xlA5grZxRvUQ6xj7AvFG9TQUA3m
|
||||
uNh2hvm9c3IjaZBNKH27bRKuDIBvZBvXdX4NL/aaFy7w7v7IKxk8j4WkfB23sgyH
|
||||
43g4b7NqKHJugZiedFu5GALmtLbShVOFbjWcre7Wvatdw8dIBmiFJqZQT3UjIuGA
|
||||
gqczIShtLxo4V+XyVkIPmzfPrRV+4zoMFIFOIaj3syyxb4krPBtxhe7nz2cWvvq0
|
||||
wePB2y4YbAAoVY8NYpd5JsMFwZtG6Uk59ygv4QIDAQABAoIBAQCzt3AyX5z4pzsA
|
||||
yBPS3toslI2LcyzogqDO+V9v01wjWSpU7q8bG/8c4NR6Icn+9JlzMJoPqJ35sjMs
|
||||
A20fQKPIR4yaG5QlLpz/iE5CHW9RU2IxaN1yUiUlH1UgVA9tHqFtUr8ZUuung20f
|
||||
XJ/ZFi7fW1cJwURPAWNGK+qYmL5BzDFvM7HC64k9vGik+PR+CseYoykA9Qe6S1Xy
|
||||
QP5WwEGUlbPWRmVhsB3zpnBHshAv9FewV9hDm1PsEG5w1/Rc7hdOXU54XyFxg9fH
|
||||
AzTLimoNEei+LyC/RsjwhafQy7Soa97s81OAz0HWm8zlQNkEHOOJQUwAGFKuQHiW
|
||||
l0A/3FJ5AoGBAPCrZpZMg8ezKN1W8pT7HzKNRfOS6RC6Yo6jg1hUVexz7yGBgdfr
|
||||
rxrh30d7w/hCCd4UeaTQMx7/x6phZWIIVbfqUJKazf+1he2a+u5iwD1BXsqnjOkc
|
||||
pp7vcFzI83osI8/0k9TbbYOGe+EofNxKfK1OWArVU+yPfEXlauTBAm/DAoGBAMmV
|
||||
EH3kCr2G8gLflH0KNpp94YbcNfdcjmiu+uNx6YoyJIOiH+bwO/bauIcvHwsCYs+H
|
||||
OmOxx5L1ffJS9v4dIsq4C29aM8/qOekKHmUZc2gevkKhAbrm9Yce3J+uQze13MFx
|
||||
37OR/kCdBS0JLgGsdQt9RbYh5guu0SZvw5SGdWuLAoGAU8HS+gu28REQ77cKxX5/
|
||||
5P/1kEdYhVHYavvNAjiXjqrqVibUIWkMj7Z8FkykbwnMlVVa4Fj08ZziyBENT4jH
|
||||
DDKnx93IQ23RJlgBbGVBsg/GBZE6IQavljCOUjw9QA+Mhxr/N90Fx/hNtJZ6nc/u
|
||||
hAH38g08H9/vyAOHqATj7DECgYAkh2KprX1UwvNwGdvqnMMwU8dejOEqphcYWT0V
|
||||
ojrT1CpRwDtPuhDjttbhiGRztkb5nGO0VS75LotYMjiX6+e2HIvV7d6durArzq2b
|
||||
XHVRVODdahfKKrgreCg6t3VuzwHl/CCxha8xPkMF2jgADaRYJKdRTetGCrPT50Tl
|
||||
0UfN6QKBgQCfGuM99/K+PiOqsfQBMPvyOYv4UuSVxqwnZ7F/rZ/0WLZZhca/8Fu0
|
||||
On3PSACuhIh7MffXiwn4hnyuws0QB9o00rtyT2/6XetN9LPrvIUqNHs6aMNYm/Hr
|
||||
QIMa0O9ZH///EdvmAfNtxrJcMoIS+Ce6s70rtGwCBGOKQKqqt5g2hQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
@@ -1,19 +1,20 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDKjCCAhICCQDKAJTeuq3LHjANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJG
|
||||
UjEPMA0GA1UECAwGRlJBTkNFMREwDwYDVQQHDAhUT1VMT1VTRTETMBEGA1UECgwK
|
||||
Y29udGFpbm91czEPMA0GA1UEAwwGc2VydmVyMB4XDTE4MDMyMTEzNDM0MVoXDTIx
|
||||
MDEwODEzNDM0MVowVzELMAkGA1UEBhMCRlIxDzANBgNVBAgMBkZSQU5DRTERMA8G
|
||||
A1UEBwwIVE9VTE9VU0UxEzARBgNVBAoMCmNvbnRhaW5vdXMxDzANBgNVBAMMBnNl
|
||||
cnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNHrqc7QcRHIc//
|
||||
QW3oAcyl9+WFLdEtl86f5hTPoV0MpVgxwc98BA+0fPb97GOnj05P7QE+Zerio5kP
|
||||
80ZUBX+0LVVilLWKvK47hZ/fxHgvtt95sZFT+0AHLk+k/D86FIMrFuk8d889fFQ0
|
||||
TJz4cdX4wNYwKt/iFNNwaWxc+wpGAsZBv9cFh5rAdeix9mzMSa82qaYdp0g51JKA
|
||||
E7oEiXnPg8U7V9YXYwGiSvybCMIqAPy8sumIBNqF+7kWQaLtGwN8tEw5xaCFQFai
|
||||
EmFn7M0xg5cC/kg/z/RmGtfRmZOIpnafIyw//ifXi7hxu+a5ETrxOMW0j2xiBpGT
|
||||
hGE5ox8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAPYDdGyNWp7R9j2oxZEbQS4lb
|
||||
+2Ol1r6PFo/zmpB6GK3CSNo65a0DtW/ITeQi97MMgGS1D3wnaFPrwxtp0mEn7HjU
|
||||
uDcufHBqqBsjYC3NEtt+yyxNeYddLD/GdFXw4d6wNRdRaFCq5N1CPQzF4VTdoSLD
|
||||
xsOq/WAHHc2cyZyOprAqm2UXyWXxn4yWZqzDsZ41/v2f3uMNxeqyIEtNZVzTKQBu
|
||||
wWw+jlQKGu0T8Ex1f0jaKI1OPtN5dzaIfO8acHcuNdmnE+hVsoqe17Dckxsj1ORf
|
||||
8ZcZ4qvULVouGINQBP4fcl5jv6TOm1U+ZSk01FcHPmiDEMB6Utyy4ZLHPbmKYg==
|
||||
MIIDNTCCAh0CFD0QQcHXUJuKwMBYDA+bBExVSP26MA0GCSqGSIb3DQEBCwUAMFYx
|
||||
CzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxFTATBgNVBAoMDFRyYWVmaWsg
|
||||
TGFiczEQMA4GA1UECwwHdHJhZWZpazENMAsGA1UEAwwEcm9vdDAeFw0yMTAxMDgx
|
||||
NzQ0MjRaFw0zMTAxMDYxNzQ0MjRaMFgxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZG
|
||||
cmFuY2UxFTATBgNVBAoMDFRyYWVmaWsgTGFiczEQMA4GA1UECwwHdHJhZWZpazEP
|
||||
MA0GA1UEAwwGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
|
||||
vYK2z8gLPOfFLgXNWP2460aeJ9vrH47x/lhKLlv4amSDHDx8Cmz/6blOUM8XOfMR
|
||||
W1xx++AgChWN9dx/kf7G2xlA5grZxRvUQ6xj7AvFG9TQUA3muNh2hvm9c3IjaZBN
|
||||
KH27bRKuDIBvZBvXdX4NL/aaFy7w7v7IKxk8j4WkfB23sgyH43g4b7NqKHJugZie
|
||||
dFu5GALmtLbShVOFbjWcre7Wvatdw8dIBmiFJqZQT3UjIuGAgqczIShtLxo4V+Xy
|
||||
VkIPmzfPrRV+4zoMFIFOIaj3syyxb4krPBtxhe7nz2cWvvq0wePB2y4YbAAoVY8N
|
||||
Ypd5JsMFwZtG6Uk59ygv4QIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQDaPg69wNeF
|
||||
NFisfBJTrscqVCTW+B80gMhpLdxXD+KO0/Wgc5xpB/wLSirNtRQyxAa3+EEcIwJv
|
||||
/wdh8EyjlDLSpFm/8ghntrKhkOfIOPDFE41M5HNfx/Fuh5btKEenOL/XdapqtNUt
|
||||
2ZE4RrsfbL79sPYepa9kDUVi2mCbeH5ollZ0MDU68HpB2YwHbCEuQNk5W3pjYK2N
|
||||
aDkVnxTkfEDM1k+3QydO1lqB5JJmcrs59BEveTqaJ3eeh/0I4OOab6OkTTZ0JNjJ
|
||||
p1573oxO+fce/bfGud8xHY5gSN9huU7U6RsgvO7Dhmal/sDNl8XC8oU90hVDVXZd
|
||||
A7ewh4jjaoIv
|
||||
-----END CERTIFICATE-----
|
||||
|
@@ -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) {
|
||||
|
@@ -53,6 +53,7 @@ func (s *K8sSuite) TearDownSuite(c *check.C) {
|
||||
"./fixtures/k8s/coredns.yaml",
|
||||
"./fixtures/k8s/rolebindings.yaml",
|
||||
"./fixtures/k8s/traefik.yaml",
|
||||
"./fixtures/k8s/ccm.yaml",
|
||||
}
|
||||
|
||||
for _, filename := range generatedFiles {
|
||||
@@ -69,22 +70,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"
|
||||
}
|
||||
}
|
||||
}
|
33
integration/testdata/rawdata-crd.json
vendored
33
integration/testdata/rawdata-crd.json
vendored
@@ -50,6 +50,20 @@
|
||||
"using": [
|
||||
"web"
|
||||
]
|
||||
},
|
||||
"other-ns-test6-route-482e4988e134701d8cc8@kubernetescrd": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"service": "other-ns-wrr3",
|
||||
"rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/c`)",
|
||||
"error": [
|
||||
"the service \"other-ns-wrr3@kubernetescrd\" does not exist"
|
||||
],
|
||||
"status": "disabled",
|
||||
"using": [
|
||||
"web"
|
||||
]
|
||||
}
|
||||
},
|
||||
"middlewares": {
|
||||
@@ -64,6 +78,14 @@
|
||||
"default-test2-route-23c7f4c450289ee29016@kubernetescrd"
|
||||
]
|
||||
},
|
||||
"default-stripprefix2@kubernetescrd": {
|
||||
"stripPrefix": {
|
||||
"prefixes": [
|
||||
"/tobestripped"
|
||||
]
|
||||
},
|
||||
"status": "enabled"
|
||||
},
|
||||
"default-stripprefix@kubernetescrd": {
|
||||
"stripPrefix": {
|
||||
"prefixes": [
|
||||
@@ -172,6 +194,17 @@
|
||||
"default-test3-route-7d0ac22d3d8db4b82618@kubernetescrd"
|
||||
]
|
||||
},
|
||||
"default-wrr2@kubernetescrd": {
|
||||
"weighted": {
|
||||
"services": [
|
||||
{
|
||||
"name": "default-whoami-80",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": "enabled"
|
||||
},
|
||||
"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)
|
||||
@@ -66,6 +66,6 @@ func (s *TLSClientHeadersSuite) TestTLSClientHeaders(c *check.C) {
|
||||
},
|
||||
}
|
||||
|
||||
err = try.RequestWithTransport(request, 2*time.Second, tr, try.BodyContains("Forwarded-Tls-Client-Cert: MIIDKjCCAhICCQDKAJTeuq3LHjANBgkqhkiG9w0BAQsFADBXMQswCQYDVQQGEwJGUjEPMA0GA1UECAwGRlJBTkNFMREwDwYDVQQHDAhUT1VMT1VTRTETMBEGA1UECgwKY29udGFpbm91czEPMA0GA1UEAwwGc2VydmVyMB4XDTE4MDMyMTEzNDM0MVoXDTIxMDEwODEzNDM0MVowVzELMAkGA1UEBhMCRlIxDzANBgNVBAgMBkZSQU5DRTERMA8GA1UEBwwIVE9VTE9VU0UxEzARBgNVBAoMCmNvbnRhaW5vdXMxDzANBgNVBAMMBnNlcnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNHrqc7QcRHIc%2F%2FQW3oAcyl9%2BWFLdEtl86f5hTPoV0MpVgxwc98BA%2B0fPb97GOnj05P7QE%2BZerio5kP80ZUBX%2B0LVVilLWKvK47hZ%2FfxHgvtt95sZFT%2B0AHLk%2Bk%2FD86FIMrFuk8d889fFQ0TJz4cdX4wNYwKt%2FiFNNwaWxc%2BwpGAsZBv9cFh5rAdeix9mzMSa82qaYdp0g51JKAE7oEiXnPg8U7V9YXYwGiSvybCMIqAPy8sumIBNqF%2B7kWQaLtGwN8tEw5xaCFQFaiEmFn7M0xg5cC%2Fkg%2Fz%2FRmGtfRmZOIpnafIyw%2F%2FifXi7hxu%2Ba5ETrxOMW0j2xiBpGThGE5ox8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAPYDdGyNWp7R9j2oxZEbQS4lb%2B2Ol1r6PFo%2FzmpB6GK3CSNo65a0DtW%2FITeQi97MMgGS1D3wnaFPrwxtp0mEn7HjUuDcufHBqqBsjYC3NEtt%2ByyxNeYddLD%2FGdFXw4d6wNRdRaFCq5N1CPQzF4VTdoSLDxsOq%2FWAHHc2cyZyOprAqm2UXyWXxn4yWZqzDsZ41%2Fv2f3uMNxeqyIEtNZVzTKQBuwWw%2BjlQKGu0T8Ex1f0jaKI1OPtN5dzaIfO8acHcuNdmnE%2BhVsoqe17Dckxsj1ORf8ZcZ4qvULVouGINQBP4fcl5jv6TOm1U%2BZSk01FcHPmiDEMB6Utyy4ZLHPbmKYg%3D%3D"))
|
||||
err = try.RequestWithTransport(request, 2*time.Second, tr, try.BodyContains("Forwarded-Tls-Client-Cert: MIIDNTCCAh0CFD0QQcHXUJuKwMBYDA%2BbBExVSP26MA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxFTATBgNVBAoMDFRyYWVmaWsgTGFiczEQMA4GA1UECwwHdHJhZWZpazENMAsGA1UEAwwEcm9vdDAeFw0yMTAxMDgxNzQ0MjRaFw0zMTAxMDYxNzQ0MjRaMFgxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIDAZGcmFuY2UxFTATBgNVBAoMDFRyYWVmaWsgTGFiczEQMA4GA1UECwwHdHJhZWZpazEPMA0GA1UEAwwGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvYK2z8gLPOfFLgXNWP2460aeJ9vrH47x%2FlhKLlv4amSDHDx8Cmz%2F6blOUM8XOfMRW1xx%2B%2BAgChWN9dx%2Fkf7G2xlA5grZxRvUQ6xj7AvFG9TQUA3muNh2hvm9c3IjaZBNKH27bRKuDIBvZBvXdX4NL%2FaaFy7w7v7IKxk8j4WkfB23sgyH43g4b7NqKHJugZiedFu5GALmtLbShVOFbjWcre7Wvatdw8dIBmiFJqZQT3UjIuGAgqczIShtLxo4V%2BXyVkIPmzfPrRV%2B4zoMFIFOIaj3syyxb4krPBtxhe7nz2cWvvq0wePB2y4YbAAoVY8NYpd5JsMFwZtG6Uk59ygv4QIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQDaPg69wNeFNFisfBJTrscqVCTW%2BB80gMhpLdxXD%2BKO0%2FWgc5xpB%2FwLSirNtRQyxAa3%2BEEcIwJv%2Fwdh8EyjlDLSpFm%2F8ghntrKhkOfIOPDFE41M5HNfx%2FFuh5btKEenOL%2FXdapqtNUt2ZE4RrsfbL79sPYepa9kDUVi2mCbeH5ollZ0MDU68HpB2YwHbCEuQNk5W3pjYK2NaDkVnxTkfEDM1k%2B3QydO1lqB5JJmcrs59BEveTqaJ3eeh%2F0I4OOab6OkTTZ0JNjJp1573oxO%2Bfce%2FbfGud8xHY5gSN9huU7U6RsgvO7Dhmal%2FsDNl8XC8oU90hVDVXZdA7ewh4jjaoIv"))
|
||||
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)
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user