Compare commits

..

39 Commits
v2.5.4 ... v2.5

Author SHA1 Message Date
Fernandez Ludovic
f34ea7a34a fix: doc requirements 2022-03-24 23:40:40 +01:00
Philippos Slicher
a70b864c55 Fix typo in metrics overview page 2022-01-21 09:54:07 +01:00
Romain
e5e48d1cc1 Prepare release v2.5.7 2022-01-20 17:08:07 +01:00
Tom Moulard
42a110dd69 Adjust log level from info to debug
Co-authored-by: rhtenhove <rhtenhove@users.noreply.github.com>
2022-01-20 12:36:08 +01:00
Ludovic Fernandez
cf14b8fa92 Update go-acme/lego to v4.6.0 2022-01-20 09:38:07 +01:00
Kevin Pollet
e7dc6ec025 Fix HTTP provider endpoint config example 2022-01-19 19:50:05 +01:00
Romain
67483c1b17 Exclude www.cloudxns.net from documentation verification 2022-01-19 16:10:08 +01:00
mpl
4071f1e7f2 Mitigate memory leak 2022-01-17 14:28:05 +01:00
Ludovic Fernandez
577709fff3 fix: middleware plugins memory leak
Co-authored-by: Julien Salleyron <julien.salleyron@gmail.com>
2022-01-14 12:22:06 +01:00
Tom Moulard
8cd45476ac Fix middleware regexp's display 2022-01-13 18:38:06 +01:00
Martin Rauscher
a9776ceafc Improve regexp matcher documentation 2022-01-10 14:32:04 +01:00
Colin Wilson
e471239955 Remove typo in Kubernetes providers labelSelector examples 2022-01-06 11:58:07 +01:00
Kevin Pollet
2e8156bfaa Update copyright for 2022 2022-01-06 11:34:05 +01:00
Tom Moulard
5e2c929322 Fix broken jaeger documentation link 2021-12-29 15:06:04 +01:00
Tom Moulard
2b5355c849 Update golangci-lint install script 2021-12-23 15:44:05 +01:00
Romain
f21f71786a Prepare release v2.5.6 2021-12-22 17:22:04 +01:00
Tom Moulard
a711f0d037 fix: update goreleaser install link to use gist 2021-12-22 14:12:04 +01:00
Ludovic Fernandez
98fc6ca441 Update Yaegi to v0.11.2 2021-12-22 09:24:05 +01:00
ichx
c10f1a3a36 Add missing API endpoints documentation 2021-12-21 14:48:05 +01:00
Douglas De Toni Machado
79a14ce992 Fix passTLSClientCert CRD example name 2021-12-18 00:52:04 +01:00
Alestrix
99ce26f7b1 Correct documentation in middleware overview 2021-12-17 16:24:06 +01:00
Kevin Pollet
16250361c3 chore: update golang.org/x/net dependency version 2021-12-16 11:52:04 +01:00
Kevin Pollet
be44385b42 fix: process all X-Forwarded-For headers in the request 2021-12-14 15:36:07 +01:00
Tom Moulard
54c77ecb54 Prepare release v2.5.5 2021-12-10 17:52:04 +01:00
tfny
a30f0dcabd Update CODE_OF_CONDUCT.md 2021-12-09 11:00:06 +01:00
Ludovic Fernandez
efef7dce4f plugins: start the go routine before calling Provide 2021-12-08 17:08:05 +01:00
Tom Moulard
1c9e4c6050 doc: align docker configuration example notes in basicauth HTTP middleware 2021-12-07 10:04:05 +01:00
Markus Lippert
92093a8c09 Update go-acme/lego to v4.5.3 2021-12-06 15:44:04 +01:00
Kevin Pollet
f69982aa9d docs: uniformize client TLS config documentation 2021-12-02 15:42:06 +01:00
Tom Moulard
82fdc569c2 docs: removing typo in consul-catalog provider doc 2021-12-01 15:58:05 +01:00
Tom Moulard
def0c1a526 Update yaegi to v0.11.1 2021-11-30 17:36:06 +01:00
Romain Bailly
ef2d03d96e fix: propagate source criterion config to RateLimit middleware in Kubernetes CRD 2021-11-26 12:10:11 +01:00
Kevin Pollet
321c9421ea chore: update docker/cli and containerd dependency versions 2021-11-25 15:34:06 +01:00
Charlie Haley
5a225b4196 test: upgrade docker-compose
Co-authored-by: Rémi Buisson <remi.buisson@traefik.io>
2021-11-25 11:10:06 +01:00
Gustavo Silva
525a6cf5b2 docs: remove misleading metrics overview configuration 2021-11-16 09:38:12 +01:00
Julien Acroute
27ec0912d5 docs: health check use readiness probe in k8s 2021-11-15 11:14:06 +01:00
kerrsmith
0a31225e65 fixed minor spelling error in Regexp Syntax section 2021-11-09 16:50:11 +01:00
Kevin Pollet
db4a92d877 fix: increase UDP read buffer length to max datagram size
Co-authored-by: Tom Moulard <tom.moulard@traefik.io>
2021-11-09 15:12:07 +01:00
Ludovic Fernandez
9df053e3f5 Update yaegi v0.11.0 2021-11-09 14:30:09 +01:00
182 changed files with 2932 additions and 1718 deletions

View File

@@ -48,6 +48,7 @@
extensionsv1beta1 = "k8s.io/api/extensions/v1beta1"
metav1 = "k8s.io/apimachinery/pkg/apis/meta/v1"
kubeerror = "k8s.io/apimachinery/pkg/api/errors"
composeapi = "github.com/docker/compose/v2/pkg/api"
[linters-settings.gomoddirectives]
replace-allow-list = [
@@ -56,6 +57,7 @@
"github.com/gorilla/mux",
"github.com/mailgun/minheap",
"github.com/mailgun/multibuf",
"github.com/jaguilar/vt100",
]
[linters]

View File

@@ -26,48 +26,30 @@ global_job_config:
- mkdir -vp "${SEMAPHORE_GIT_DIR}" "${GOPATH}/bin"
- export GOPROXY=https://proxy.golang.org,direct
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "${GOPATH}/bin" v1.43.0
- curl -sfL https://install.goreleaser.com/github.com/goreleaser/goreleaser.sh | bash -s -- -b "${GOPATH}/bin"
- curl -sSfL https://gist.githubusercontent.com/traefiker/6d7ac019c11d011e4f131bb2cca8900e/raw/goreleaser.sh | bash -s -- -b "${GOPATH}/bin"
- go install github.com/containous/go-bindata/go-bindata@v1.0.0
- checkout
- cache restore traefik-$(checksum go.sum)
blocks:
- name: Test Integration Container
- name: Test Integration
dependencies: []
run:
when: "branch =~ '.*' OR pull_request =~'.*'"
task:
jobs:
- name: Test Integration Container
- name: Test Integration
commands:
- make pull-images
- mkdir -p static # Avoid to generate webui
- PRE_TARGET="" make binary
- make test-integration-container
- make test-integration
- df -h
epilogue:
always:
commands:
- cache store traefik-$(checksum go.sum) $HOME/go/pkg/mod
- name: Test Integration Host
dependencies: []
run:
when: "branch =~ '.*' OR pull_request =~'.*'"
task:
env_vars:
- name: PRE_TARGET
value: ""
jobs:
- name: Test Integration Host
commands:
- mkdir -p static # Avoid to generate webui
- make test-integration-host
epilogue:
always:
commands:
- cache store traefik-$(checksum go.sum) $HOME/go/pkg/mod
- name: Release
dependencies: []
run:
@@ -83,7 +65,7 @@ blocks:
- name: GH_VERSION
value: 1.12.1
- name: CODENAME
value: "livarot"
value: "brie"
- name: PRE_TARGET
value: ""
prologue:

View File

@@ -1,3 +1,53 @@
## [v2.5.7](https://github.com/traefik/traefik/tree/v2.5.7) (2022-01-20)
[All Commits](https://github.com/traefik/traefik/compare/v2.5.6...v2.5.7)
**Bug fixes:**
- **[acme]** Update go-acme/lego to v4.6.0 ([#8716](https://github.com/traefik/traefik/pull/8716) by [ldez](https://github.com/ldez))
- **[logs]** Adjust log level from info to debug ([#8718](https://github.com/traefik/traefik/pull/8718) by [tomMoulard](https://github.com/tomMoulard))
- **[plugins]** Fix middleware plugins memory leak ([#8702](https://github.com/traefik/traefik/pull/8702) by [ldez](https://github.com/ldez))
- **[server]** Mitigate memory leak ([#8706](https://github.com/traefik/traefik/pull/8706) by [mpl](https://github.com/mpl))
- **[webui,middleware]** Fix middleware regexp&#39;s display ([#8697](https://github.com/traefik/traefik/pull/8697) by [tomMoulard](https://github.com/tomMoulard))
**Documentation:**
- **[http]** Fix HTTP provider endpoint config example ([#8715](https://github.com/traefik/traefik/pull/8715) by [kevinpollet](https://github.com/kevinpollet))
- **[k8s]** Remove typo in Kubernetes providers labelSelector examples ([#8676](https://github.com/traefik/traefik/pull/8676) by [colinwilson](https://github.com/colinwilson))
- **[rules]** Improve regexp matcher documentation ([#8686](https://github.com/traefik/traefik/pull/8686) by [Hades32](https://github.com/Hades32))
- **[tracing]** Fix broken jaeger documentation link ([#8665](https://github.com/traefik/traefik/pull/8665) by [tomMoulard](https://github.com/tomMoulard))
- Update copyright for 2022 ([#8679](https://github.com/traefik/traefik/pull/8679) by [kevinpollet](https://github.com/kevinpollet))
## [v2.5.6](https://github.com/traefik/traefik/tree/v2.5.6) (2021-12-22)
[All Commits](https://github.com/traefik/traefik/compare/v2.5.5...v2.5.6)
**Bug fixes:**
- **[middleware]** Process all X-Forwarded-For headers in the request ([#8596](https://github.com/traefik/traefik/pull/8596) by [kevinpollet](https://github.com/kevinpollet))
- **[plugins]** Update Yaegi to v0.11.2 ([#8650](https://github.com/traefik/traefik/pull/8650) by [ldez](https://github.com/ldez))
- **[server]** Update golang.org/x/net dependency version ([#8635](https://github.com/traefik/traefik/pull/8635) by [kevinpollet](https://github.com/kevinpollet))
**Documentation:**
- **[api]** Add missing API endpoints documentation ([#8649](https://github.com/traefik/traefik/pull/8649) by [ichxxx](https://github.com/ichxxx))
- **[middleware]** Fix passTLSClientCert CRD example name ([#8637](https://github.com/traefik/traefik/pull/8637) by [ddtmachado](https://github.com/ddtmachado))
- **[middleware]** Correct documentation in middleware overview ([#8636](https://github.com/traefik/traefik/pull/8636) by [Alestrix](https://github.com/Alestrix))
## [v2.5.5](https://github.com/traefik/traefik/tree/v2.5.5) (2021-12-09)
[All Commits](https://github.com/traefik/traefik/compare/v2.5.4...v2.5.5)
**Bug fixes:**
- **[acme]** Update go-acme/lego to v4.5.3 ([#8607](https://github.com/traefik/traefik/pull/8607) by [lippertmarkus](https://github.com/lippertmarkus))
- **[k8s/crd,k8s]** fix: propagate source criterion config to RateLimit middleware in Kubernetes CRD ([#8591](https://github.com/traefik/traefik/pull/8591) by [rbailly-talend](https://github.com/rbailly-talend))
- **[plugins]** plugins: start the go routine before calling Provide ([#8620](https://github.com/traefik/traefik/pull/8620) by [ldez](https://github.com/ldez))
- **[plugins]** Update yaegi to v0.11.1 ([#8600](https://github.com/traefik/traefik/pull/8600) by [tomMoulard](https://github.com/tomMoulard))
- **[plugins]** Update yaegi v0.11.0 ([#8564](https://github.com/traefik/traefik/pull/8564) by [ldez](https://github.com/ldez))
- **[udp]** fix: increase UDP read buffer length to max datagram size ([#8560](https://github.com/traefik/traefik/pull/8560) by [kevinpollet](https://github.com/kevinpollet))
**Documentation:**
- **[consul]** docs: removing typo in consul-catalog provider doc ([#8603](https://github.com/traefik/traefik/pull/8603) by [tomMoulard](https://github.com/tomMoulard))
- **[metrics]** docs: remove misleading metrics overview configuration ([#8579](https://github.com/traefik/traefik/pull/8579) by [gsilvapt](https://github.com/gsilvapt))
- **[middleware]** docs: align docker configuration example notes in basicauth HTTP middleware ([#8615](https://github.com/traefik/traefik/pull/8615) by [tomMoulard](https://github.com/tomMoulard))
- **[service]** docs: health check use readiness probe in k8s ([#8575](https://github.com/traefik/traefik/pull/8575) by [Vampouille](https://github.com/Vampouille))
- **[tls]** docs: uniformize client TLS config documentation ([#8602](https://github.com/traefik/traefik/pull/8602) by [kevinpollet](https://github.com/kevinpollet))
- Update CODE_OF_CONDUCT.md ([#8619](https://github.com/traefik/traefik/pull/8619) by [tfny](https://github.com/tfny))
- fixed minor spelling error in Regexp Syntax section ([#8565](https://github.com/traefik/traefik/pull/8565) by [kerrsmith](https://github.com/kerrsmith))
## [v2.5.4](https://github.com/traefik/traefik/tree/v2.5.4) (2021-11-08)
[All Commits](https://github.com/traefik/traefik/compare/v2.5.3...v2.5.4)

View File

@@ -2,7 +2,7 @@
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience,nationality, personal appearance, race, religion, or sexual identity and orientation.
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
@@ -30,15 +30,19 @@ Project maintainers have the right and responsibility to remove, edit, or reject
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or our community.
Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
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.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

View File

@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2021 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2022 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

View File

@@ -15,7 +15,7 @@ TRAEFIK_DEV_IMAGE := traefik-dev$(if $(GIT_BRANCH),:$(subst /,-,$(GIT_BRANCH)))
REPONAME := $(shell echo $(REPO) | tr '[:upper:]' '[:lower:]')
TRAEFIK_IMAGE := $(if $(REPONAME),$(REPONAME),"traefik/traefik")
INTEGRATION_OPTS := $(if $(MAKE_DOCKER_HOST),-e "DOCKER_HOST=$(MAKE_DOCKER_HOST)", -e "TEST_CONTAINER=1" -v "/var/run/docker.sock:/var/run/docker.sock")
INTEGRATION_OPTS := $(if $(MAKE_DOCKER_HOST),-e "DOCKER_HOST=$(MAKE_DOCKER_HOST)",-v "/var/run/docker.sock:/var/run/docker.sock")
DOCKER_BUILD_ARGS := $(if $(DOCKER_VERSION), "--build-arg=DOCKER_VERSION=$(DOCKER_VERSION)",)
TRAEFIK_ENVS := \
@@ -32,7 +32,8 @@ TRAEFIK_ENVS := \
TRAEFIK_MOUNT := -v "$(CURDIR)/$(BIND_DIR):/go/src/github.com/traefik/traefik/$(BIND_DIR)"
DOCKER_RUN_OPTS := $(TRAEFIK_ENVS) $(TRAEFIK_MOUNT) "$(TRAEFIK_DEV_IMAGE)"
DOCKER_NON_INTERACTIVE ?= false
DOCKER_RUN_TRAEFIK := docker run --add-host=host.docker.internal:127.0.0.1 $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -it) $(DOCKER_RUN_OPTS)
DOCKER_RUN_TRAEFIK := docker run $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -it) $(DOCKER_RUN_OPTS)
DOCKER_RUN_TRAEFIK_TEST := docker run --add-host=host.docker.internal:127.0.0.1 --rm --name=traefik --network traefik-test-network -v $(PWD):$(PWD) -w $(PWD) $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -it) $(DOCKER_RUN_OPTS)
DOCKER_RUN_TRAEFIK_NOTTY := docker run $(INTEGRATION_OPTS) $(if $(DOCKER_NON_INTERACTIVE), , -i) $(DOCKER_RUN_OPTS)
PRE_TARGET ?= build-dev-image
@@ -81,30 +82,27 @@ crossbinary-default-parallel:
$(MAKE) build-dev-image crossbinary-default
## Run the unit and integration tests
test: build-dev-image
$(DOCKER_RUN_TRAEFIK) ./script/make.sh generate test-unit binary test-integration
test: $(PRE_TARGET)
-docker network create traefik-test-network --driver bridge --subnet 172.31.42.0/24
trap 'docker network rm traefik-test-network' EXIT; \
$(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK_TEST),) ./script/make.sh generate test-unit binary test-integration
## Run the unit tests
test-unit: $(PRE_TARGET)
$(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate test-unit
-docker network create traefik-test-network --driver bridge --subnet 172.31.42.0/24
trap 'docker network rm traefik-test-network' EXIT; \
$(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK_TEST)) ./script/make.sh generate test-unit
## Run the integration tests
test-integration: $(PRE_TARGET)
-docker network create traefik-test-network --driver bridge --subnet 172.31.42.0/24
trap 'docker network rm traefik-test-network' EXIT; \
$(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK_TEST),) ./script/make.sh generate binary test-integration
## Pull all images for integration tests
pull-images:
grep --no-filename -E '^\s+image:' ./integration/resources/compose/*.yml | awk '{print $$2}' | sort | uniq | xargs -P 6 -n 1 docker pull
## Run the integration tests
test-integration: $(PRE_TARGET) binary
$(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK),TEST_CONTAINER=1) ./script/make.sh test-integration
TEST_HOST=1 ./script/make.sh test-integration
## Run the container integration tests
test-integration-container: $(PRE_TARGET) binary
$(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK),TEST_CONTAINER=1) ./script/make.sh test-integration
## Run the host integration tests
test-integration-host: $(PRE_TARGET) binary
TEST_HOST=1 ./script/make.sh test-integration
## Validate code and docs
validate-files: $(PRE_TARGET)
$(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate validate-lint validate-misspell

View File

@@ -19,13 +19,13 @@ 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.43.0
RUN curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | bash -s -- -b $GOPATH/bin v1.43.0
# Download misspell binary to bin folder in $GOPATH
RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4
# Download goreleaser binary to bin folder in $GOPATH
RUN curl -sfL https://install.goreleaser.com/github.com/goreleaser/goreleaser.sh | sh
RUN curl -sfL https://gist.githubusercontent.com/traefiker/6d7ac019c11d011e4f131bb2cca8900e/raw/goreleaser.sh | sh
WORKDIR /go/src/github.com/traefik/traefik

View File

@@ -367,7 +367,9 @@ For complete details, refer to your provider's _Additional configuration_ link.
| [Simply.com](https://www.simply.com/en/domains/) | `simply` | `SIMPLY_ACCOUNT_NAME`, `SIMPLY_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/simply) |
| [Sonic](https://www.sonic.com/) | `sonic` | `SONIC_USER_ID`, `SONIC_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/sonic) |
| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/stackpath) |
| [Tencent Cloud DNS](https://cloud.tencent.com/product/cns) | `tencentcloud` | `TENCENTCLOUD_SECRET_ID`, `TENCENTCLOUD_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/tencentcloud) |
| [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/transip) |
| [UKFast SafeDNS](https://www.ukfast.co.uk/dns-hosting.html) | `safedns` | `SAFEDNS_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/safedns) |
| [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/vegadns) |
| [Versio](https://www.versio.nl/domeinnamen) | `versio` | `VERSIO_USERNAME`, `VERSIO_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/versio) |
| [VinylDNS](https://www.vinyldns.io) | `vinyldns` | `VINYLDNS_ACCESS_KEY`, `VINYLDNS_SECRET_KEY`, `VINYLDNS_HOST` | [Additional configuration](https://go-acme.github.io/lego/dns/vinyldns) |

View File

@@ -91,9 +91,11 @@ The `users` option is an array of authorized users. Each user must be declared u
```yaml tab="Docker"
# Declaring the user list
#
# Note: all dollar signs in the hash need to be doubled for escaping.
# Note: when used in docker-compose.yml all dollar signs in the hash need to be doubled for escaping.
# To create a user:password pair, the following command can be used:
# echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
#
# Also note that dollar signs should NOT be doubled when they not evaluated (e.g. Ansible docker_container module).
labels:
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
```

View File

@@ -349,12 +349,16 @@ http:
### `tls`
The `tls` option is the TLS configuration from Traefik to the authentication server.
_Optional_
#### `tls.ca`
Defines the TLS configuration used for the secure connection to the authentication server.
Certificate Authority used for the secured connection to the authentication server,
defaults to the system bundle.
#### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secured connection to the authentication server,
it defaults to the system bundle.
```yaml tab="Docker"
labels:
@@ -417,13 +421,15 @@ http:
ca = "path/to/local.crt"
```
#### `tls.caOptional`
#### `caOptional`
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to the authentication server.
_Optional_
The value of `caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to the authentication server.
!!! warning ""
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
If `ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
@@ -479,9 +485,12 @@ http:
caOptional = true
```
#### `tls.cert`
#### `cert`
The public certificate used for the secure connection to the authentication server.
_Optional_
`cert` is the path to the public certificate used for the secure connection to the authentication server.
When using this option, setting the `key` option is required.
```yaml tab="Docker"
labels:
@@ -554,9 +563,12 @@ http:
For security reasons, the field does not exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
#### `tls.key`
#### `key`
The private certificate used for the secure connection to the authentication server.
_Optional_
`key` is the path to the private key used for the secure connection to the authentication server.
When using this option, setting the `cert` option is required.
```yaml tab="Docker"
labels:
@@ -629,7 +641,9 @@ http:
For security reasons, the field does not exist for Kubernetes IngressRoute, and one should use the `secret` field instead.
#### `tls.insecureSkipVerify`
#### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`, the TLS connection to the authentication server accepts any certificate presented by the server regardless of the hostnames it covers.

View File

@@ -84,7 +84,7 @@ labels:
# As TOML Configuration File
[http.routers]
[http.routers.router1]
service = "myService"
service = "service1"
middlewares = ["foo-add-prefix"]
rule = "Host(`example.com`)"
@@ -105,7 +105,7 @@ labels:
http:
routers:
router1:
service: myService
service: service1
middlewares:
- "foo-add-prefix"
rule: "Host(`example.com`)"

View File

@@ -23,7 +23,7 @@ labels:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: addprefix
name: test-passtlsclientcert
spec:
passTLSClientCert:
pem: true

View File

@@ -7,22 +7,6 @@ Traefik supports 4 metrics backends:
- [Prometheus](./prometheus.md)
- [StatsD](./statsd.md)
## Configuration
To enable metrics:
```yaml tab="File (YAML)"
metrics: {}
```
```toml tab="File (TOML)"
[metrics]
```
```bash tab="CLI"
--metrics=true
```
## Server Metrics
| Metric | DataDog | InfluxDB | Prometheus | StatsD |
@@ -39,7 +23,7 @@ The total count of configuration reloads.
config.reload.total
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.config.reload.total
```
@@ -59,7 +43,7 @@ The total count of configuration reload failures.
config.reload.total (with tag "failure" to true)
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.config.reload.total.failure
```
@@ -79,7 +63,7 @@ The timestamp of the last configuration reload success.
config.reload.lastSuccessTimestamp
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.config.reload.lastSuccessTimestamp
```
@@ -99,7 +83,7 @@ The timestamp of the last configuration reload failure.
config.reload.lastFailureTimestamp
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.config.reload.lastFailureTimestamp
```
@@ -130,7 +114,7 @@ Available labels: `code`, `method`, `protocol`, `entrypoint`.
entrypoint.request.total
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.entrypoint.requests.total
```
@@ -161,7 +145,7 @@ Available labels: `code`, `method`, `protocol`, `entrypoint`.
entrypoint.request.duration
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.entrypoint.request.duration
```
@@ -183,7 +167,7 @@ Available labels: `method`, `protocol`, `entrypoint`.
entrypoint.connections.open
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.entrypoint.connections.open
```
@@ -216,7 +200,7 @@ Available labels: `code`, `method`, `protocol`, `service`.
service.request.total
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.service.requests.total
```
@@ -247,7 +231,7 @@ Available labels: `code`, `method`, `protocol`, `service`.
service.request.duration
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.service.request.duration
```
@@ -269,7 +253,7 @@ Available labels: `method`, `protocol`, `service`.
service.connections.open
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.service.connections.open
```
@@ -291,7 +275,7 @@ Available labels: `service`.
service.retries.total
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.service.retries.total
```
@@ -313,7 +297,7 @@ Available labels: `service`, `url`.
service.server.up
```
```influxdb tab="InfluDB"
```influxdb tab="InfluxDB"
traefik.service.server.up
```

View File

@@ -18,7 +18,7 @@ tracing:
!!! warning
Traefik is able to send data over the compact thrift protocol to the [Jaeger agent](https://www.jaegertracing.io/docs/deployment/#agent)
or a [Jaeger collector](https://www.jaegertracing.io/docs/deployment/#collectors).
or a [Jaeger collector](https://www.jaegertracing.io/docs/deployment/#collector).
!!! info
All Jaeger configuration can be overridden by [environment variables](https://github.com/jaegertracing/jaeger-client-go#environment-variables)

View File

@@ -147,9 +147,16 @@ All the following endpoints must be accessed with a `GET` HTTP request.
| `/api/tcp/routers/{name}` | Returns the information of the TCP router specified by `name`. |
| `/api/tcp/services` | Lists all the TCP services information. |
| `/api/tcp/services/{name}` | Returns the information of the TCP service specified by `name`. |
| `/api/tcp/middlewares` | Lists all the TCP middlewares information. |
| `/api/tcp/middlewares/{name}` | Returns the information of the TCP middleware specified by `name`. |
| `/api/udp/routers` | Lists all the UDP routers information. |
| `/api/udp/routers/{name}` | Returns the information of the UDP router specified by `name`. |
| `/api/udp/services` | Lists all the UDP services information. |
| `/api/udp/services/{name}` | Returns the information of the UDP service specified by `name`. |
| `/api/entrypoints` | Lists all the entry points information. |
| `/api/entrypoints/{name}` | Returns the information of the entry point specified by `name`. |
| `/api/overview` | Returns statistic information about http and tcp as well as enabled features and providers. |
| `/api/rawdata` | Returns information about dynamic configurations, errors, status and dependency relations. |
| `/api/version` | Returns information about Traefik version. |
| `/debug/vars` | See the [expvar](https://golang.org/pkg/expvar/) Go documentation. |
| `/debug/pprof/` | See the [pprof Index](https://golang.org/pkg/net/http/pprof/#Index) Go documentation. |

View File

@@ -362,14 +362,14 @@ providers:
_Optional_
Defines TLS options for Consul server endpoint.
Defines the TLS configuration used for the secure connection to Consul Catalog.
##### `ca`
_Optional_
Certificate Authority used for the secure connection to Consul,
defaults to the system bundle.
`ca` is the path to the certificate authority used for the secure connection to Consul Catalog,
it defaults to the system bundle.
```yaml tab="File (YAML)"
providers:
@@ -392,11 +392,11 @@ providers:
_Optional_
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Consul.
The value of `caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Consul Catalog.
!!! warning ""
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
If `ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
@@ -423,8 +423,7 @@ providers:
_Optional_
`cert` is the path to the public certificate to use for Consul communication.
`cert` is the path to the public certificate used for the secure connection to Consul Catalog.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
@@ -451,8 +450,7 @@ providers:
_Optional_
`key` is the path to the private key for Consul communication.
`key` is the path to the private key used for the secure connection to Consul Catalog.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
@@ -477,7 +475,7 @@ providers:
##### `insecureSkipVerify`
_Optional_
_Optional, Default=false_
If `insecureSkipVerify` is `true`, the TLS connection to Consul accepts any certificate presented by the server regardless of the hostnames it covers.

View File

@@ -104,10 +104,14 @@ providers:
_Optional_
#### `tls.ca`
Defines the TLS configuration used for the secure connection to Consul.
Certificate Authority used for the secure connection to Consul,
defaults to the system bundle.
#### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to Consul,
it defaults to the system bundle.
```yaml tab="File (YAML)"
providers:
@@ -125,13 +129,15 @@ providers:
--providers.consul.tls.ca=path/to/ca.crt
```
#### `tls.caOptional`
#### `caOptional`
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Consul.
_Optional_
The value of `caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Consul.
!!! warning ""
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
If `ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
@@ -153,9 +159,12 @@ providers:
--providers.consul.tls.caOptional=true
```
#### `tls.cert`
#### `cert`
Public certificate used for the secure connection to Consul.
_Optional_
`cert` is the path to the public certificate used for the secure connection to Consul.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
providers:
@@ -176,9 +185,12 @@ providers:
--providers.consul.tls.key=path/to/foo.key
```
#### `tls.key`
#### `key`
Private certificate used for the secure connection to Consul.
_Optional_
`key` is the path to the private key used for the secure connection to Consul.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
providers:
@@ -199,7 +211,9 @@ providers:
--providers.consul.tls.key=path/to/foo.key
```
#### `tls.insecureSkipVerify`
#### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`, the TLS connection to Consul accepts any certificate presented by the server regardless of the hostnames it covers.

View File

@@ -613,10 +613,14 @@ providers:
_Optional_
#### `tls.ca`
Defines the TLS configuration used for the secure connection to Docker.
Certificate Authority used for the secure connection to Docker,
defaults to the system bundle.
#### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to Docker,
it defaults to the system bundle.
```yaml tab="File (YAML)"
providers:
@@ -634,13 +638,15 @@ providers:
--providers.docker.tls.ca=path/to/ca.crt
```
#### `tls.caOptional`
#### `caOptional`
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Docker.
_Optional_
The value of `caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Docker.
!!! warning ""
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
If `ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
@@ -662,9 +668,10 @@ providers:
--providers.docker.tls.caOptional=true
```
#### `tls.cert`
#### `cert`
Public certificate used for the secure connection to Docker.
`cert` is the path to the public certificate used for the secure connection to Docker.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
providers:
@@ -685,9 +692,12 @@ providers:
--providers.docker.tls.key=path/to/foo.key
```
#### `tls.key`
#### `key`
Private certificate used for the secure connection to Docker.
_Optional_
`key` is the path to the private key used for the secure connection Docker.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
providers:
@@ -708,7 +718,9 @@ providers:
--providers.docker.tls.key=path/to/foo.key
```
#### `tls.insecureSkipVerify`
#### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`, the TLS connection to Docker accepts any certificate presented by the server regardless of the hostnames it covers.

View File

@@ -104,10 +104,14 @@ providers:
_Optional_
#### `tls.ca`
Defines the TLS configuration used for the secure connection to etcd.
Certificate Authority used for the secure connection to etcd,
defaults to the system bundle.
#### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to etcd,
it defaults to the system bundle.
```yaml tab="File (YAML)"
providers:
@@ -125,13 +129,15 @@ providers:
--providers.etcd.tls.ca=path/to/ca.crt
```
#### `tls.caOptional`
#### `caOptional`
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to etcd.
_Optional_
The value of `caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to etcd.
!!! warning ""
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
If `ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
@@ -153,9 +159,12 @@ providers:
--providers.etcd.tls.caOptional=true
```
#### `tls.cert`
#### `cert`
Public certificate used for the secure connection to etcd.
_Optional_
`cert` is the path to the public certificate used for the secure connection to etcd.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
providers:
@@ -176,9 +185,12 @@ providers:
--providers.etcd.tls.key=path/to/foo.key
```
#### `tls.key`
#### `key`
Private certificate used for the secure connection to etcd.
_Optional_
`key` is the path to the private key used for the secure connection to etcd.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
providers:
@@ -199,7 +211,9 @@ providers:
--providers.etcd.tls.key=path/to/foo.key
```
#### `tls.insecureSkipVerify`
#### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`, the TLS connection to etcd accepts any certificate presented by the server regardless of the hostnames it covers.

View File

@@ -17,8 +17,7 @@ Defines the HTTP(S) endpoint to poll.
```yaml tab="File (YAML)"
providers:
http:
endpoint:
- "http://127.0.0.1:9000/api"
endpoint: "http://127.0.0.1:9000/api"
```
```toml tab="File (TOML)"
@@ -55,7 +54,7 @@ providers:
_Optional, Default="5s"_
Defines the polling timeout when connecting to the configured endpoint.
Defines the polling timeout when connecting to the endpoint.
```yaml tab="File (YAML)"
providers:
@@ -76,10 +75,14 @@ providers:
_Optional_
#### `tls.ca`
Defines the TLS configuration used for the secure connection to the endpoint.
Certificate Authority used for the secure connection to the configured endpoint,
defaults to the system bundle.
#### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to the endpoint,
it defaults to the system bundle.
```yaml tab="File (YAML)"
providers:
@@ -97,13 +100,15 @@ providers:
--providers.http.tls.ca=path/to/ca.crt
```
#### `tls.caOptional`
#### `caOptional`
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to the configured endpoint.
_Optional_
The value of `caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to the endpoint.
!!! warning ""
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
If `ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
@@ -125,9 +130,12 @@ providers:
--providers.http.tls.caOptional=true
```
#### `tls.cert`
#### `cert`
Public certificate used for the secure connection to the configured endpoint.
_Optional_
`cert` is the path to the public certificate used for the secure connection to the endpoint.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
providers:
@@ -148,9 +156,12 @@ providers:
--providers.http.tls.key=path/to/foo.key
```
#### `tls.key`
#### `key`
Private certificate used for the secure connection to the configured endpoint.
_Optional_
`key` is the path to the private key used for the secure connection to the endpoint.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
providers:
@@ -171,7 +182,9 @@ providers:
--providers.http.tls.key=path/to/foo.key
```
#### `tls.insecureSkipVerify`
#### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`, the TLS connection to the endpoint accepts any certificate presented by the server regardless of the hostnames it covers.

View File

@@ -195,13 +195,13 @@ See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-
```yaml tab="File (YAML)"
providers:
kubernetesCRD:
labelselector: "app=traefik"
labelSelector: "app=traefik"
# ...
```
```toml tab="File (TOML)"
[providers.kubernetesCRD]
labelselector = "app=traefik"
labelSelector = "app=traefik"
# ...
```

View File

@@ -229,7 +229,7 @@ See [label-selectors](https://kubernetes.io/docs/concepts/overview/working-with-
```yaml tab="File (YAML)"
providers:
kubernetesIngress:
labelselector: "app=traefik"
labelSelector: "app=traefik"
# ...
```

View File

@@ -404,10 +404,12 @@ providers:
_Optional_
#### `tls.ca`
Defines the TLS configuration used for the secure connection to Marathon.
Certificate Authority used for the secure connection to Marathon,
defaults to the system bundle.
#### `ca`
`ca` is the path to the certificate authority used for the secure connection to Marathon,
it defaults to the system bundle.
```yaml tab="File (YAML)"
providers:
@@ -425,13 +427,15 @@ providers:
--providers.marathon.tls.ca=path/to/ca.crt
```
#### `tls.caOptional`
#### `caOptional`
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Marathon.
_Optional_
The value of `caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Marathon.
!!! warning ""
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
If `ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
@@ -453,9 +457,12 @@ providers:
--providers.marathon.tls.caOptional=true
```
#### `tls.cert`
#### `cert`
Public certificate used for the secure connection to Marathon.
_Optional_
`cert` is the path to the public certificate used for the secure connection to Marathon.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
providers:
@@ -476,9 +483,12 @@ providers:
--providers.marathon.tls.key=path/to/foo.key
```
#### `tls.key`
#### `key`
Private certificate used for the secure connection to Marathon.
_Optional_
`key` is the path to the private key used for the secure connection to Marathon.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
providers:
@@ -499,7 +509,9 @@ providers:
--providers.marathon.tls.key=path/to/foo.key
```
#### `tls.insecureSkipVerify`
#### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`, the TLS connection to Marathon accepts any certificate presented by the server regardless of the hostnames it covers.
@@ -532,18 +544,18 @@ see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration).
```yaml tab="File (YAML)"
providers:
marathon:
responseHeaderTimeout: "10s"
tlsHandshakeTimeout: "10s"
# ...
```
```toml tab="File (TOML)"
[providers.marathon]
responseHeaderTimeout = "10s"
tlsHandshakeTimeout = "10s"
# ...
```
```bash tab="CLI"
--providers.marathon.responseHeaderTimeout=10s
--providers.marathon.tlsHandshakeTimeout=10s
# ...
```

View File

@@ -104,10 +104,14 @@ providers:
_Optional_
#### `tls.ca`
Defines the TLS configuration used for the secure connection to Redis.
Certificate Authority used for the secure connection to Redis,
defaults to the system bundle.
#### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to Redis,
it defaults to the system bundle.
```yaml tab="File (YAML)"
providers:
@@ -125,13 +129,15 @@ providers:
--providers.redis.tls.ca=path/to/ca.crt
```
#### `tls.caOptional`
#### `caOptional`
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Redis.
_Optional_
The value of `caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Redis.
!!! warning ""
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
If `ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
@@ -153,9 +159,12 @@ providers:
--providers.redis.tls.caOptional=true
```
#### `tls.cert`
#### `cert`
Public certificate used for the secure connection to Redis.
_Optional_
`cert` is the path to the public certificate used for the secure connection to Redis.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
providers:
@@ -176,9 +185,12 @@ providers:
--providers.redis.tls.key=path/to/foo.key
```
#### `tls.key`
#### `key`
Private certificate used for the secure connection to Redis.
_Optional_
`key` is the path to the private key used for the secure connection to Redis.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
providers:
@@ -199,7 +211,9 @@ providers:
--providers.redis.tls.key=path/to/foo.key
```
#### `tls.insecureSkipVerify`
#### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`, the TLS connection to Redis accepts any certificate presented by the server regardless of the hostnames it covers.

View File

@@ -104,10 +104,14 @@ providers:
_Optional_
#### `tls.ca`
Defines the TLS configuration used for the secure connection to ZooKeeper.
Certificate Authority used for the secure connection to ZooKeeper,
defaults to the system bundle.
#### `ca`
_Optional_
`ca` is the path to the certificate authority used for the secure connection to ZooKeeper,
it defaults to the system bundle.
```yaml tab="File (YAML)"
providers:
@@ -125,13 +129,15 @@ providers:
--providers.zookeeper.tls.ca=path/to/ca.crt
```
#### `tls.caOptional`
#### `caOptional`
The value of `tls.caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Zookeeper.
_Optional_
The value of `caOptional` defines which policy should be used for the secure connection with TLS Client Authentication to Zookeeper.
!!! warning ""
If `tls.ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
If `ca` is undefined, this option will be ignored, and no client certificate will be requested during the handshake. Any provided certificate will thus never be verified.
When this option is set to `true`, a client certificate is requested during the handshake but is not required. If a certificate is sent, it is required to be valid.
@@ -153,9 +159,12 @@ providers:
--providers.zookeeper.tls.caOptional=true
```
#### `tls.cert`
#### `cert`
Public certificate used for the secure connection to ZooKeeper.
_Optional_
`cert` is the path to the public certificate used for the secure connection to ZooKeeper.
When using this option, setting the `key` option is required.
```yaml tab="File (YAML)"
providers:
@@ -176,9 +185,12 @@ providers:
--providers.zookeeper.tls.key=path/to/foo.key
```
#### `tls.key`
#### `key`
Private certificate used for the secure connection to ZooKeeper.
_Optional_
`key` is the path to the private key used for the secure connection to ZooKeeper.
When using this option, setting the `cert` option is required.
```yaml tab="File (YAML)"
providers:
@@ -199,7 +211,9 @@ providers:
--providers.zookeeper.tls.key=path/to/foo.key
```
#### `tls.insecureSkipVerify`
#### `insecureSkipVerify`
_Optional, Default=false_
If `insecureSkipVerify` is `true`, the TLS connection to Zookeeper accepts any certificate presented by the server regardless of the hostnames it covers.

View File

@@ -63,7 +63,7 @@ For example, to change the rule, you could add the tag ```traefik.http.routers.m
See [tls](../routers/index.md#tls) for more information.
```yaml
traefik.http.routers.myrouter>.tls=true
traefik.http.routers.myrouter.tls=true
```
??? info "`traefik.http.routers.<router_name>.tls.certresolver`"
@@ -136,7 +136,7 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
See [serverstransport](../services/index.md#serverstransport) for more information.
```yaml
traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar@file
traefik.http.services.myservice.loadbalancer.serverstransport=foobar@file
```
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"

View File

@@ -233,11 +233,11 @@ The table below lists all the available matchers:
| ```Headers(`key`, `value`)``` | Check if there is a key `key`defined in the headers, with the value `value` |
| ```HeadersRegexp(`key`, `regexp`)``` | Check if there is a key `key`defined in the headers, with a value that matches the regular expression `regexp` |
| ```Host(`example.com`, ...)``` | Check if the request domain (host header value) targets one of the given `domains`. |
| ```HostHeader(`example.com`, ...)``` | Check if the request domain (host header value) targets one of the given `domains`. |
| ```HostRegexp(`example.com`, `{subdomain:[a-z]+}.example.com`, ...)``` | Check if the request domain matches the given `regexp`. |
| ```HostHeader(`example.com`, ...)``` | Same as `Host`, only exists for historical reasons. |
| ```HostRegexp(`example.com`, `{subdomain:[a-z]+}.example.com`, ...)``` | Match the request domain. See "Regexp Syntax" below. |
| ```Method(`GET`, ...)``` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`) |
| ```Path(`/path`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`, ...)``` | Match exact request path. It accepts a sequence of literal and regular expression paths. |
| ```PathPrefix(`/products/`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`)``` | Match request prefix path. It accepts a sequence of literal and regular expression prefix paths. |
| ```Path(`/path`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`, ...)``` | Match exact request path. See "Regexp Syntax" below. |
| ```PathPrefix(`/products/`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`)``` | Match request prefix path. See "Regexp Syntax" below. |
| ```Query(`foo=bar`, `bar=baz`)``` | Match Query String parameters. It accepts a sequence of key=value pairs. |
| ```ClientIP(`10.0.0.0/16`, `::1`)``` | Match if the request client IP is one of the given IP/CIDR. It accepts IPv4, IPv6 and CIDR formats. |
@@ -249,10 +249,11 @@ The table below lists all the available matchers:
!!! important "Regexp Syntax"
`HostRegexp` and `Path` accept an expression with zero or more groups enclosed by curly braces.
Named groups can be like `{name:pattern}` that matches the given regexp pattern or like `{name}` that matches anything until the next dot.
The group name (`name` is the above examples) is an arbitrary value.
Any pattern supported by [Go's regexp package](https://golang.org/pkg/regexp/) may be used (example: `{subdomain:[a-z]+}.{domain}.com`).
`HostRegexp`, `PathPrefix`, and `Path` accept an expression with zero or more groups enclosed by curly braces, which are called named regexps.
Named regexps, of the form `{name:regexp}`, are the only expressions considered for regexp matching.
The regexp name (`name` in the above example) is an arbitrary value, that exists only for historical reasons.
Any `regexp` supported by [Go's regexp package](https://golang.org/pkg/regexp/) may be used.
!!! info "Combining Matchers Using Operators and Parenthesis"

View File

@@ -336,11 +336,11 @@ Below are the available options for the health check mechanism:
Traefik keeps monitoring the health of unhealthy servers.
If a server has recovered (returning `2xx` -> `3xx` responses again), it will be added back to the load balancer rotation pool.
!!! warning "Health check in Kubernetes"
!!! warning "Health check with Kubernetes"
The Traefik health check is not available for `kubernetesCRD` and `kubernetesIngress` providers because Kubernetes
already has a health check mechanism.
Unhealthy pods will be removed by kubernetes. (cf [liveness documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-a-liveness-http-request))
Kubernetes has an health check mechanism to remove unhealthy pods from Kubernetes services (cf [readiness probe](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes)).
As unhealthy pods have no Kubernetes endpoints, Traefik will not forward traffic to them.
Therefore, Traefik health check is not available for `kubernetesCRD` and `kubernetesIngress` providers.
??? example "Custom Interval & Timeout -- Using the [File Provider](../../providers/file.md)"

View File

@@ -27,7 +27,7 @@ theme:
prev: 'Previous'
next: 'Next'
copyright: "Copyright &copy; 2016-2020 Containous; 2020-2021 Traefik Labs"
copyright: "Copyright &copy; 2016-2020 Containous; 2020-2022 Traefik Labs"
extra_javascript:
- assets/js/hljs/highlight.pack.js # Download from https://highlightjs.org/download/ and enable YAML, TOML and Dockerfile

View File

@@ -4,3 +4,4 @@ mkdocs-bootswatch==1.0
mkdocs-traefiklabs>=100.0.7
markdown-include==0.5.1
mkdocs-exclude==1.0.2
Jinja2==3.0.0

View File

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

44
go.mod
View File

@@ -7,30 +7,26 @@ require (
github.com/BurntSushi/toml v0.3.1
github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61
github.com/Masterminds/sprig/v3 v3.2.2
github.com/Microsoft/hcsshim v0.8.7 // indirect
github.com/Shopify/sarama v1.23.1 // indirect
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
github.com/abronan/valkeyrie v0.2.0
github.com/aws/aws-sdk-go v1.39.0
github.com/cenkalti/backoff/v4 v4.1.1
github.com/containerd/containerd v1.3.2 // indirect
github.com/compose-spec/compose-go v1.0.3
github.com/containerd/containerd v1.5.8 // indirect
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
github.com/davecgh/go-spew v1.1.1
github.com/docker/cli v0.0.0-20200221155518-740919cc7fc0
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v17.12.0-ce-rc1.0.20200204220554-5f6d6f3f2203+incompatible
github.com/docker/docker-credential-helpers v0.6.3 // indirect
github.com/docker/cli v20.10.11+incompatible
github.com/docker/compose/v2 v2.0.1
github.com/docker/docker v20.10.7+incompatible
github.com/docker/go-connections v0.4.0
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 // indirect
github.com/docker/libcompose v0.0.0-20190805081528-eac9fe1b8b03 // indirect
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 // indirect
github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e // indirect
github.com/eapache/channels v1.1.0
github.com/elazarl/go-bindata-assetfs v1.0.0
github.com/fatih/structs v1.1.0
github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2
github.com/go-acme/lego/v4 v4.5.0
github.com/go-acme/lego/v4 v4.6.0
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.5.2
@@ -41,24 +37,17 @@ require (
github.com/hashicorp/consul/api v1.10.0
github.com/hashicorp/go-hclog v0.16.1
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-version v1.2.1
github.com/hashicorp/go-version v1.3.0
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d
github.com/instana/go-sensor v1.5.1
github.com/klauspost/compress v1.13.0
github.com/libkermit/compose v0.0.0-20171122111507-c04e39c026ad
github.com/libkermit/docker v0.0.0-20171122101128-e6674d32b807
github.com/libkermit/docker-check v0.0.0-20171122104347-1113af38e591
github.com/lucas-clemente/quic-go v0.23.0
github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f
github.com/miekg/dns v1.1.43
github.com/mitchellh/copystructure v1.0.0
github.com/mitchellh/hashstructure v1.0.0
github.com/mitchellh/mapstructure v1.4.1
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/opencontainers/runc v1.0.0-rc10 // indirect
github.com/opentracing/opentracing-go v1.1.0
github.com/mitchellh/mapstructure v1.4.2
github.com/opentracing/opentracing-go v1.2.0
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5
github.com/openzipkin/zipkin-go v0.2.2
github.com/patrickmn/go-cache v2.1.0+incompatible
@@ -68,12 +57,12 @@ require (
github.com/prometheus/client_golang v1.11.0
github.com/prometheus/client_model v0.2.0
github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac
github.com/sirupsen/logrus v1.7.0
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0
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.4
github.com/traefik/yaegi v0.10.0
github.com/traefik/yaegi v0.11.2
github.com/uber/jaeger-client-go v2.29.1+incompatible
github.com/uber/jaeger-lib v2.2.0+incompatible
github.com/unrolled/render v1.0.2
@@ -84,7 +73,7 @@ require (
go.elastic.co/apm v1.13.1
go.elastic.co/apm/module/apmot v1.13.1
golang.org/x/mod v0.4.2
golang.org/x/net v0.0.0-20210614182718-04defd469f4e
golang.org/x/net v0.0.0-20211209124913-491a49abca63
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2 // indirect
golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6
golang.org/x/tools v0.1.2
@@ -105,7 +94,14 @@ require (
replace (
github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e
github.com/go-check/check => github.com/containous/check v0.0.0-20170915194414-ca0bf163426a
github.com/gorilla/mux => github.com/containous/mux v0.0.0-20181024131434-c33f32e26898
github.com/gorilla/mux => github.com/containous/mux v0.0.0-20220113180107-8ffa4f6d063c
github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595
github.com/mailgun/multibuf => github.com/containous/multibuf v0.0.0-20190809014333-8b6c9a7e6bba
)
// https://github.com/docker/compose/blob/e44222664abd07ce1d1fe6796d84d93cbc7468c3/go.mod#L131
replace github.com/jaguilar/vt100 => github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305
// ambiguous import: found package github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http in multiple modules
// tencentcloud uses monorepo with multimodule but the go.mod files are incomplete.
exclude github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible

805
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -36,12 +36,7 @@ type accessLogValue struct {
func (s *AccessLogSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "access_log")
s.composeProject.Start(c)
s.composeProject.Container(c, "server0")
s.composeProject.Container(c, "server1")
s.composeProject.Container(c, "server2")
s.composeProject.Container(c, "server3")
s.composeUp(c)
}
func (s *AccessLogSuite) TearDownTest(c *check.C) {
@@ -122,7 +117,7 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontend(c *check.C) {
code: "200",
user: "test",
routerName: "rt-authFrontend",
serviceURL: "http://172.17.0",
serviceURL: "http://172.31.42",
},
}
@@ -136,8 +131,6 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontend(c *check.C) {
checkStatsForLogFile(c)
s.composeProject.Container(c, "authFrontend")
waitForTraefik(c, "authFrontend")
// Verify Traefik started OK
@@ -193,7 +186,7 @@ func (s *AccessLogSuite) TestAccessLogDigestAuthMiddleware(c *check.C) {
code: "200",
user: "test",
routerName: "rt-digestAuthMiddleware",
serviceURL: "http://172.17.0",
serviceURL: "http://172.31.42",
},
}
@@ -207,8 +200,6 @@ func (s *AccessLogSuite) TestAccessLogDigestAuthMiddleware(c *check.C) {
checkStatsForLogFile(c)
s.composeProject.Container(c, "digestAuthMiddleware")
waitForTraefik(c, "digestAuthMiddleware")
// Verify Traefik started OK
@@ -322,8 +313,6 @@ func (s *AccessLogSuite) TestAccessLogFrontendRedirect(c *check.C) {
checkStatsForLogFile(c)
s.composeProject.Container(c, "frontendRedirect")
waitForTraefik(c, "frontendRedirect")
// Verify Traefik started OK
@@ -375,8 +364,6 @@ func (s *AccessLogSuite) TestAccessLogRateLimit(c *check.C) {
checkStatsForLogFile(c)
s.composeProject.Container(c, "rateLimit")
waitForTraefik(c, "rateLimit")
// Verify Traefik started OK
@@ -471,8 +458,6 @@ func (s *AccessLogSuite) TestAccessLogFrontendWhitelist(c *check.C) {
checkStatsForLogFile(c)
s.composeProject.Container(c, "frontendWhitelist")
waitForTraefik(c, "frontendWhitelist")
// Verify Traefik started OK
@@ -504,7 +489,7 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontendSuccess(c *check.C) {
code: "200",
user: "test",
routerName: "rt-authFrontend",
serviceURL: "http://172.17.0",
serviceURL: "http://172.31.42",
},
}
@@ -518,8 +503,6 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontendSuccess(c *check.C) {
checkStatsForLogFile(c)
s.composeProject.Container(c, "authFrontend")
waitForTraefik(c, "authFrontend")
// Verify Traefik started OK
@@ -548,7 +531,6 @@ func checkNoOtherTraefikProblems(c *check.C) {
c.Assert(err, checker.IsNil)
if len(traefikLog) > 0 {
fmt.Printf("%s\n", string(traefikLog))
c.Assert(traefikLog, checker.HasLen, 0)
}
}
@@ -616,7 +598,6 @@ func checkTraefikStarted(c *check.C) []byte {
c.Assert(err, checker.IsNil)
if len(traefikLog) > 0 {
fmt.Printf("%s\n", string(traefikLog))
c.Assert(traefikLog, checker.HasLen, 0)
}
return traefikLog
}

View File

@@ -4,6 +4,7 @@ import (
"crypto/tls"
"crypto/x509"
"fmt"
"net"
"net/http"
"os"
"path/filepath"
@@ -19,7 +20,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// ACME test suites (using libcompose).
// ACME test suites.
type AcmeSuite struct {
BaseSuite
pebbleIP string
@@ -54,7 +55,8 @@ const (
)
func (s *AcmeSuite) getAcmeURL() string {
return fmt.Sprintf("https://%s:14000/dir", s.pebbleIP)
return fmt.Sprintf("https://%s/dir",
net.JoinHostPort(s.pebbleIP, "14000"))
}
func setupPebbleRootCA() (*http.Transport, error) {
@@ -86,11 +88,10 @@ func setupPebbleRootCA() (*http.Transport, error) {
func (s *AcmeSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "pebble")
s.composeProject.Start(c)
s.composeUp(c)
s.fakeDNSServer = startFakeDNSServer()
s.pebbleIP = s.composeProject.Container(c, "pebble").NetworkSettings.IPAddress
s.fakeDNSServer = startFakeDNSServer(s.getContainerIP(c, "traefik"))
s.pebbleIP = s.getComposeServiceIP(c, "pebble")
pebbleTransport, err := setupPebbleRootCA()
if err != nil {
@@ -115,15 +116,14 @@ func (s *AcmeSuite) SetUpSuite(c *check.C) {
}
func (s *AcmeSuite) TearDownSuite(c *check.C) {
err := s.fakeDNSServer.Shutdown()
if err != nil {
c.Log(err)
if s.fakeDNSServer != nil {
err := s.fakeDNSServer.Shutdown()
if err != nil {
c.Log(err)
}
}
// shutdown and delete compose project
if s.composeProject != nil {
s.composeProject.Stop(c)
}
s.composeDown(c)
}
func (s *AcmeSuite) TestHTTP01Domains(c *check.C) {

View File

@@ -2,6 +2,7 @@ package integration
import (
"fmt"
"net"
"net/http"
"os"
"time"
@@ -14,32 +15,31 @@ import (
type ConsulCatalogSuite struct {
BaseSuite
consulClient *api.Client
consulAgentClient *api.Client
consulAddress string
consulAgentAddress string
consulClient *api.Client
consulAgentClient *api.Client
consulURL string
}
func (s *ConsulCatalogSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "consul_catalog")
s.composeProject.Start(c)
s.consulAddress = "http://" + s.composeProject.Container(c, "consul").NetworkSettings.IPAddress + ":8500"
client, err := api.NewClient(&api.Config{
Address: s.consulAddress,
s.composeUp(c)
s.consulURL = "http://" + net.JoinHostPort(s.getComposeServiceIP(c, "consul"), "8500")
var err error
s.consulClient, err = api.NewClient(&api.Config{
Address: s.consulURL,
})
c.Check(err, check.IsNil)
s.consulClient = client
// Wait for consul to elect itself leader
err = s.waitToElectConsulLeader()
c.Assert(err, checker.IsNil)
s.consulAgentAddress = "http://" + s.composeProject.Container(c, "consul-agent").NetworkSettings.IPAddress + ":8500"
clientAgent, err := api.NewClient(&api.Config{
Address: s.consulAgentAddress,
s.consulAgentClient, err = api.NewClient(&api.Config{
Address: "http://" + net.JoinHostPort(s.getComposeServiceIP(c, "consul-agent"), "8500"),
})
c.Check(err, check.IsNil)
s.consulAgentClient = clientAgent
}
func (s *ConsulCatalogSuite) waitToElectConsulLeader() error {
@@ -66,13 +66,6 @@ func (s *ConsulCatalogSuite) waitForConnectCA() error {
})
}
func (s *ConsulCatalogSuite) TearDownSuite(c *check.C) {
// shutdown and delete compose project
if s.composeProject != nil {
s.composeProject.Stop(c)
}
}
func (s *ConsulCatalogSuite) registerService(reg *api.AgentServiceRegistration, onAgent bool) error {
client := s.consulClient
if onAgent {
@@ -96,7 +89,7 @@ func (s *ConsulCatalogSuite) TestWithNotExposedByDefaultAndDefaultsSettings(c *c
Name: "whoami",
Tags: []string{"traefik.enable=true"},
Port: 80,
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoami1"),
}
err := s.registerService(reg1, false)
c.Assert(err, checker.IsNil)
@@ -106,7 +99,7 @@ func (s *ConsulCatalogSuite) TestWithNotExposedByDefaultAndDefaultsSettings(c *c
Name: "whoami",
Tags: []string{"traefik.enable=true"},
Port: 80,
Address: s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoami2"),
}
err = s.registerService(reg2, false)
c.Assert(err, checker.IsNil)
@@ -116,7 +109,7 @@ func (s *ConsulCatalogSuite) TestWithNotExposedByDefaultAndDefaultsSettings(c *c
Name: "whoami",
Tags: []string{"traefik.enable=true"},
Port: 80,
Address: s.composeProject.Container(c, "whoami3").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoami3"),
}
err = s.registerService(reg3, false)
c.Assert(err, checker.IsNil)
@@ -124,7 +117,7 @@ func (s *ConsulCatalogSuite) TestWithNotExposedByDefaultAndDefaultsSettings(c *c
tempObjects := struct {
ConsulAddress string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
}
file := s.adaptFile(c, "fixtures/consul_catalog/default_not_exposed.toml", tempObjects)
@@ -163,7 +156,7 @@ func (s *ConsulCatalogSuite) TestWithNotExposedByDefaultAndDefaultsSettings(c *c
}
func (s *ConsulCatalogSuite) TestByLabels(c *check.C) {
containerIP := s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress
containerIP := s.getComposeServiceIP(c, "whoami1")
reg := &api.AgentServiceRegistration{
ID: "whoami1",
@@ -183,7 +176,7 @@ func (s *ConsulCatalogSuite) TestByLabels(c *check.C) {
tempObjects := struct {
ConsulAddress string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
}
file := s.adaptFile(c, "fixtures/consul_catalog/default_not_exposed.toml", tempObjects)
@@ -195,7 +188,7 @@ func (s *ConsulCatalogSuite) TestByLabels(c *check.C) {
c.Assert(err, checker.IsNil)
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"))
err = try.GetRequest("http://127.0.0.1:8000/whoami", 5*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContainsOr("Hostname: whoami1", "Hostname: whoami2", "Hostname: whoami3"))
c.Assert(err, checker.IsNil)
err = s.deregisterService("whoami1", false)
@@ -207,7 +200,7 @@ func (s *ConsulCatalogSuite) TestSimpleConfiguration(c *check.C) {
ConsulAddress string
DefaultRule string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
}
@@ -219,7 +212,7 @@ func (s *ConsulCatalogSuite) TestSimpleConfiguration(c *check.C) {
Name: "whoami",
Tags: []string{"traefik.enable=true"},
Port: 80,
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoami1"),
}
err := s.registerService(reg, false)
c.Assert(err, checker.IsNil)
@@ -246,7 +239,7 @@ func (s *ConsulCatalogSuite) TestRegisterServiceWithoutIP(c *check.C) {
ConsulAddress string
DefaultRule string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
}
@@ -285,7 +278,7 @@ func (s *ConsulCatalogSuite) TestDefaultConsulService(c *check.C) {
DefaultRule string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
}
@@ -296,7 +289,7 @@ func (s *ConsulCatalogSuite) TestDefaultConsulService(c *check.C) {
ID: "whoami1",
Name: "whoami",
Port: 80,
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoami1"),
}
err := s.registerService(reg, false)
c.Assert(err, checker.IsNil)
@@ -324,7 +317,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithTCPLabels(c *check.C) {
ConsulAddress string
DefaultRule string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
}
@@ -341,7 +334,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithTCPLabels(c *check.C) {
"traefik.tcp.Services.Super.Loadbalancer.server.port=8080",
},
Port: 8080,
Address: s.composeProject.Container(c, "whoamitcp").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoamitcp"),
}
err := s.registerService(reg, false)
@@ -371,7 +364,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithLabels(c *check.C) {
ConsulAddress string
DefaultRule string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
}
@@ -386,7 +379,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithLabels(c *check.C) {
"traefik.http.Routers.Super.Rule=Host(`my.super.host`)",
},
Port: 80,
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoami1"),
}
err := s.registerService(reg1, false)
@@ -400,7 +393,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithLabels(c *check.C) {
"traefik.http.Routers.SuperHost.Rule=Host(`my-super.host`)",
},
Port: 80,
Address: s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoami2"),
}
err = s.registerService(reg2, false)
c.Assert(err, checker.IsNil)
@@ -438,7 +431,7 @@ func (s *ConsulCatalogSuite) TestSameServiceIDOnDifferentConsulAgent(c *check.C)
ConsulAddress string
DefaultRule string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
}
@@ -457,7 +450,7 @@ func (s *ConsulCatalogSuite) TestSameServiceIDOnDifferentConsulAgent(c *check.C)
Name: "whoami",
Tags: tags,
Port: 80,
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoami1"),
}
err := s.registerService(reg1, false)
c.Assert(err, checker.IsNil)
@@ -467,7 +460,7 @@ func (s *ConsulCatalogSuite) TestSameServiceIDOnDifferentConsulAgent(c *check.C)
Name: "whoami",
Tags: tags,
Port: 80,
Address: s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoami2"),
}
err = s.registerService(reg2, true)
c.Assert(err, checker.IsNil)
@@ -490,8 +483,7 @@ func (s *ConsulCatalogSuite) TestSameServiceIDOnDifferentConsulAgent(c *check.C)
c.Assert(err, checker.IsNil)
err = try.Request(req, 2*time.Second, try.StatusCodeIs(200),
try.BodyContainsOr(s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress))
try.BodyContainsOr(s.getComposeServiceIP(c, "whoami1"), s.getComposeServiceIP(c, "whoami2")))
c.Assert(err, checker.IsNil)
err = s.deregisterService("whoami", false)
@@ -506,7 +498,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithOneMissingLabels(c *check.C) {
ConsulAddress string
DefaultRule string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
}
@@ -521,7 +513,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithOneMissingLabels(c *check.C) {
"traefik.random.value=my.super.host",
},
Port: 80,
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
Address: s.getComposeServiceIP(c, "whoami1"),
}
err := s.registerService(reg, false)
@@ -546,11 +538,12 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithOneMissingLabels(c *check.C) {
}
func (s *ConsulCatalogSuite) TestConsulServiceWithHealthCheck(c *check.C) {
whoamiIP := s.getComposeServiceIP(c, "whoami1")
tags := []string{
"traefik.enable=true",
"traefik.http.routers.router1.rule=Path(`/whoami`)",
"traefik.http.routers.router1.service=service1",
"traefik.http.services.service1.loadBalancer.server.url=http://" + s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
"traefik.http.services.service1.loadBalancer.server.url=http://" + whoamiIP,
}
reg1 := &api.AgentServiceRegistration{
@@ -558,7 +551,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithHealthCheck(c *check.C) {
Name: "whoami",
Tags: tags,
Port: 80,
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
Address: whoamiIP,
Check: &api.AgentServiceCheck{
CheckID: "some-failed-check",
TCP: "127.0.0.1:1234",
@@ -574,7 +567,7 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithHealthCheck(c *check.C) {
tempObjects := struct {
ConsulAddress string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
}
file := s.adaptFile(c, "fixtures/consul_catalog/simple.toml", tempObjects)
@@ -592,17 +585,16 @@ func (s *ConsulCatalogSuite) TestConsulServiceWithHealthCheck(c *check.C) {
err = s.deregisterService("whoami1", false)
c.Assert(err, checker.IsNil)
containerIP := s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress
whoami2IP := s.getComposeServiceIP(c, "whoami2")
reg2 := &api.AgentServiceRegistration{
ID: "whoami2",
Name: "whoami",
Tags: tags,
Port: 80,
Address: containerIP,
Address: whoami2IP,
Check: &api.AgentServiceCheck{
CheckID: "some-ok-check",
TCP: containerIP + ":80",
TCP: whoami2IP + ":80",
Name: "some-ok-check",
Interval: "1s",
Timeout: "1s",
@@ -629,7 +621,7 @@ func (s *ConsulCatalogSuite) TestConsulConnect(c *check.C) {
err := s.waitForConnectCA()
c.Assert(err, checker.IsNil)
connectIP := s.composeProject.Container(c, "connect").NetworkSettings.IPAddress
connectIP := s.getComposeServiceIP(c, "connect")
reg := &api.AgentServiceRegistration{
ID: "uuid-api1",
Name: "uuid-api",
@@ -649,7 +641,7 @@ func (s *ConsulCatalogSuite) TestConsulConnect(c *check.C) {
err = s.registerService(reg, false)
c.Assert(err, checker.IsNil)
whoamiIP := s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress
whoamiIP := s.getComposeServiceIP(c, "whoami1")
regWhoami := &api.AgentServiceRegistration{
ID: "whoami1",
Name: "whoami",
@@ -667,7 +659,7 @@ func (s *ConsulCatalogSuite) TestConsulConnect(c *check.C) {
tempObjects := struct {
ConsulAddress string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
}
file := s.adaptFile(c, "fixtures/consul_catalog/connect.toml", tempObjects)
defer os.Remove(file)
@@ -695,7 +687,7 @@ func (s *ConsulCatalogSuite) TestConsulConnect_ByDefault(c *check.C) {
err := s.waitForConnectCA()
c.Assert(err, checker.IsNil)
connectIP := s.composeProject.Container(c, "connect").NetworkSettings.IPAddress
connectIP := s.getComposeServiceIP(c, "connect")
reg := &api.AgentServiceRegistration{
ID: "uuid-api1",
Name: "uuid-api",
@@ -714,7 +706,7 @@ func (s *ConsulCatalogSuite) TestConsulConnect_ByDefault(c *check.C) {
err = s.registerService(reg, false)
c.Assert(err, checker.IsNil)
whoamiIP := s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress
whoamiIP := s.getComposeServiceIP(c, "whoami1")
regWhoami := &api.AgentServiceRegistration{
ID: "whoami1",
Name: "whoami1",
@@ -729,7 +721,7 @@ func (s *ConsulCatalogSuite) TestConsulConnect_ByDefault(c *check.C) {
err = s.registerService(regWhoami, false)
c.Assert(err, checker.IsNil)
whoami2IP := s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress
whoami2IP := s.getComposeServiceIP(c, "whoami2")
regWhoami2 := &api.AgentServiceRegistration{
ID: "whoami2",
Name: "whoami2",
@@ -748,7 +740,7 @@ func (s *ConsulCatalogSuite) TestConsulConnect_ByDefault(c *check.C) {
tempObjects := struct {
ConsulAddress string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
}
file := s.adaptFile(c, "fixtures/consul_catalog/connect_by_default.toml", tempObjects)
defer os.Remove(file)
@@ -781,7 +773,7 @@ func (s *ConsulCatalogSuite) TestConsulConnect_NotAware(c *check.C) {
err := s.waitForConnectCA()
c.Assert(err, checker.IsNil)
connectIP := s.composeProject.Container(c, "connect").NetworkSettings.IPAddress
connectIP := s.getComposeServiceIP(c, "connect")
reg := &api.AgentServiceRegistration{
ID: "uuid-api1",
Name: "uuid-api",
@@ -801,7 +793,7 @@ func (s *ConsulCatalogSuite) TestConsulConnect_NotAware(c *check.C) {
err = s.registerService(reg, false)
c.Assert(err, checker.IsNil)
whoamiIP := s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress
whoamiIP := s.getComposeServiceIP(c, "whoami1")
regWhoami := &api.AgentServiceRegistration{
ID: "whoami1",
Name: "whoami",
@@ -819,7 +811,7 @@ func (s *ConsulCatalogSuite) TestConsulConnect_NotAware(c *check.C) {
tempObjects := struct {
ConsulAddress string
}{
ConsulAddress: s.consulAddress,
ConsulAddress: s.consulURL,
}
file := s.adaptFile(c, "fixtures/consul_catalog/connect_not_aware.toml", tempObjects)
defer os.Remove(file)

View File

@@ -3,6 +3,8 @@ package integration
import (
"bytes"
"encoding/json"
"fmt"
"net"
"net/http"
"os"
"path/filepath"
@@ -18,20 +20,24 @@ import (
checker "github.com/vdemeester/shakers"
)
// Consul test suites (using libcompose).
// Consul test suites.
type ConsulSuite struct {
BaseSuite
kvClient store.Store
kvClient store.Store
consulURL string
}
func (s *ConsulSuite) setupStore(c *check.C) {
s.createComposeProject(c, "consul")
s.composeProject.Start(c)
s.composeUp(c)
consulAddr := net.JoinHostPort(s.getComposeServiceIP(c, "consul"), "8500")
s.consulURL = fmt.Sprintf("http://%s", consulAddr)
consul.Register()
kv, err := valkeyrie.NewStore(
store.CONSUL,
[]string{s.composeProject.Container(c, "consul").NetworkSettings.IPAddress + ":8500"},
[]string{consulAddr},
&store.Config{
ConnectionTimeout: 10 * time.Second,
},
@@ -46,20 +52,10 @@ func (s *ConsulSuite) setupStore(c *check.C) {
c.Assert(err, checker.IsNil)
}
func (s *ConsulSuite) TearDownTest(c *check.C) {
// shutdown and delete compose project
if s.composeProject != nil {
s.composeProject.Stop(c)
}
}
func (s *ConsulSuite) TearDownSuite(c *check.C) {}
func (s *ConsulSuite) TestSimpleConfiguration(c *check.C) {
s.setupStore(c)
address := "http://" + s.composeProject.Container(c, "consul").NetworkSettings.IPAddress + ":8500"
file := s.adaptFile(c, "fixtures/consul/simple.toml", struct{ ConsulAddress string }{address})
file := s.adaptFile(c, "fixtures/consul/simple.toml", struct{ ConsulAddress string }{s.consulURL})
defer os.Remove(file)
data := map[string]string{

View File

@@ -14,33 +14,17 @@ import (
checker "github.com/vdemeester/shakers"
)
const (
composeProject = "minimal"
)
// Docker tests suite.
type DockerComposeSuite struct {
BaseSuite
}
func (s *DockerComposeSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, composeProject)
s.composeProject.Start(c)
}
func (s *DockerComposeSuite) TearDownSuite(c *check.C) {
// shutdown and delete compose project
if s.composeProject != nil {
s.composeProject.Stop(c)
}
s.createComposeProject(c, "minimal")
s.composeUp(c)
}
func (s *DockerComposeSuite) TestComposeScale(c *check.C) {
serviceCount := 2
composeService := "whoami1"
s.composeProject.Scale(c, composeService, serviceCount)
tempObjects := struct {
DockerHost string
DefaultRule string
@@ -81,8 +65,8 @@ func (s *DockerComposeSuite) TestComposeScale(c *check.C) {
if strings.HasSuffix(name, "@internal") {
continue
}
c.Assert(name, checker.Equals, composeService+"-integrationtest"+composeProject+"@docker")
c.Assert(service.LoadBalancer.Servers, checker.HasLen, serviceCount)
c.Assert(name, checker.Equals, "whoami1-"+s.composeProject.Name+"@docker")
c.Assert(service.LoadBalancer.Servers, checker.HasLen, 2)
// We could break here, but we don't just to keep us honest.
}
}

View File

@@ -6,80 +6,24 @@ import (
"io"
"net/http"
"os"
"strings"
"time"
"github.com/docker/docker/pkg/namesgenerator"
"github.com/go-check/check"
d "github.com/libkermit/docker"
"github.com/libkermit/docker-check"
"github.com/traefik/traefik/v2/integration/try"
checker "github.com/vdemeester/shakers"
)
// Images to have or pull before the build in order to make it work.
// FIXME handle this offline but loading them before build.
var RequiredImages = map[string]string{
"swarm": "1.0.0",
"traefik/whoami": "latest",
}
// Docker tests suite.
type DockerSuite struct {
BaseSuite
project *docker.Project
}
func (s *DockerSuite) startContainer(c *check.C, image string, args ...string) string {
return s.startContainerWithConfig(c, image, d.ContainerConfig{
Cmd: args,
})
}
func (s *DockerSuite) startContainerWithLabels(c *check.C, image string, labels map[string]string, args ...string) string {
return s.startContainerWithConfig(c, image, d.ContainerConfig{
Cmd: args,
Labels: labels,
})
}
func (s *DockerSuite) startContainerWithNameAndLabels(c *check.C, name, image string, labels map[string]string, args ...string) string {
return s.startContainerWithConfig(c, image, d.ContainerConfig{
Name: name,
Cmd: args,
Labels: labels,
})
}
func (s *DockerSuite) startContainerWithConfig(c *check.C, image string, config d.ContainerConfig) string {
if config.Name == "" {
config.Name = namesgenerator.GetRandomName(10)
}
container := s.project.StartWithConfig(c, image, config)
// FIXME(vdemeester) this is ugly (it's because of the / in front of the name in docker..)
return strings.SplitAfter(container.Name, "/")[1]
}
func (s *DockerSuite) stopAndRemoveContainerByName(c *check.C, name string) {
s.project.Stop(c, name)
s.project.Remove(c, name)
}
func (s *DockerSuite) SetUpSuite(c *check.C) {
project := docker.NewProjectFromEnv(c)
s.project = project
// Pull required images
for repository, tag := range RequiredImages {
image := fmt.Sprintf("%s:%s", repository, tag)
s.project.Pull(c, image)
}
func (s *DockerSuite) SetUpTest(c *check.C) {
s.createComposeProject(c, "docker")
}
func (s *DockerSuite) TearDownTest(c *check.C) {
s.project.Clean(c, os.Getenv("CIRCLECI") != "") // FIXME
s.composeDown(c)
}
func (s *DockerSuite) TestSimpleConfiguration(c *check.C) {
@@ -94,13 +38,15 @@ func (s *DockerSuite) TestSimpleConfiguration(c *check.C) {
file := s.adaptFile(c, "fixtures/docker/simple.toml", tempObjects)
defer os.Remove(file)
s.composeUp(c)
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
// TODO validate : run on 80
// Expected a 404 as we did not configure anything
err = try.GetRequest("http://127.0.0.1:8000/", 500*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))
c.Assert(err, checker.IsNil)
@@ -118,18 +64,19 @@ func (s *DockerSuite) TestDefaultDockerContainers(c *check.C) {
file := s.adaptFile(c, "fixtures/docker/simple.toml", tempObjects)
defer os.Remove(file)
name := s.startContainer(c, "swarm:1.0.0", "manage", "token://blablabla")
s.composeUp(c, "simple")
// Start traefik
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil)
c.Assert(err, checker.IsNil)
req.Host = fmt.Sprintf("%s.docker.localhost", strings.ReplaceAll(name, "_", "-"))
req.Host = fmt.Sprintf("simple-%s.docker.localhost", s.composeProject.Name)
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK)
@@ -156,18 +103,12 @@ func (s *DockerSuite) TestDockerContainersWithTCPLabels(c *check.C) {
file := s.adaptFile(c, "fixtures/docker/simple.toml", tempObjects)
defer os.Remove(file)
// Start a container with some labels
labels := map[string]string{
"traefik.tcp.Routers.Super.Rule": "HostSNI(`my.super.host`)",
"traefik.tcp.Routers.Super.tls": "true",
"traefik.tcp.Services.Super.Loadbalancer.server.port": "8080",
}
s.startContainerWithLabels(c, "traefik/whoamitcp", labels, "-name", "my.super.host")
s.composeUp(c, "withtcplabels")
// Start traefik
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
@@ -193,17 +134,7 @@ func (s *DockerSuite) TestDockerContainersWithLabels(c *check.C) {
file := s.adaptFile(c, "fixtures/docker/simple.toml", tempObjects)
defer os.Remove(file)
// Start a container with some labels
labels := map[string]string{
"traefik.http.Routers.Super.Rule": "Host(`my.super.host`)",
}
s.startContainerWithLabels(c, "swarm:1.0.0", labels, "manage", "token://blabla")
// Start another container by replacing a '.' by a '-'
labels = map[string]string{
"traefik.http.Routers.SuperHost.Rule": "Host(`my-super.host`)",
}
s.startContainerWithLabels(c, "swarm:1.0.0", labels, "manage", "token://blablabla")
s.composeUp(c, "withlabels1", "withlabels2")
// Start traefik
cmd, display := s.traefikCmd(withConfigFile(file))
@@ -249,15 +180,12 @@ func (s *DockerSuite) TestDockerContainersWithOneMissingLabels(c *check.C) {
file := s.adaptFile(c, "fixtures/docker/simple.toml", tempObjects)
defer os.Remove(file)
// Start a container with some labels
labels := map[string]string{
"traefik.random.value": "my.super.host",
}
s.startContainerWithLabels(c, "swarm:1.0.0", labels, "manage", "token://blabla")
s.composeUp(c, "withonelabelmissing")
// Start traefik
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
@@ -285,16 +213,12 @@ func (s *DockerSuite) TestRestartDockerContainers(c *check.C) {
file := s.adaptFile(c, "fixtures/docker/simple.toml", tempObjects)
defer os.Remove(file)
// Start a container with some labels
labels := map[string]string{
"traefik.http.Routers.Super.Rule": "Host(`my.super.host`)",
"traefik.http.Services.powpow.LoadBalancer.server.Port": "2375",
}
s.startContainerWithNameAndLabels(c, "powpow", "swarm:1.0.0", labels, "manage", "token://blabla")
s.composeUp(c, "powpow")
// Start traefik
cmd, display := s.traefikCmd(withConfigFile(file))
defer display(c)
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
@@ -318,16 +242,14 @@ func (s *DockerSuite) TestRestartDockerContainers(c *check.C) {
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("powpow"))
c.Assert(err, checker.IsNil)
s.stopAndRemoveContainerByName(c, "powpow")
defer s.project.Remove(c, "powpow")
s.composeStop(c, "powpow")
time.Sleep(5 * time.Second)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("powpow"))
c.Assert(err, checker.NotNil)
s.startContainerWithNameAndLabels(c, "powpow", "swarm:1.0.0", labels, "manage", "token://blabla")
s.composeUp(c, "powpow")
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 60*time.Second, try.BodyContains("powpow"))
c.Assert(err, checker.IsNil)
}

View File

@@ -10,7 +10,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// ErrorPagesSuite test suites (using libcompose).
// ErrorPagesSuite test suites.
type ErrorPagesSuite struct {
BaseSuite
ErrorPageIP string
@@ -19,10 +19,10 @@ type ErrorPagesSuite struct {
func (s *ErrorPagesSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "error_pages")
s.composeProject.Start(c)
s.composeUp(c)
s.ErrorPageIP = s.composeProject.Container(c, "nginx2").NetworkSettings.IPAddress
s.BackendIP = s.composeProject.Container(c, "nginx1").NetworkSettings.IPAddress
s.ErrorPageIP = s.getComposeServiceIP(c, "nginx2")
s.BackendIP = s.getComposeServiceIP(c, "nginx1")
}
func (s *ErrorPagesSuite) TestSimpleConfiguration(c *check.C) {

View File

@@ -3,6 +3,7 @@ package integration
import (
"bytes"
"encoding/json"
"net"
"net/http"
"os"
"path/filepath"
@@ -18,20 +19,24 @@ import (
checker "github.com/vdemeester/shakers"
)
// etcd test suites (using libcompose).
// etcd test suites.
type EtcdSuite struct {
BaseSuite
kvClient store.Store
etcdAddr string
}
func (s *EtcdSuite) setupStore(c *check.C) {
func (s *EtcdSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "etcd")
s.composeProject.Start(c)
s.composeUp(c)
etcdv3.Register()
kv, err := valkeyrie.NewStore(
var err error
s.etcdAddr = net.JoinHostPort(s.getComposeServiceIP(c, "etcd"), "2379")
s.kvClient, err = valkeyrie.NewStore(
store.ETCDV3,
[]string{s.composeProject.Container(c, "etcd").NetworkSettings.IPAddress + ":2379"},
[]string{s.etcdAddr},
&store.Config{
ConnectionTimeout: 10 * time.Second,
},
@@ -39,27 +44,14 @@ func (s *EtcdSuite) setupStore(c *check.C) {
if err != nil {
c.Fatal("Cannot create store etcd")
}
s.kvClient = kv
// wait for etcd
err = try.Do(60*time.Second, try.KVExists(kv, "test"))
err = try.Do(60*time.Second, try.KVExists(s.kvClient, "test"))
c.Assert(err, checker.IsNil)
}
func (s *EtcdSuite) TearDownTest(c *check.C) {
// shutdown and delete compose project
if s.composeProject != nil {
s.composeProject.Stop(c)
}
}
func (s *EtcdSuite) TearDownSuite(c *check.C) {}
func (s *EtcdSuite) TestSimpleConfiguration(c *check.C) {
s.setupStore(c)
address := s.composeProject.Container(c, "etcd").NetworkSettings.IPAddress + ":2379"
file := s.adaptFile(c, "fixtures/etcd/simple.toml", struct{ EtcdAddress string }{address})
file := s.adaptFile(c, "fixtures/etcd/simple.toml", struct{ EtcdAddress string }{s.etcdAddr})
defer os.Remove(file)
data := map[string]string{

View File

@@ -9,7 +9,9 @@ import (
"github.com/traefik/traefik/v2/pkg/log"
)
type handler struct{}
type handler struct {
traefikIP string
}
// ServeDNS a fake DNS server
// Simplified version of the Challenge Test Server from Boulder
@@ -21,11 +23,6 @@ func (s *handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
m.SetReply(r)
m.Compress = false
fakeDNS := os.Getenv("DOCKER_HOST_IP")
if fakeDNS == "" {
fakeDNS = "127.0.0.1"
}
for _, q := range r.Question {
logger.Infof("Query -- [%s] %s", q.Name, dns.TypeToString[q.Qtype])
@@ -38,7 +35,7 @@ func (s *handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
Class: dns.ClassINET,
Ttl: 0,
}
record.A = net.ParseIP(fakeDNS)
record.A = net.ParseIP(s.traefikIP)
m.Answer = append(m.Answer, record)
case dns.TypeCAA:
@@ -101,11 +98,11 @@ func (s *handler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
}
}
func startFakeDNSServer() *dns.Server {
func startFakeDNSServer(traefikIP string) *dns.Server {
srv := &dns.Server{
Addr: ":5053",
Net: "udp",
Handler: &handler{},
Handler: &handler{traefikIP},
}
go func() {

View File

@@ -15,7 +15,7 @@ type FileSuite struct{ BaseSuite }
func (s *FileSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "file")
s.composeProject.Start(c)
s.composeUp(c)
}
func (s *FileSuite) TestSimpleConfiguration(c *check.C) {

View File

@@ -6,4 +6,4 @@
[http.services]
[http.services.service2.loadBalancer]
[[http.services.service2.loadBalancer.servers]]
url = "http://172.17.0.123:80"
url = "http://127.0.0.1:80"

View File

@@ -33,13 +33,13 @@
[http.services.service1.loadBalancer]
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoamiEndpoint}}:8080"
url = "http://{{ .WhoamiIP }}:8080"
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoamiEndpoint}}:8081"
url = "http://{{ .WhoamiIP }}:8081"
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoamiEndpoint}}:8082"
url = "http://{{ .WhoamiIP }}:8082"
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoamiEndpoint}}:80"
url = "http://{{ .WhoamiIP }}:80"

View File

@@ -31,7 +31,7 @@
[http.services.service1.loadBalancer]
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoamiEndpoint}}:8080"
url = "http://{{ .WhoamiIP }}:8080"
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoamiEndpoint}}:80"
url = "http://{{ .WhoamiIP }}:80"

View File

@@ -27,7 +27,7 @@
[tcp.services]
[tcp.services.whoami-no-tls.loadBalancer]
[[tcp.services.whoami-no-tls.loadBalancer.servers]]
address = "localhost:8086"
address = "whoami-no-tls:8080"
[http]
[http.routers]
@@ -40,4 +40,4 @@
[http.services]
[http.services.whoami.loadBalancer]
[[http.services.whoami.loadBalancer.servers]]
url = "http://localhost:8085"
url = "http://whoami:80"

View File

@@ -27,4 +27,4 @@
[tcp.services]
[tcp.services.whoami-no-tls.loadBalancer]
[[tcp.services.whoami-no-tls.loadBalancer.servers]]
address = "localhost:8086"
address = "whoami-banner:8080"

View File

@@ -38,18 +38,14 @@
[tcp.services]
[tcp.services.whoami-a.loadBalancer]
[[tcp.services.whoami-a.loadBalancer.servers]]
address = "localhost:8081"
address = "whoami-a:8080"
[tcp.services.whoami-b.loadBalancer]
[[tcp.services.whoami-b.loadBalancer.servers]]
address = "localhost:8082"
address = "whoami-b:8080"
[tcp.middlewares]
[tcp.middlewares.allowing-ipwhitelist.ipWhiteList]
sourceRange = ["127.0.0.1/32"]
[tcp.middlewares.blocking-ipwhitelist.ipWhiteList]
sourceRange = ["127.127.127.127/32"]
[[tls.certificates]]
certFile = "fixtures/tcp/whoami-c.crt"
keyFile = "fixtures/tcp/whoami-c.key"

View File

@@ -29,11 +29,15 @@
rule = "Path(`/whoami/`)"
service = "whoami"
[http.routers.my-https-router.tls]
[http.routers.api]
rule = "PathPrefix(`/api`)"
service = "api@internal"
entryPoints = ["traefik"]
[http.services]
[http.services.whoami.loadBalancer]
[[http.services.whoami.loadBalancer.servers]]
url = "http://localhost:8085"
url = "http://whoami:80"
[tcp]
[tcp.routers]
[tcp.routers.to-whoami-a]
@@ -58,15 +62,15 @@
[tcp.services.whoami-a.loadBalancer]
[[tcp.services.whoami-a.loadBalancer.servers]]
address = "localhost:8081"
address = "whoami-a:8080"
[tcp.services.whoami-b.loadBalancer]
[[tcp.services.whoami-b.loadBalancer.servers]]
address = "localhost:8082"
address = "whoami-b:8080"
[tcp.services.whoami-no-cert.loadBalancer]
[[tcp.services.whoami-no-cert.loadBalancer.servers]]
address = "localhost:8083"
address = "whoami-no-cert:8080"
[[tls.certificates]]
certFile = "fixtures/tcp/whoami-c.crt"

View File

@@ -36,7 +36,7 @@
[tcp.services.whoami-no-cert]
[tcp.services.whoami-no-cert.loadBalancer]
[[tcp.services.whoami-no-cert.loadBalancer.servers]]
address = "localhost:8083"
address = "whoami-no-cert:8080"
[tls.options]

View File

@@ -24,14 +24,14 @@
service = "whoami-a"
entryPoints = [ "tcp" ]
[tcp.routers.to-whoami-a.tls]
passthrough=true
passthrough = true
[tcp.routers.to-whoami-b]
rule = "HostSNI(`whoami-b.test`)"
service = "whoami-b"
entryPoints = [ "tcp" ]
[tcp.routers.to-whoami-b.tls]
passthrough=true
passthrough = true
[tcp.routers.to-whoami-no-cert]
rule = "HostSNI(`whoami-c.test`)"
@@ -47,16 +47,17 @@
[tcp.services]
[tcp.services.whoami-no-tls.loadBalancer]
[[tcp.services.whoami-no-tls.loadBalancer.servers]]
address = "localhost:8084"
address = "whoami-no-tls:8080"
[tcp.services.whoami-a.loadBalancer]
[[tcp.services.whoami-a.loadBalancer.servers]]
address = "localhost:8081"
address = "whoami-a:8080"
[tcp.services.whoami-b.loadBalancer]
[[tcp.services.whoami-b.loadBalancer.servers]]
address = "localhost:8082"
address = "whoami-b:8080"
[tcp.services.whoami-no-cert.loadBalancer]
[[tcp.services.whoami-no-cert.loadBalancer.servers]]
address = "localhost:8083"
address = "whoami-no-cert:8080"

View File

@@ -27,4 +27,4 @@
[tcp.services]
[tcp.services.whoami-no-tls.loadBalancer]
[[tcp.services.whoami-no-tls.loadBalancer.servers]]
address = "localhost:8084"
address = "whoami-no-tls:8080"

View File

@@ -18,25 +18,24 @@
## dynamic configuration ##
[tcp]
[tcp.routers]
[tcp.routers.to-whoami-a]
rule = "HostSNI(`whoami-a.test`)"
[tcp.routers.to-whoami-b]
rule = "HostSNI(`whoami-b.test`)"
service = "whoami"
entryPoints = [ "tcp" ]
[tcp.routers.to-whoami-a.tls]
[tcp.routers.to-whoami-b.tls]
passthrough=true
[[tcp.services.whoami.weighted.services]]
name="whoami-a"
name="whoami-b"
weight=3
[[tcp.services.whoami.weighted.services]]
name="whoami-b"
name="whoami-ab"
weight=1
[tcp.services.whoami-a.loadBalancer]
[[tcp.services.whoami-a.loadBalancer.servers]]
address = "localhost:8081"
[tcp.services.whoami-b.loadBalancer]
[[tcp.services.whoami-b.loadBalancer.servers]]
address = "localhost:8082"
address = "whoami-b:8080"
[tcp.services.whoami-ab.loadBalancer]
[[tcp.services.whoami-ab.loadBalancer.servers]]
address = "whoami-ab:8080"

View File

@@ -55,16 +55,16 @@
[http.services.service1.loadBalancer]
passHostHeader = true
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}"
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service2]
[http.services.service2.loadBalancer]
passHostHeader = true
[[http.services.service2.loadBalancer.servers]]
url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}"
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service3]
[http.services.service3.loadBalancer]
passHostHeader = true
[[http.services.service3.loadBalancer.servers]]
url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}"
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"

View File

@@ -54,16 +54,16 @@
[http.services.service1.loadBalancer]
passHostHeader = true
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}"
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service2]
[http.services.service2.loadBalancer]
passHostHeader = true
[[http.services.service2.loadBalancer.servers]]
url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}"
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service3]
[http.services.service3.loadBalancer]
passHostHeader = true
[[http.services.service3.loadBalancer.servers]]
url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}"
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"

View File

@@ -50,16 +50,16 @@
[http.services.service1.loadBalancer]
passHostHeader = true
[[http.services.service1.loadBalancer.servers]]
url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}"
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service2]
[http.services.service2.loadBalancer]
passHostHeader = true
[[http.services.service2.loadBalancer.servers]]
url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}"
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"
[http.services.service3]
[http.services.service3.loadBalancer]
passHostHeader = true
[[http.services.service3.loadBalancer.servers]]
url = "http://{{.WhoAmiIP}}:{{.WhoAmiPort}}"
url = "http://{{.WhoamiIP}}:{{.WhoamiPort}}"

View File

@@ -13,7 +13,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// HealthCheck test suites (using libcompose).
// HealthCheck test suites.
type HealthCheckSuite struct {
BaseSuite
whoami1IP string
@@ -24,12 +24,12 @@ type HealthCheckSuite struct {
func (s *HealthCheckSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "healthcheck")
s.composeProject.Start(c)
s.composeUp(c)
s.whoami1IP = s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress
s.whoami2IP = s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress
s.whoami3IP = s.composeProject.Container(c, "whoami3").NetworkSettings.IPAddress
s.whoami4IP = s.composeProject.Container(c, "whoami4").NetworkSettings.IPAddress
s.whoami1IP = s.getComposeServiceIP(c, "whoami1")
s.whoami2IP = s.getComposeServiceIP(c, "whoami2")
s.whoami3IP = s.getComposeServiceIP(c, "whoami3")
s.whoami4IP = s.getComposeServiceIP(c, "whoami4")
}
func (s *HealthCheckSuite) TestSimpleConfiguration(c *check.C) {
@@ -90,7 +90,7 @@ func (s *HealthCheckSuite) TestSimpleConfiguration(c *check.C) {
// Check if the service with bad health check (whoami2) never respond.
err = try.Request(frontendReq, 2*time.Second, try.BodyContains(s.whoami2IP))
c.Assert(err, checker.Not(checker.IsNil))
c.Assert(err, checker.NotNil)
// TODO validate : run on 80
resp, err := http.Get("http://127.0.0.1:8000/")

View File

@@ -13,9 +13,7 @@ type HostResolverSuite struct{ BaseSuite }
func (s *HostResolverSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "hostresolver")
s.composeProject.Start(c)
s.composeProject.Container(c, "server1")
s.composeUp(c)
}
func (s *HostResolverSuite) TestSimpleConfig(c *check.C) {
@@ -48,7 +46,7 @@ func (s *HostResolverSuite) TestSimpleConfig(c *check.C) {
c.Assert(err, checker.IsNil)
req.Host = test.host
err = try.Request(req, 500*time.Millisecond, try.StatusCodeIs(test.status), try.HasBody())
err = try.Request(req, 1*time.Second, try.StatusCodeIs(test.status), try.HasBody())
c.Assert(err, checker.IsNil)
}
}

View File

@@ -1063,13 +1063,13 @@ func (s *HTTPSSuite) TestEntryPointHttpsRedirectAndPathModification(c *check.C)
for _, test := range testCases {
sourceURL := fmt.Sprintf("http://127.0.0.1:8888%s", test.path)
for _, host := range test.hosts {
req, err := http.NewRequest("GET", sourceURL, nil)
req, err := http.NewRequest(http.MethodGet, sourceURL, nil)
c.Assert(err, checker.IsNil)
req.Host = host
resp, err := client.Do(req)
c.Assert(err, checker.IsNil)
defer resp.Body.Close()
resp.Body.Close()
location := resp.Header.Get("Location")
expected := fmt.Sprintf("https://%s:8443%s", host, test.path)

View File

@@ -3,9 +3,9 @@ package integration
import (
"bytes"
"context"
"flag"
"fmt"
"net"
"os"
"os/exec"
"path/filepath"
@@ -14,17 +14,23 @@ import (
"text/template"
"time"
"github.com/compose-spec/compose-go/cli"
"github.com/compose-spec/compose-go/types"
"github.com/docker/cli/cli/config/configfile"
"github.com/docker/compose/v2/cmd/formatter"
composeapi "github.com/docker/compose/v2/pkg/api"
"github.com/docker/compose/v2/pkg/compose"
dockertypes "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/client"
"github.com/fatih/structs"
"github.com/go-check/check"
compose "github.com/libkermit/compose/check"
"github.com/traefik/traefik/v2/pkg/log"
checker "github.com/vdemeester/shakers"
)
var (
integration = flag.Bool("integration", false, "run integration tests")
container = flag.Bool("container", false, "run container integration tests")
host = flag.Bool("host", false, "run host integration tests")
showLog = flag.Bool("tlog", false, "always show Traefik logs")
)
@@ -34,45 +40,39 @@ func Test(t *testing.T) {
return
}
if *container {
// tests launched from a container
check.Suite(&AccessLogSuite{})
check.Suite(&AcmeSuite{})
check.Suite(&EtcdSuite{})
check.Suite(&ConsulSuite{})
check.Suite(&ConsulCatalogSuite{})
check.Suite(&DockerComposeSuite{})
check.Suite(&DockerSuite{})
check.Suite(&ErrorPagesSuite{})
check.Suite(&FileSuite{})
check.Suite(&GRPCSuite{})
check.Suite(&HealthCheckSuite{})
check.Suite(&HeadersSuite{})
check.Suite(&HostResolverSuite{})
check.Suite(&HTTPSuite{})
check.Suite(&HTTPSSuite{})
check.Suite(&KeepAliveSuite{})
check.Suite(&LogRotationSuite{})
check.Suite(&MarathonSuite{})
check.Suite(&MarathonSuite15{})
check.Suite(&RateLimitSuite{})
check.Suite(&RedisSuite{})
check.Suite(&RestSuite{})
check.Suite(&RetrySuite{})
check.Suite(&SimpleSuite{})
check.Suite(&TimeoutSuite{})
check.Suite(&TLSClientHeadersSuite{})
check.Suite(&TracingSuite{})
check.Suite(&UDPSuite{})
check.Suite(&WebsocketSuite{})
check.Suite(&ZookeeperSuite{})
}
if *host {
// tests launched from the host
check.Suite(&K8sSuite{})
check.Suite(&ProxyProtocolSuite{})
check.Suite(&TCPSuite{})
}
check.Suite(&AccessLogSuite{})
check.Suite(&AcmeSuite{})
check.Suite(&ConsulCatalogSuite{})
check.Suite(&ConsulSuite{})
check.Suite(&DockerComposeSuite{})
check.Suite(&DockerSuite{})
check.Suite(&ErrorPagesSuite{})
check.Suite(&EtcdSuite{})
check.Suite(&FileSuite{})
check.Suite(&GRPCSuite{})
check.Suite(&HeadersSuite{})
check.Suite(&HealthCheckSuite{})
check.Suite(&HostResolverSuite{})
check.Suite(&HTTPSSuite{})
check.Suite(&HTTPSuite{})
check.Suite(&K8sSuite{})
check.Suite(&KeepAliveSuite{})
check.Suite(&LogRotationSuite{})
check.Suite(&MarathonSuite15{})
check.Suite(&MarathonSuite{})
check.Suite(&ProxyProtocolSuite{})
check.Suite(&RateLimitSuite{})
check.Suite(&RedisSuite{})
check.Suite(&RestSuite{})
check.Suite(&RetrySuite{})
check.Suite(&SimpleSuite{})
check.Suite(&TCPSuite{})
check.Suite(&TimeoutSuite{})
check.Suite(&TLSClientHeadersSuite{})
check.Suite(&TracingSuite{})
check.Suite(&UDPSuite{})
check.Suite(&WebsocketSuite{})
check.Suite(&ZookeeperSuite{})
check.TestingT(t)
}
@@ -80,36 +80,72 @@ func Test(t *testing.T) {
var traefikBinary = "../dist/traefik"
type BaseSuite struct {
composeProject *compose.Project
composeProject *types.Project
dockerComposeService composeapi.Service
dockerClient *client.Client
}
func (s *BaseSuite) TearDownSuite(c *check.C) {
// shutdown and delete compose project
if s.composeProject != nil {
s.composeProject.Stop(c)
if s.composeProject != nil && s.dockerComposeService != nil {
s.composeDown(c)
}
}
// createComposeProject creates the docker compose project stored as a field in the BaseSuite.
// This method should be called before starting and/or stopping compose services.
func (s *BaseSuite) createComposeProject(c *check.C, name string) {
projectName := fmt.Sprintf("integration-test-%s", name)
projectName := fmt.Sprintf("traefik-integration-test-%s", name)
composeFile := fmt.Sprintf("resources/compose/%s.yml", name)
addrs, err := net.InterfaceAddrs()
var err error
s.dockerClient, err = client.NewClientWithOpts()
c.Assert(err, checker.IsNil)
for _, addr := range addrs {
ip, _, err := net.ParseCIDR(addr.String())
c.Assert(err, checker.IsNil)
if !ip.IsLoopback() && ip.To4() != nil {
_ = os.Setenv("DOCKER_HOST_IP", ip.String())
break
}
}
s.composeProject = compose.CreateProject(c, projectName, composeFile)
s.dockerComposeService = compose.NewComposeService(s.dockerClient, &configfile.ConfigFile{})
ops, err := cli.NewProjectOptions([]string{composeFile}, cli.WithName(projectName))
c.Assert(err, checker.IsNil)
s.composeProject, err = cli.ProjectFromOptions(ops)
c.Assert(err, checker.IsNil)
}
func withConfigFile(file string) string {
return "--configFile=" + file
// composeUp starts the given services of the current docker compose project, if they are not already started.
// Already running services are not affected (i.e. not stopped).
func (s *BaseSuite) composeUp(c *check.C, services ...string) {
c.Assert(s.composeProject, check.NotNil)
c.Assert(s.dockerComposeService, check.NotNil)
// We use Create and Restart instead of Up, because the only option that actually works to control which containers
// are started is within the RestartOptions.
err := s.dockerComposeService.Create(context.Background(), s.composeProject, composeapi.CreateOptions{})
c.Assert(err, checker.IsNil)
err = s.dockerComposeService.Restart(context.Background(), s.composeProject, composeapi.RestartOptions{Services: services})
c.Assert(err, checker.IsNil)
}
// composeStop stops the given services of the current docker compose project and removes the corresponding containers.
func (s *BaseSuite) composeStop(c *check.C, services ...string) {
c.Assert(s.dockerComposeService, check.NotNil)
c.Assert(s.composeProject, check.NotNil)
err := s.dockerComposeService.Stop(context.Background(), s.composeProject, composeapi.StopOptions{Services: services})
c.Assert(err, checker.IsNil)
err = s.dockerComposeService.Remove(context.Background(), s.composeProject, composeapi.RemoveOptions{
Services: services,
Force: true,
})
c.Assert(err, checker.IsNil)
}
// composeDown stops all compose project services and removes the corresponding containers.
func (s *BaseSuite) composeDown(c *check.C) {
c.Assert(s.dockerComposeService, check.NotNil)
c.Assert(s.composeProject, check.NotNil)
err := s.dockerComposeService.Down(context.Background(), s.composeProject.Name, composeapi.DownOptions{})
c.Assert(err, checker.IsNil)
}
func (s *BaseSuite) cmdTraefik(args ...string) (*exec.Cmd, *bytes.Buffer) {
@@ -134,6 +170,7 @@ func (s *BaseSuite) traefikCmd(args ...string) (*exec.Cmd, func(*check.C)) {
return cmd, func(c *check.C) {
if c.Failed() || *showLog {
s.displayLogK3S(c)
s.displayLogCompose(c)
s.displayTraefikLog(c, out)
}
}
@@ -153,6 +190,25 @@ func (s *BaseSuite) displayLogK3S(c *check.C) {
log.WithoutContext().Println()
}
func (s *BaseSuite) displayLogCompose(c *check.C) {
if s.dockerComposeService == nil || s.composeProject == nil {
log.WithoutContext().Infof("%s: No docker compose logs.", c.TestName())
return
}
log.WithoutContext().Infof("%s: docker compose logs: ", c.TestName())
logWriter := log.WithoutContext().WriterLevel(log.GetLevel())
logConsumer := formatter.NewLogConsumer(context.Background(), logWriter, false, true)
err := s.dockerComposeService.Logs(context.Background(), s.composeProject.Name, logConsumer, composeapi.LogOptions{})
c.Assert(err, checker.IsNil)
log.WithoutContext().Println()
log.WithoutContext().Println("################################")
log.WithoutContext().Println()
}
func (s *BaseSuite) displayTraefikLog(c *check.C, output *bytes.Buffer) {
if output == nil || output.Len() == 0 {
log.WithoutContext().Infof("%s: No Traefik logs.", c.TestName())
@@ -168,6 +224,7 @@ func (s *BaseSuite) getDockerHost() string {
// Default docker socket
dockerHost = "unix:///var/run/docker.sock"
}
return dockerHost
}
@@ -192,3 +249,38 @@ func (s *BaseSuite) adaptFile(c *check.C, path string, tempObjects interface{})
return tmpFile.Name()
}
func (s *BaseSuite) getComposeServiceIP(c *check.C, name string) string {
filter := filters.NewArgs(
filters.Arg("label", fmt.Sprintf("%s=%s", composeapi.ProjectLabel, s.composeProject.Name)),
filters.Arg("label", fmt.Sprintf("%s=%s", composeapi.ServiceLabel, name)),
)
containers, err := s.dockerClient.ContainerList(context.Background(), dockertypes.ContainerListOptions{Filters: filter})
c.Assert(err, checker.IsNil)
c.Assert(containers, checker.HasLen, 1)
networkNames := s.composeProject.NetworkNames()
c.Assert(networkNames, checker.HasLen, 1)
network := s.composeProject.Networks[networkNames[0]]
return containers[0].NetworkSettings.Networks[network.Name].IPAddress
}
func (s *BaseSuite) getContainerIP(c *check.C, name string) string {
container, err := s.dockerClient.ContainerInspect(context.Background(), name)
c.Assert(err, checker.IsNil)
c.Assert(container.NetworkSettings.Networks, check.NotNil)
for _, network := range container.NetworkSettings.Networks {
return network.IPAddress
}
// Should never happen.
c.Error("No network found")
return ""
}
func withConfigFile(file string) string {
return "--configFile=" + file
}

View File

@@ -28,7 +28,7 @@ type K8sSuite struct{ BaseSuite }
func (s *K8sSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "k8s")
s.composeProject.Start(c)
s.composeUp(c)
abs, err := filepath.Abs("./fixtures/k8s/config.skip/kubeconfig.yaml")
c.Assert(err, checker.IsNil)
@@ -44,7 +44,7 @@ func (s *K8sSuite) SetUpSuite(c *check.C) {
}
func (s *K8sSuite) TearDownSuite(c *check.C) {
s.composeProject.Stop(c)
s.composeDown(c)
generatedFiles := []string{
"./fixtures/k8s/config.skip/kubeconfig.yaml",
@@ -56,8 +56,7 @@ func (s *K8sSuite) TearDownSuite(c *check.C) {
}
for _, filename := range generatedFiles {
err := os.Remove(filename)
if err != nil {
if err := os.Remove(filename); err != nil {
log.WithoutContext().Warning(err)
}
}

View File

@@ -13,17 +13,38 @@ import (
"github.com/go-check/check"
"github.com/traefik/traefik/v2/integration/try"
"github.com/traefik/traefik/v2/pkg/log"
checker "github.com/vdemeester/shakers"
)
const (
traefikTestLogFileRotated = traefikTestLogFile + ".rotated"
traefikTestAccessLogFileRotated = traefikTestAccessLogFile + ".rotated"
)
// Log rotation integration test suite.
type LogRotationSuite struct{ BaseSuite }
func (s *LogRotationSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "access_log")
s.composeProject.Start(c)
s.composeUp(c)
}
s.composeProject.Container(c, "server1")
func (s *LogRotationSuite) TearDownSuite(c *check.C) {
s.composeDown(c)
generatedFiles := []string{
traefikTestLogFile,
traefikTestLogFileRotated,
traefikTestAccessLogFile,
traefikTestAccessLogFileRotated,
}
for _, filename := range generatedFiles {
if err := os.Remove(filename); err != nil {
log.WithoutContext().Warning(err)
}
}
}
func (s *LogRotationSuite) TestAccessLogRotation(c *check.C) {
@@ -36,8 +57,6 @@ func (s *LogRotationSuite) TestAccessLogRotation(c *check.C) {
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
defer os.Remove(traefikTestAccessLogFile)
// Verify Traefik started ok
verifyEmptyErrorLog(c, "traefik.log")
@@ -52,7 +71,7 @@ func (s *LogRotationSuite) TestAccessLogRotation(c *check.C) {
c.Assert(err, checker.IsNil)
// Rename access log
err = os.Rename(traefikTestAccessLogFile, traefikTestAccessLogFile+".rotated")
err = os.Rename(traefikTestAccessLogFile, traefikTestAccessLogFileRotated)
c.Assert(err, checker.IsNil)
// in the midst of the requests, issue SIGUSR1 signal to server process
@@ -66,8 +85,8 @@ func (s *LogRotationSuite) TestAccessLogRotation(c *check.C) {
c.Assert(err, checker.IsNil)
// Verify access.log.rotated output as expected
logAccessLogFile(c, traefikTestAccessLogFile+".rotated")
lineCount := verifyLogLines(c, traefikTestAccessLogFile+".rotated", 0, true)
logAccessLogFile(c, traefikTestAccessLogFileRotated)
lineCount := verifyLogLines(c, traefikTestAccessLogFileRotated, 0, true)
c.Assert(lineCount, checker.GreaterOrEqualThan, 1)
// make sure that the access log file is at least created before we do assertions on it
@@ -95,12 +114,10 @@ func (s *LogRotationSuite) TestTraefikLogRotation(c *check.C) {
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
defer os.Remove(traefikTestAccessLogFile)
waitForTraefik(c, "server1")
// Rename traefik log
err = os.Rename(traefikTestLogFile, traefikTestLogFile+".rotated")
err = os.Rename(traefikTestLogFile, traefikTestLogFileRotated)
c.Assert(err, checker.IsNil)
// issue SIGUSR1 signal to server process
@@ -118,7 +135,7 @@ func (s *LogRotationSuite) TestTraefikLogRotation(c *check.C) {
c.Assert(err, checker.IsNil)
// we have at least 6 lines in traefik.log.rotated
lineCount := verifyLogLines(c, traefikTestLogFile+".rotated", 0, false)
lineCount := verifyLogLines(c, traefikTestLogFileRotated, 0, false)
// GreaterOrEqualThan used to ensure test doesn't break
// If more log entries are output on startup

View File

@@ -1,7 +1,6 @@
package integration
import (
"fmt"
"net/http"
"os"
"time"
@@ -12,7 +11,7 @@ import (
checker "github.com/vdemeester/shakers"
)
// Marathon test suites (using libcompose).
// Marathon test suites.
type MarathonSuite15 struct {
BaseSuite
marathonURL string
@@ -20,53 +19,15 @@ type MarathonSuite15 struct {
func (s *MarathonSuite15) SetUpSuite(c *check.C) {
s.createComposeProject(c, "marathon15")
s.composeProject.Start(c)
s.composeUp(c)
marathonIPAddr := s.composeProject.Container(c, containerNameMarathon).NetworkSettings.IPAddress
c.Assert(marathonIPAddr, checker.Not(checker.HasLen), 0)
s.marathonURL = "http://" + marathonIPAddr + ":8080"
s.marathonURL = "http://" + containerNameMarathon + ":8080"
// Wait for Marathon readiness prior to creating the client so that we
// don't run into the "all cluster members down" state right from the
// start.
err := try.GetRequest(s.marathonURL+"/v2/leader", 1*time.Minute, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
// Add entry for Mesos slave container IP address in the hosts file so
// that Traefik can properly forward traffic.
// This is necessary as long as we are still using the docker-compose v1
// spec. Once we switch to v2 or higher, we can have both the test/builder
// container and the Mesos slave container join the same custom network and
// enjoy DNS-discoverable container host names.
mesosSlaveIPAddr := s.composeProject.Container(c, containerNameMesosSlave).NetworkSettings.IPAddress
c.Assert(mesosSlaveIPAddr, checker.Not(checker.HasLen), 0)
err = s.extendDockerHostsFile(containerNameMesosSlave, mesosSlaveIPAddr)
c.Assert(err, checker.IsNil)
}
// extendDockerHostsFile extends the hosts file (/etc/hosts) by the given
// host/IP address mapping if we are running inside a container.
func (s *MarathonSuite15) extendDockerHostsFile(host, ipAddr string) error {
const hostsFile = "/etc/hosts"
// Determine if the run inside a container. The most reliable way to
// do this is to inject an indicator, which we do in terms of an
// environment variable.
// (See also https://groups.google.com/d/topic/docker-user/JOGE7AnJ3Gw/discussion.)
if os.Getenv("CONTAINER") == "DOCKER" {
// We are running inside a container -- extend the hosts file.
file, err := os.OpenFile(hostsFile, os.O_APPEND|os.O_WRONLY, 0o600)
if err != nil {
return err
}
defer file.Close()
if _, err = file.WriteString(fmt.Sprintf("%s\t%s\n", ipAddr, host)); err != nil {
return err
}
}
return nil
}
func (s *MarathonSuite15) TestConfigurationUpdate(c *check.C) {

View File

@@ -1,7 +1,6 @@
package integration
import (
"fmt"
"net/http"
"os"
"time"
@@ -12,12 +11,9 @@ import (
checker "github.com/vdemeester/shakers"
)
const (
containerNameMesosSlave = "mesos-slave"
containerNameMarathon = "marathon"
)
const containerNameMarathon = "marathon"
// Marathon test suites (using libcompose).
// Marathon test suites.
type MarathonSuite struct {
BaseSuite
marathonURL string
@@ -25,53 +21,15 @@ type MarathonSuite struct {
func (s *MarathonSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "marathon")
s.composeProject.Start(c)
s.composeUp(c)
marathonIPAddr := s.composeProject.Container(c, containerNameMarathon).NetworkSettings.IPAddress
c.Assert(marathonIPAddr, checker.Not(checker.HasLen), 0)
s.marathonURL = "http://" + marathonIPAddr + ":8080"
s.marathonURL = "http://" + containerNameMarathon + ":8080"
// Wait for Marathon readiness prior to creating the client so that we
// don't run into the "all cluster members down" state right from the
// start.
err := try.GetRequest(s.marathonURL+"/v2/leader", 1*time.Minute, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
// Add entry for Mesos slave container IP address in the hosts file so
// that Traefik can properly forward traffic.
// This is necessary as long as we are still using the docker-compose v1
// spec. Once we switch to v2 or higher, we can have both the test/builder
// container and the Mesos slave container join the same custom network and
// enjoy DNS-discoverable container host names.
mesosSlaveIPAddr := s.composeProject.Container(c, containerNameMesosSlave).NetworkSettings.IPAddress
c.Assert(mesosSlaveIPAddr, checker.Not(checker.HasLen), 0)
err = s.extendDockerHostsFile(containerNameMesosSlave, mesosSlaveIPAddr)
c.Assert(err, checker.IsNil)
}
// extendDockerHostsFile extends the hosts file (/etc/hosts) by the given
// host/IP address mapping if we are running inside a container.
func (s *MarathonSuite) extendDockerHostsFile(host, ipAddr string) error {
const hostsFile = "/etc/hosts"
// Determine if the run inside a container. The most reliable way to
// do this is to inject an indicator, which we do in terms of an
// environment variable.
// (See also https://groups.google.com/d/topic/docker-user/JOGE7AnJ3Gw/discussion.)
if os.Getenv("CONTAINER") == "DOCKER" {
// We are running inside a container -- extend the hosts file.
file, err := os.OpenFile(hostsFile, os.O_APPEND|os.O_WRONLY, 0o600)
if err != nil {
return err
}
defer file.Close()
if _, err = file.WriteString(fmt.Sprintf("%s\t%s\n", ipAddr, host)); err != nil {
return err
}
}
return nil
}
func deployApplication(c *check.C, client marathon.Marathon, application *marathon.Application) {

View File

@@ -10,22 +10,27 @@ import (
checker "github.com/vdemeester/shakers"
)
type ProxyProtocolSuite struct{ BaseSuite }
type ProxyProtocolSuite struct {
BaseSuite
gatewayIP string
haproxyIP string
whoamiIP string
}
func (s *ProxyProtocolSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "proxy-protocol")
s.composeProject.Start(c)
s.composeUp(c)
s.gatewayIP = s.getContainerIP(c, "traefik")
s.haproxyIP = s.getComposeServiceIP(c, "haproxy")
s.whoamiIP = s.getComposeServiceIP(c, "whoami")
}
func (s *ProxyProtocolSuite) TestProxyProtocolTrusted(c *check.C) {
gatewayIP := s.composeProject.Container(c, "haproxy").NetworkSettings.Gateway
haproxyIP := s.composeProject.Container(c, "haproxy").NetworkSettings.IPAddress
whoamiIP := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress
file := s.adaptFile(c, "fixtures/proxy-protocol/with.toml", struct {
HaproxyIP string
WhoamiIP string
}{HaproxyIP: haproxyIP, WhoamiIP: whoamiIP})
}{HaproxyIP: s.haproxyIP, WhoamiIP: s.whoamiIP})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
@@ -34,21 +39,17 @@ func (s *ProxyProtocolSuite) TestProxyProtocolTrusted(c *check.C) {
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
err = try.GetRequest("http://"+haproxyIP+"/whoami", 1*time.Second,
err = try.GetRequest("http://"+s.haproxyIP+"/whoami", 1*time.Second,
try.StatusCodeIs(http.StatusOK),
try.BodyContains("X-Forwarded-For: "+gatewayIP))
try.BodyContains("X-Forwarded-For: "+s.gatewayIP))
c.Assert(err, checker.IsNil)
}
func (s *ProxyProtocolSuite) TestProxyProtocolV2Trusted(c *check.C) {
gatewayIP := s.composeProject.Container(c, "haproxy").NetworkSettings.Gateway
haproxyIP := s.composeProject.Container(c, "haproxy").NetworkSettings.IPAddress
whoamiIP := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress
file := s.adaptFile(c, "fixtures/proxy-protocol/with.toml", struct {
HaproxyIP string
WhoamiIP string
}{HaproxyIP: haproxyIP, WhoamiIP: whoamiIP})
}{HaproxyIP: s.haproxyIP, WhoamiIP: s.whoamiIP})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
@@ -57,20 +58,17 @@ func (s *ProxyProtocolSuite) TestProxyProtocolV2Trusted(c *check.C) {
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
err = try.GetRequest("http://"+haproxyIP+":81/whoami", 1*time.Second,
err = try.GetRequest("http://"+s.haproxyIP+":81/whoami", 1*time.Second,
try.StatusCodeIs(http.StatusOK),
try.BodyContains("X-Forwarded-For: "+gatewayIP))
try.BodyContains("X-Forwarded-For: "+s.gatewayIP))
c.Assert(err, checker.IsNil)
}
func (s *ProxyProtocolSuite) TestProxyProtocolNotTrusted(c *check.C) {
haproxyIP := s.composeProject.Container(c, "haproxy").NetworkSettings.IPAddress
whoamiIP := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress
file := s.adaptFile(c, "fixtures/proxy-protocol/without.toml", struct {
HaproxyIP string
WhoamiIP string
}{HaproxyIP: haproxyIP, WhoamiIP: whoamiIP})
}{HaproxyIP: s.haproxyIP, WhoamiIP: s.whoamiIP})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
@@ -79,20 +77,17 @@ func (s *ProxyProtocolSuite) TestProxyProtocolNotTrusted(c *check.C) {
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
err = try.GetRequest("http://"+haproxyIP+"/whoami", 1*time.Second,
err = try.GetRequest("http://"+s.haproxyIP+"/whoami", 1*time.Second,
try.StatusCodeIs(http.StatusOK),
try.BodyContains("X-Forwarded-For: "+haproxyIP))
try.BodyContains("X-Forwarded-For: "+s.haproxyIP))
c.Assert(err, checker.IsNil)
}
func (s *ProxyProtocolSuite) TestProxyProtocolV2NotTrusted(c *check.C) {
haproxyIP := s.composeProject.Container(c, "haproxy").NetworkSettings.IPAddress
whoamiIP := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress
file := s.adaptFile(c, "fixtures/proxy-protocol/without.toml", struct {
HaproxyIP string
WhoamiIP string
}{HaproxyIP: haproxyIP, WhoamiIP: whoamiIP})
}{HaproxyIP: s.haproxyIP, WhoamiIP: s.whoamiIP})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
@@ -101,8 +96,8 @@ func (s *ProxyProtocolSuite) TestProxyProtocolV2NotTrusted(c *check.C) {
c.Assert(err, checker.IsNil)
defer s.killCmd(cmd)
err = try.GetRequest("http://"+haproxyIP+":81/whoami", 1*time.Second,
err = try.GetRequest("http://"+s.haproxyIP+":81/whoami", 1*time.Second,
try.StatusCodeIs(http.StatusOK),
try.BodyContains("X-Forwarded-For: "+haproxyIP))
try.BodyContains("X-Forwarded-For: "+s.haproxyIP))
c.Assert(err, checker.IsNil)
}

View File

@@ -17,9 +17,9 @@ type RateLimitSuite struct {
func (s *RateLimitSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "ratelimit")
s.composeProject.Start(c)
s.composeUp(c)
s.ServerIP = s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress
s.ServerIP = s.getComposeServiceIP(c, "whoami1")
}
func (s *RateLimitSuite) TestSimpleConfiguration(c *check.C) {

View File

@@ -3,6 +3,7 @@ package integration
import (
"bytes"
"encoding/json"
"net"
"net/http"
"os"
"path/filepath"
@@ -18,20 +19,22 @@ import (
checker "github.com/vdemeester/shakers"
)
// Redis test suites (using libcompose).
// Redis test suites.
type RedisSuite struct {
BaseSuite
kvClient store.Store
kvClient store.Store
redisAddr string
}
func (s *RedisSuite) setupStore(c *check.C) {
s.createComposeProject(c, "redis")
s.composeProject.Start(c)
s.composeUp(c)
s.redisAddr = net.JoinHostPort(s.getComposeServiceIP(c, "redis"), "6379")
redis.Register()
kv, err := valkeyrie.NewStore(
store.REDIS,
[]string{s.composeProject.Container(c, "redis").NetworkSettings.IPAddress + ":6379"},
[]string{s.redisAddr},
&store.Config{
ConnectionTimeout: 10 * time.Second,
},
@@ -46,20 +49,10 @@ func (s *RedisSuite) setupStore(c *check.C) {
c.Assert(err, checker.IsNil)
}
func (s *RedisSuite) TearDownTest(c *check.C) {
// shutdown and delete compose project
if s.composeProject != nil {
s.composeProject.Stop(c)
}
}
func (s *RedisSuite) TearDownSuite(c *check.C) {}
func (s *RedisSuite) TestSimpleConfiguration(c *check.C) {
s.setupStore(c)
address := s.composeProject.Container(c, "redis").NetworkSettings.IPAddress + ":6379"
file := s.adaptFile(c, "fixtures/redis/simple.toml", struct{ RedisAddress string }{address})
file := s.adaptFile(c, "fixtures/redis/simple.toml", struct{ RedisAddress string }{s.redisAddr})
defer os.Remove(file)
data := map[string]string{

View File

@@ -1,77 +1,91 @@
server0:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt-server0.entryPoints=web
- traefik.http.routers.rt-server0.rule=Path("/test")
- traefik.http.services.service1.loadbalancer.server.port=80
server1:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt-server1.entryPoints=web
- traefik.http.routers.rt-server1.rule=Host("frontend1.docker.local")
- traefik.http.routers.rt-server1.service=service1
- traefik.http.services.service1.loadbalancer.server.port=80
server2:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt-server2.entryPoints=web
- traefik.http.routers.rt-server2.rule=Host("frontend2.docker.local")
- traefik.http.services.service2.loadbalancer.server.port=80
server3:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt-server3.entryPoints=web
- traefik.http.routers.rt-server3.rule=Host("frontend2.docker.local")
- traefik.http.services.service2.loadbalancer.server.port=80
authFrontend:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt-authFrontend.entryPoints=httpFrontendAuth
- traefik.http.routers.rt-authFrontend.rule=Host("frontend.auth.docker.local")
- traefik.http.routers.rt-authFrontend.middlewares=basicauth
- traefik.http.middlewares.basicauth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/
- traefik.http.services.service3.loadbalancer.server.port=80
digestAuthMiddleware:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt-digestAuthMiddleware.entryPoints=digestAuth
- traefik.http.routers.rt-digestAuthMiddleware.rule=Host("entrypoint.digest.auth.docker.local")
- traefik.http.routers.rt-digestAuthMiddleware.middlewares=digestauth
- traefik.http.middlewares.digestauth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05, test2:traefik:518845800f9e2bfb1f1f740ec24f074e
- traefik.http.services.service3.loadbalancer.server.port=80
frontendRedirect:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt-frontendRedirect.entryPoints=frontendRedirect
- traefik.http.routers.rt-frontendRedirect.rule=Path("/test")
- traefik.http.routers.rt-frontendRedirect.middlewares=redirecthttp
- traefik.http.middlewares.redirecthttp.redirectScheme.scheme=http
- traefik.http.middlewares.redirecthttp.redirectScheme.port=8000
- traefik.http.services.service3.loadbalancer.server.port=80
rateLimit:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt-rateLimit.entryPoints=httpRateLimit
- traefik.http.routers.rt-rateLimit.rule=Host("ratelimit.docker.local")
- traefik.http.routers.rt-rateLimit.middlewares=rate
- traefik.http.middlewares.rate.ratelimit
- traefik.http.middlewares.rate.ratelimit.average=1
- traefik.http.middlewares.rate.ratelimit.burst=2
- traefik.http.services.service3.loadbalancer.server.port=80
frontendWhitelist:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt-frontendWhitelist.entryPoints=web
- traefik.http.routers.rt-frontendWhitelist.rule=Host("frontend.whitelist.docker.local")
- traefik.http.routers.rt-frontendWhitelist.middlewares=wl
- traefik.http.middlewares.wl.ipwhitelist.sourcerange=8.8.8.8/32
- traefik.http.services.service3.loadbalancer.server.port=80
version: "3.8"
services:
server0:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt-server0.entryPoints: web
traefik.http.routers.rt-server0.rule: Path(`/test`)
traefik.http.services.service1.loadbalancer.server.port: 80
server1:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt-server1.entryPoints: web
traefik.http.routers.rt-server1.rule: Host(`frontend1.docker.local`)
traefik.http.routers.rt-server1.service: service1
traefik.http.services.service1.loadbalancer.server.port: 80
server2:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt-server2.entryPoints: web
traefik.http.routers.rt-server2.rule: Host(`frontend2.docker.local`)
traefik.http.services.service2.loadbalancer.server.port: 80
server3:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt-server3.entryPoints: web
traefik.http.routers.rt-server3.rule: Host(`frontend2.docker.local`)
traefik.http.services.service2.loadbalancer.server.port: 80
authFrontend:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt-authFrontend.entryPoints: httpFrontendAuth
traefik.http.routers.rt-authFrontend.rule: Host(`frontend.auth.docker.local`)
traefik.http.routers.rt-authFrontend.middlewares: basicauth
traefik.http.middlewares.basicauth.basicauth.users: test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/
traefik.http.services.service3.loadbalancer.server.port: 80
digestAuthMiddleware:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt-digestAuthMiddleware.entryPoints: digestAuth
traefik.http.routers.rt-digestAuthMiddleware.rule: Host(`entrypoint.digest.auth.docker.local`)
traefik.http.routers.rt-digestAuthMiddleware.middlewares: digestauth
traefik.http.middlewares.digestauth.digestauth.users: test:traefik:a2688e031edb4be6a3797f3882655c05, test2:traefik:518845800f9e2bfb1f1f740ec24f074e
traefik.http.services.service3.loadbalancer.server.port: 80
frontendRedirect:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt-frontendRedirect.entryPoints: frontendRedirect
traefik.http.routers.rt-frontendRedirect.rule: Path(`/test`)
traefik.http.routers.rt-frontendRedirect.middlewares: redirecthttp
traefik.http.middlewares.redirecthttp.redirectScheme.scheme: http
traefik.http.middlewares.redirecthttp.redirectScheme.port: 8000
traefik.http.services.service3.loadbalancer.server.port: 80
rateLimit:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt-rateLimit.entryPoints: httpRateLimit
traefik.http.routers.rt-rateLimit.rule: Host(`ratelimit.docker.local`)
traefik.http.routers.rt-rateLimit.middlewares: rate
traefik.http.middlewares.rate.ratelimit.average: 1
traefik.http.middlewares.rate.ratelimit.burst: 2
traefik.http.services.service3.loadbalancer.server.port: 80
frontendWhitelist:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt-frontendWhitelist.entryPoints: web
traefik.http.routers.rt-frontendWhitelist.rule: Host(`frontend.whitelist.docker.local`)
traefik.http.routers.rt-frontendWhitelist.middlewares: wl
traefik.http.middlewares.wl.ipwhitelist.sourcerange: 8.8.8.8/32
traefik.http.services.service3.loadbalancer.server.port: 80
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,11 +1,18 @@
whoami1:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.router1.rule=PathPrefix("/whoami")
- traefik.http.routers.router2.rule=PathPrefix("/whoami2")
version: "3.8"
services:
whoami1:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.router1.rule: PathPrefix(`/whoami`)
traefik.http.routers.router2.rule: PathPrefix(`/whoami2`)
whoami2:
image: traefik/whoami
labels:
- traefik.enable=false
whoami2:
image: traefik/whoami
labels:
traefik.enable: false
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,4 +1,9 @@
consul:
image: consul:1.6
ports:
- "8500:8500"
version: "3.8"
services:
consul:
image: consul:1.6
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,32 +1,37 @@
consul:
image: consul:1.6.2
ports:
- 8500:8500
command: "agent -server -bootstrap -ui -client 0.0.0.0 -hcl 'connect { enabled = true }'"
consul-agent:
image: consul:1.6.2
ports:
- 8501:8500
command: "agent -retry-join consul -client 0.0.0.0"
links:
- consul
whoami1:
image: traefik/whoami
hostname: whoami1
whoami2:
image: traefik/whoami
hostname: whoami2
whoami3:
image: traefik/whoami
hostname: whoami3
whoamitcp:
image: traefik/whoamitcp
hostname: whoamitcp
connect:
image: hashicorpnomad/uuid-api:v5
links:
- consul
environment:
PORT: 443
BIND: 0.0.0.0
CONSUL_HTTP_ADDR: http://consul:8500
version: "3.8"
services:
consul:
image: consul:1.6.2
command: agent -server -bootstrap -ui -client 0.0.0.0 -hcl 'connect { enabled = true }'
consul-agent:
image: consul:1.6.2
command: agent -retry-join consul -client 0.0.0.0
whoami1:
image: traefik/whoami
hostname: whoami1
whoami2:
image: traefik/whoami
hostname: whoami2
whoami3:
image: traefik/whoami
hostname: whoami3
whoamitcp:
image: traefik/whoamitcp
hostname: whoamitcp
connect:
image: hashicorpnomad/uuid-api:v5
environment:
PORT: 443
BIND: 0.0.0.0
CONSUL_HTTP_ADDR: http://consul:8500
networks:
default:
name: traefik-test-network
external: true

View File

@@ -0,0 +1,43 @@
version: "3.8"
services:
simple:
image: swarm:1.0.0
command: [ "manage", "token://blablabla" ]
withtcplabels:
image: traefik/whoamitcp
command: [ "-name", "my.super.host" ]
labels:
traefik.tcp.Routers.Super.Rule: HostSNI(`my.super.host`)
traefik.tcp.Routers.Super.tls: true
traefik.tcp.Services.Super.Loadbalancer.server.port: 8080
withlabels1:
image: swarm:1.0.0
command: [ "manage", "token://blabla" ]
labels:
traefik.http.Routers.Super.Rule: Host(`my.super.host`)
withlabels2:
image: swarm:1.0.0
command: [ "manage", "token://blablabla" ]
labels:
traefik.http.Routers.SuperHost.Rule: Host(`my-super.host`)
withonelabelmissing:
image: swarm:1.0.0
command: [ "manage", "token://blabla" ]
labels:
traefik.random.value: my.super.host
powpow:
image: swarm:1.0.0
command: [ "manage", "token://blabla" ]
labels:
traefik.http.Routers.Super.Rule: Host(`my.super.host`)
traefik.http.Services.powpow.LoadBalancer.server.Port: 2375
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,4 +1,12 @@
nginx1:
image: nginx:1.13.8-alpine
nginx2:
image: nginx:1.13.8-alpine
version: "3.8"
services:
nginx1:
image: nginx:1.13.8-alpine
nginx2:
image: nginx:1.13.8-alpine
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,5 +1,10 @@
etcd:
image: quay.io/coreos/etcd:v3.3.18
command: etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://0.0.0.0:2380
ports:
- "2379:2379"
version: "3.8"
services:
etcd:
image: quay.io/coreos/etcd:v3.3.18
command: etcd --listen-client-urls http://0.0.0.0:2379 --advertise-client-urls http://0.0.0.0:2380
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,20 +1,21 @@
whoami1:
image: traefik/whoami
ports:
- "8881:80"
whoami2:
image: traefik/whoami
ports:
- "8882:80"
whoami3:
image: traefik/whoami
ports:
- "8883:80"
whoami4:
image: traefik/whoami
ports:
- "8884:80"
whoami5:
image: traefik/whoami
ports:
- "8885:80"
version: "3.8"
services:
whoami1:
image: traefik/whoami
whoami2:
image: traefik/whoami
whoami3:
image: traefik/whoami
whoami4:
image: traefik/whoami
whoami5:
image: traefik/whoami
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,11 +1,18 @@
whoami1:
image: traefik/whoami
version: "3.8"
services:
whoami1:
image: traefik/whoami
whoami2:
image: traefik/whoami
whoami2:
image: traefik/whoami
whoami3:
image: traefik/whoami
whoami3:
image: traefik/whoami
whoami4:
image: traefik/whoami
whoami4:
image: traefik/whoami
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,6 +1,13 @@
server1:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.services.service1.loadbalancer.server.port=80
- traefik.http.routers.router1.rule=Host("github.com")
version: "3.8"
services:
server1:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.services.service1.loadbalancer.server.port: 80
traefik.http.routers.router1.rule: Host(`github.com`)
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,21 +1,24 @@
server:
image: rancher/k3s:v1.18.20-k3s1
command: server --disable-agent --no-deploy coredns --no-deploy servicelb --no-deploy traefik --no-deploy local-storage --no-deploy metrics-server --log /output/k3s.log
environment:
- K3S_CLUSTER_SECRET=somethingtotallyrandom
- K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml
- K3S_KUBECONFIG_MODE=666
volumes:
- ../../fixtures/k8s/config.skip:/output
- ../../fixtures/k8s:/var/lib/rancher/k3s/server/manifests
ports:
- 6443:6443
version: "3.8"
services:
server:
image: rancher/k3s:v1.18.20-k3s1
command: server --disable-agent --no-deploy coredns --no-deploy servicelb --no-deploy traefik --no-deploy local-storage --no-deploy metrics-server --log /output/k3s.log --bind-address=server --tls-san=server
environment:
K3S_CLUSTER_SECRET: somethingtotallyrandom
K3S_KUBECONFIG_OUTPUT: /output/kubeconfig.yaml
K3S_KUBECONFIG_MODE: 666
volumes:
- ./fixtures/k8s/config.skip:/output
- ./fixtures/k8s:/var/lib/rancher/k3s/server/manifests
node:
image: rancher/k3s:v1.18.20-k3s1
privileged: true
links:
- server
environment:
- K3S_URL=https://server:6443
- K3S_CLUSTER_SECRET=somethingtotallyrandom
node:
image: rancher/k3s:v1.18.20-k3s1
privileged: true
environment:
K3S_URL: https://server:6443
K3S_CLUSTER_SECRET: somethingtotallyrandom
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,54 +1,60 @@
zookeeper:
image: zookeeper:3.4.10
version: "3.8"
services:
zookeeper:
image: zookeeper:3.4.10
mesos-master:
links:
- zookeeper
image: mesosphere/mesos-master:1.0.1-2.0.93.ubuntu1404
# Uncomment published ports for interactive debugging.
# ports:
# - "5050:5050"
environment:
- MESOS_HOSTNAME=mesos-master
- MESOS_CLUSTER=local
- MESOS_REGISTRY=in_memory
- MESOS_LOG_DIR=/var/log
- MESOS_WORK_DIR=/var/lib/mesos
- MESOS_ZK=zk://zookeeper:2181/mesos
mesos-master:
image: mesosphere/mesos-master:1.0.1-2.0.93.ubuntu1404
# Uncomment published ports for interactive debugging.
# ports:
# - "5050:5050"
environment:
MESOS_HOSTNAME: mesos-master
MESOS_CLUSTER: local
MESOS_REGISTRY: in_memory
MESOS_LOG_DIR: /var/log
MESOS_WORK_DIR: /var/lib/mesos
MESOS_ZK: zk://zookeeper:2181/mesos
mesos-slave:
links:
- zookeeper
- mesos-master
image: mesosphere/mesos-slave-dind:0.3.0_mesos-1.0.1_docker-1.10.3_ubuntu-14.04.5
privileged: true
# Uncomment published ports for interactive debugging.
# ports:
# - "5051:5051"
environment:
- MESOS_HOSTNAME=mesos-slave
- MESOS_CONTAINERIZERS=docker,mesos
- MESOS_ISOLATOR=cgroups/cpu,cgroups/mem
- MESOS_LOG_DIR=/var/log
- MESOS_MASTER=zk://zookeeper:2181/mesos
- MESOS_PORT=5051
- MESOS_WORK_DIR=/var/lib/mesos
- MESOS_EXECUTOR_REGISTRATION_TIMEOUT=5mins
- MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD=90secs
- MESOS_DOCKER_STOP_TIMEOUT=60secs
- MESOS_RESOURCES=cpus:2;mem:2048;disk:20480;ports(*):[12000-12999]
mesos-slave:
image: docker:dind
privileged: true
# Uncomment published ports for interactive debugging.
# ports:
# - "5051:5051"
# docker version in mesosphere/mesos-slave-dind:0.3.0_mesos-1.0.1_docker-1.10.3_ubuntu-14.04.5 is too old and can't
# pull images on new kernels.
command:
- "/bin/sh"
- "-c"
- "(/usr/local/bin/dockerd-entrypoint.sh &); sleep 10; set -x; \
docker -H unix:///var/run/docker.sock run -d --net=host --privileged \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /cgroup:/cgroup -v /sys:/sys \
-v /usr/local/bin/docker:/usr/local/bin/docker \
-e MESOS_HOSTNAME=mesos-slave \
-e MESOS_CONTAINERIZERS=docker,mesos \
-e MESOS_ISOLATOR=cgroups/cpu,cgroups/mem \
-e MESOS_LOG_DIR=/var/log \
-e MESOS_MASTER=zk://zookeeper:2181/mesos \
-e MESOS_PORT=5051 \
-e MESOS_WORK_DIR=/var/lib/mesos \
-e MESOS_EXECUTOR_REGISTRATION_TIMEOUT=5mins \
-e MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD=90secs \
-e MESOS_DOCKER_STOP_TIMEOUT=60secs \
-e MESOS_RESOURCES='cpus:2;mem:2048;disk:20480;ports(*):[12000-12999]' \
mesosphere/mesos-slave:1.0.3; sleep 600"
marathon:
links:
- zookeeper
- mesos-master
- mesos-slave
image: mesosphere/marathon:v1.3.12
# Uncomment published ports for interactive debugging.
# ports:
# - "8080:8080"
extra_hosts:
- "mesos-slave:172.17.0.1"
environment:
- MARATHON_ZK=zk://zookeeper:2181/marathon
- MARATHON_MASTER=zk://zookeeper:2181/mesos
marathon:
image: mesosphere/marathon:v1.3.12
# Uncomment published ports for interactive debugging.
# ports:
# - "8080:8080"
environment:
MARATHON_ZK: zk://zookeeper:2181/marathon
MARATHON_MASTER: zk://zookeeper:2181/mesos
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,55 +1,51 @@
zookeeper:
image: zookeeper:3.4.10
version: "3.8"
services:
zookeeper:
image: zookeeper:3.4.10
mesos-master:
links:
- zookeeper
image: mesosphere/mesos-master:1.4.1
# Uncomment published ports for interactive debugging.
# ports:
# - "5050:5050"
environment:
- MESOS_HOSTNAME=mesos-master
- MESOS_CLUSTER=local
- MESOS_REGISTRY=in_memory
- MESOS_LOG_DIR=/var/log
- MESOS_WORK_DIR=/var/lib/mesos
- MESOS_ZK=zk://zookeeper:2181/mesos
mesos-master:
image: mesosphere/mesos-master:1.4.1
# Uncomment published ports for interactive debugging.
# ports:
# - "5050:5050"
environment:
MESOS_HOSTNAME: mesos-master
MESOS_CLUSTER: local
MESOS_REGISTRY: in_memory
MESOS_LOG_DIR: /var/log
MESOS_WORK_DIR: /var/lib/mesos
MESOS_ZK: zk://zookeeper:2181/mesos
mesos-slave:
links:
- zookeeper
- mesos-master
image: mesosphere/mesos-slave-dind:0.4.0_mesos-1.4.1_docker-17.05.0_ubuntu-16.04.3
privileged: true
# Uncomment published ports for interactive debugging.
# ports:
# - "5051:5051"
environment:
- MESOS_HOSTNAME=mesos-slave
- MESOS_CONTAINERIZERS=docker,mesos
- MESOS_ISOLATOR=cgroups/cpu,cgroups/mem
- MESOS_LOG_DIR=/var/log
- MESOS_MASTER=zk://zookeeper:2181/mesos
- MESOS_PORT=5051
- MESOS_WORK_DIR=/var/lib/mesos
- MESOS_EXECUTOR_REGISTRATION_TIMEOUT=5mins
- MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD=90secs
- MESOS_DOCKER_STOP_TIMEOUT=60secs
- MESOS_RESOURCES=cpus:2;mem:2048;disk:20480;ports(*):[12000-12999]
- MESOS_SYSTEMD_ENABLE_SUPPORT=false
mesos-slave:
image: mesosphere/mesos-slave-dind:0.4.0_mesos-1.4.1_docker-17.05.0_ubuntu-16.04.3
privileged: true
# Uncomment published ports for interactive debugging.
# ports:
# - "5051:5051"
environment:
MESOS_HOSTNAME: mesos-slave
MESOS_CONTAINERIZERS: docker,mesos
MESOS_ISOLATOR: cgroups/cpu,cgroups/mem
MESOS_LOG_DIR: /var/log
MESOS_MASTER: zk://zookeeper:2181/mesos
MESOS_PORT: 5051
MESOS_WORK_DIR: /var/lib/mesos
MESOS_EXECUTOR_REGISTRATION_TIMEOUT: 5mins
MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD: 90secs
MESOS_DOCKER_STOP_TIMEOUT: 60secs
MESOS_RESOURCES: cpus:2;mem:2048;disk:20480;ports(*):[12000-12999]
MESOS_SYSTEMD_ENABLE_SUPPORT: false
marathon:
links:
- zookeeper
- mesos-master
- mesos-slave
image: mesosphere/marathon:v1.5.9
# Uncomment published ports for interactive debugging.
# ports:
# - "8080:8080"
extra_hosts:
- "mesos-slave:172.17.0.1"
environment:
- MARATHON_ZK=zk://zookeeper:2181/marathon
- MARATHON_MASTER=zk://zookeeper:2181/mesos
marathon:
image: mesosphere/marathon:v1.5.9
# Uncomment published ports for interactive debugging.
# ports:
# - "8080:8080"
environment:
MARATHON_ZK: zk://zookeeper:2181/marathon
MARATHON_MASTER: zk://zookeeper:2181/mesos
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,6 +1,14 @@
whoami1:
image: traefik/whoami
labels:
- traefik.http.Routers.RouterMini.Rule=PathPrefix("/whoami")
- traefik.enable=true
version: "3.8"
services:
whoami1:
image: traefik/whoami
labels:
traefik.http.Routers.RouterMini.Rule: PathPrefix(`/whoami`)
traefik.enable: true
deploy:
replicas: 2
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,10 +1,15 @@
pebble:
image: letsencrypt/pebble:v2.3.1
command: pebble --dnsserver ${DOCKER_HOST_IP}:5053
ports:
- 14000:14000
environment:
# https://github.com/letsencrypt/pebble#testing-at-full-speed
- PEBBLE_VA_NOSLEEP=1
# https://github.com/letsencrypt/pebble#invalid-anti-replay-nonce-errors
- PEBBLE_WFE_NONCEREJECT=0
version: "3.8"
services:
pebble:
image: letsencrypt/pebble:v2.3.1
command: pebble --dnsserver traefik:5053
environment:
# https://github.com/letsencrypt/pebble#testing-at-full-speed
PEBBLE_VA_NOSLEEP: 1
# https://github.com/letsencrypt/pebble#invalid-anti-replay-nonce-errors
PEBBLE_WFE_NONCEREJECT: 0
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,7 +1,14 @@
haproxy:
image: haproxy:2.2
volumes:
- ../haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
version: "3.8"
services:
haproxy:
image: haproxy:2.2
volumes:
- ./resources/haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
whoami:
image: traefik/whoami
whoami:
image: traefik/whoami
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,2 +1,9 @@
whoami1:
image: traefik/whoami
version: "3.8"
services:
whoami1:
image: traefik/whoami
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,4 +1,9 @@
redis:
image: redis:5.0
ports:
- "6379:6379"
version: "3.8"
services:
redis:
image: redis:5.0
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,2 +1,9 @@
whoami:
image: traefik/whoami
version: "3.8"
services:
whoami:
image: traefik/whoami
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,4 +1,9 @@
whoami1:
image: traefik/whoami
ports:
- "8881:80"
version: "3.8"
services:
whoami1:
image: traefik/whoami
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,2 +1,9 @@
whoami:
image: traefik/whoami
version: "3.8"
services:
whoami:
image: traefik/whoami
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,4 +1,12 @@
whoami1:
image: traefik/whoami
whoami2:
image: traefik/whoami
version: "3.8"
services:
whoami1:
image: traefik/whoami
whoami2:
image: traefik/whoami
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,38 +1,39 @@
whoami-a:
image: traefik/whoamitcp
command: -name whoami-a -certFile /certs/whoami-a.crt -keyFile /certs/whoami-a.key
volumes:
- ../../fixtures/tcp:/certs
ports:
- "8081:8080"
version: "3.8"
services:
whoami-a:
image: traefik/whoamitcp
command: -name whoami-a -certFile /certs/whoami-a.crt -keyFile /certs/whoami-a.key
volumes:
- ./fixtures/tcp:/certs
whoami-b:
image: traefik/whoamitcp
command: -name whoami-b -certFile /certs/whoami-b.crt -keyFile /certs/whoami-b.key
volumes:
- ../../fixtures/tcp:/certs
ports:
- "8082:8080"
whoami-b:
image: traefik/whoamitcp
command: -name whoami-b -certFile /certs/whoami-b.crt -keyFile /certs/whoami-b.key
volumes:
- ./fixtures/tcp:/certs
whoami-no-cert:
image: traefik/whoamitcp
command: -name whoami-no-cert
ports:
- "8083:8080"
whoami-ab:
image: traefik/whoamitcp
command: -name whoami-ab -certFile /certs/whoami-b.crt -keyFile /certs/whoami-b.key
volumes:
- ./fixtures/tcp:/certs
whoami-no-tls:
image: traefik/whoamitcp
command: -name whoami-no-tls
ports:
- "8084:8080"
whoami-no-cert:
image: traefik/whoamitcp
command: -name whoami-no-cert
whoami:
image: traefik/whoami
ports:
- "8085:80"
whoami-no-tls:
image: traefik/whoamitcp
command: -name whoami-no-tls
whoami-banner:
image: traefik/whoamitcp
command: -name whoami-banner --banner
ports:
- "8086:8080"
whoami:
image: traefik/whoami
whoami-banner:
image: traefik/whoamitcp
command: -name whoami-banner --banner
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,7 +1,12 @@
timeoutEndpoint:
image: yaman/timeout
environment:
- PROTO=http
- PORT=9000
ports:
- "9000:9000"
version: "3.8"
services:
timeoutEndpoint:
image: yaman/timeout
environment:
PROTO: http
PORT: 9000
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,7 +1,14 @@
whoami:
version: "3.8"
services:
whoami:
image: traefik/whoami
labels:
- traefik.http.routers.route1.rule=PathPrefix(`/foo`)
- traefik.http.routers.route1.middlewares=passtls
- traefik.http.routers.route1.tls=true
- traefik.http.middlewares.passtls.passtlsclientcert.pem=true
traefik.http.routers.route1.rule: PathPrefix(`/foo`)
traefik.http.routers.route1.middlewares: passtls
traefik.http.routers.route1.tls: true
traefik.http.middlewares.passtls.passtlsclientcert.pem: true
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,21 +1,20 @@
zipkin:
image: openzipkin/zipkin:2.16.2
environment:
STORAGE_TYPE: mem
JAVA_OPTS: -Dlogging.level.zipkin=DEBUG
ports:
- 9411:9411
jaeger:
image: jaegertracing/all-in-one:1.14
environment:
COLLECTOR_ZIPKIN_HTTP_PORT: 9411
ports:
- "5775:5775/udp"
- "6831:6831/udp"
- "6832:6832/udp"
- "5778:5778"
- "16686:16686"
- "14268:14268"
- "9411:9411"
whoami:
image: traefik/whoami
version: "3.8"
services:
zipkin:
image: openzipkin/zipkin:2.16.2
environment:
STORAGE_TYPE: mem
JAVA_OPTS: -Dlogging.level.zipkin=DEBUG
jaeger:
image: jaegertracing/all-in-one:1.14
environment:
COLLECTOR_ZIPKIN_HTTP_PORT: 9411
whoami:
image: traefik/whoami
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,14 +1,21 @@
whoami-a:
image: traefik/whoamiudp:latest
command: -name whoami-a
version: "3.8"
services:
whoami-a:
image: traefik/whoamiudp:latest
command: -name whoami-a
whoami-b:
image: traefik/whoamiudp:latest
command: -name whoami-b
whoami-b:
image: traefik/whoamiudp:latest
command: -name whoami-b
whoami-c:
image: traefik/whoamiudp:latest
command: -name whoami-c
whoami-c:
image: traefik/whoamiudp:latest
command: -name whoami-c
whoami-d:
image: traefik/whoami
whoami-d:
image: traefik/whoami
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,34 +1,41 @@
noOverrideWhitelist:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt1.rule=Host("no.override.whitelist.docker.local")
- traefik.http.routers.rt1.middlewares=wl1
- traefik.http.middlewares.wl1.ipwhiteList.sourceRange=8.8.8.8
version: "3.8"
services:
noOverrideWhitelist:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt1.rule: Host(`no.override.whitelist.docker.local`)
traefik.http.routers.rt1.middlewares: wl1
traefik.http.middlewares.wl1.ipwhiteList.sourceRange: 8.8.8.8
overrideIPStrategyRemoteAddrWhitelist:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt2.rule=Host("override.remoteaddr.whitelist.docker.local")
- traefik.http.routers.rt2.middlewares=wl2
- traefik.http.middlewares.wl2.ipwhitelist.sourceRange=8.8.8.8
- traefik.http.middlewares.wl2.ipwhitelist.ipStrategy=true
overrideIPStrategyRemoteAddrWhitelist:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt2.rule: Host(`override.remoteaddr.whitelist.docker.local`)
traefik.http.routers.rt2.middlewares: wl2
traefik.http.middlewares.wl2.ipwhitelist.sourceRange: 8.8.8.8
traefik.http.middlewares.wl2.ipwhitelist.ipStrategy: true
overrideIPStrategyDepthWhitelist:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt3.rule=Host("override.depth.whitelist.docker.local")
- traefik.http.routers.rt3.middlewares=wl3
- traefik.http.middlewares.wl3.ipwhitelist.sourceRange=8.8.8.8
- traefik.http.middlewares.wl3.ipwhitelist.ipStrategy.depth=3
overrideIPStrategyDepthWhitelist:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt3.rule: Host(`override.depth.whitelist.docker.local`)
traefik.http.routers.rt3.middlewares: wl3
traefik.http.middlewares.wl3.ipwhitelist.sourceRange: 8.8.8.8
traefik.http.middlewares.wl3.ipwhitelist.ipStrategy.depth: 3
overrideIPStrategyExcludedIPsWhitelist:
image: traefik/whoami
labels:
- traefik.enable=true
- traefik.http.routers.rt4.rule=Host("override.excludedips.whitelist.docker.local")
- traefik.http.routers.rt4.middlewares=wl4
- traefik.http.middlewares.wl4.ipwhitelist.sourceRange=8.8.8.8
- traefik.http.middlewares.wl4.ipwhitelist.ipStrategy.excludedIPs=10.0.0.1,10.0.0.2
overrideIPStrategyExcludedIPsWhitelist:
image: traefik/whoami
labels:
traefik.enable: true
traefik.http.routers.rt4.rule: Host(`override.excludedips.whitelist.docker.local`)
traefik.http.routers.rt4.middlewares: wl4
traefik.http.middlewares.wl4.ipwhitelist.sourceRange: 8.8.8.8
traefik.http.middlewares.wl4.ipwhitelist.ipStrategy.excludedIPs: 10.0.0.1,10.0.0.2
networks:
default:
name: traefik-test-network
external: true

View File

@@ -1,4 +1,9 @@
zookeeper:
image: zookeeper:3.5
ports:
- "2181:2181"
version: "3.8"
services:
zookeeper:
image: zookeeper:3.5
networks:
default:
name: traefik-test-network
external: true

View File

@@ -23,8 +23,8 @@ frontend TestServerTestV2
backend TestServerNodes
mode tcp
server TestServer01 172.17.0.1:8000 send-proxy
server TestServer01 traefik:8000 send-proxy
backend TestServerNodesV2
mode tcp
server TestServer01 172.17.0.1:8000 send-proxy-v2
server TestServer01 traefik:8000 send-proxy-v2

View File

@@ -3,6 +3,7 @@ package integration
import (
"bytes"
"encoding/json"
"net"
"net/http"
"os"
"strings"
@@ -14,12 +15,16 @@ import (
checker "github.com/vdemeester/shakers"
)
type RestSuite struct{ BaseSuite }
type RestSuite struct {
BaseSuite
whoamiAddr string
}
func (s *RestSuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "rest")
s.composeUp(c)
s.composeProject.Start(c)
s.whoamiAddr = net.JoinHostPort(s.getComposeServiceIP(c, "whoami1"), "80")
}
func (s *RestSuite) TestSimpleConfigurationInsecure(c *check.C) {
@@ -60,7 +65,7 @@ func (s *RestSuite) TestSimpleConfigurationInsecure(c *check.C) {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://" + s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress + ":80",
URL: "http://" + s.whoamiAddr,
},
},
},
@@ -86,7 +91,7 @@ func (s *RestSuite) TestSimpleConfigurationInsecure(c *check.C) {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress + ":80",
Address: s.whoamiAddr,
},
},
},
@@ -164,7 +169,7 @@ func (s *RestSuite) TestSimpleConfiguration(c *check.C) {
LoadBalancer: &dynamic.ServersLoadBalancer{
Servers: []dynamic.Server{
{
URL: "http://" + s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress + ":80",
URL: "http://" + s.whoamiAddr,
},
},
},
@@ -190,7 +195,7 @@ func (s *RestSuite) TestSimpleConfiguration(c *check.C) {
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress + ":80",
Address: s.whoamiAddr,
},
},
},
@@ -213,10 +218,10 @@ func (s *RestSuite) TestSimpleConfiguration(c *check.C) {
c.Assert(err, checker.IsNil)
c.Assert(response.StatusCode, checker.Equals, http.StatusOK)
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1000*time.Millisecond, try.BodyContains(test.ruleMatch))
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains(test.ruleMatch))
c.Assert(err, checker.IsNil)
err = try.GetRequest("http://127.0.0.1:8000/", 1000*time.Millisecond, try.StatusCodeIs(http.StatusOK))
err = try.GetRequest("http://127.0.0.1:8000/", time.Second, try.StatusCodeIs(http.StatusOK))
c.Assert(err, checker.IsNil)
}
}

View File

@@ -11,18 +11,20 @@ import (
checker "github.com/vdemeester/shakers"
)
type RetrySuite struct{ BaseSuite }
type RetrySuite struct {
BaseSuite
whoamiIP string
}
func (s *RetrySuite) SetUpSuite(c *check.C) {
s.createComposeProject(c, "retry")
s.composeProject.Start(c)
s.composeUp(c)
s.whoamiIP = s.getComposeServiceIP(c, "whoami")
}
func (s *RetrySuite) TestRetry(c *check.C) {
whoamiEndpoint := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress
file := s.adaptFile(c, "fixtures/retry/simple.toml", struct {
WhoamiEndpoint string
}{whoamiEndpoint})
file := s.adaptFile(c, "fixtures/retry/simple.toml", struct{ WhoamiIP string }{s.whoamiIP})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
@@ -44,10 +46,7 @@ func (s *RetrySuite) TestRetry(c *check.C) {
}
func (s *RetrySuite) TestRetryBackoff(c *check.C) {
whoamiEndpoint := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress
file := s.adaptFile(c, "fixtures/retry/backoff.toml", struct {
WhoamiEndpoint string
}{whoamiEndpoint})
file := s.adaptFile(c, "fixtures/retry/backoff.toml", struct{ WhoamiIP string }{s.whoamiIP})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))
@@ -72,10 +71,7 @@ func (s *RetrySuite) TestRetryBackoff(c *check.C) {
}
func (s *RetrySuite) TestRetryWebsocket(c *check.C) {
whoamiEndpoint := s.composeProject.Container(c, "whoami").NetworkSettings.IPAddress
file := s.adaptFile(c, "fixtures/retry/simple.toml", struct {
WhoamiEndpoint string
}{whoamiEndpoint})
file := s.adaptFile(c, "fixtures/retry/simple.toml", struct{ WhoamiIP string }{s.whoamiIP})
defer os.Remove(file)
cmd, display := s.traefikCmd(withConfigFile(file))

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