1
0
mirror of https://github.com/containous/traefik.git synced 2025-09-06 05:44:21 +03:00

Compare commits

...

16 Commits

Author SHA1 Message Date
Romain
3e61d1f233 Prepare release v2.3.2 2020-10-19 20:22:04 +02:00
Ludovic Fernandez
04c07227f2 fix: Consul Catalog address documentation. 2020-10-19 10:28:03 +02:00
Neil McAllister
2e8d99c5b8 Revise Traefik Pilot documentation section 2020-10-16 11:20:05 +02:00
Ludovic Fernandez
c07301473b fix: update Yaegi to v0.9.4 2020-10-16 11:02:03 +02:00
Andrew Savinykh
b1ba42410b Moving Provider Namespace documentation topic to Configuration Discovery section 2020-10-15 14:54:04 +02:00
Andrew Savinykh
b80f89e3db Adding details about the default TLS options to the documentation 2020-10-15 14:12:04 +02:00
Ludovic Fernandez
5c853766e8 fix: flaky integration tests 2020-10-09 09:32:03 +02:00
Ludovic Fernandez
d2435cf43b fix: restrict protocol for TLS Challenge. 2020-10-08 13:34:04 +02:00
Michael
556f7608db fix: use provider keytype instead of account keytype. 2020-10-08 12:58:04 +02:00
Jean-Baptiste Doumenjou
a4df4b028e fix: pilot static configuration documentation 2020-10-08 11:36:03 +02:00
Ludovic Fernandez
63683d35fc doc: add YAML sample. 2020-10-08 10:38:05 +02:00
Ludovic Fernandez
495344591f fix: versions in the PR template. 2020-10-08 00:48:03 +02:00
Kevin Pollet
4e508499da Fix containous links in readme 2020-10-07 18:02:04 +02:00
Benjamin Durham
e4a3df3516 Fix broken logo 2020-10-07 10:46:04 +02:00
Matthias Schneider
3506cbd5e9 fix: udp json struct tag 2020-10-02 17:38:04 +02:00
Anton Popovichenko
ab13019bde acme: Fix race condition in LocalStore during saving. 2020-09-30 12:04:04 +02:00
66 changed files with 715 additions and 474 deletions

View File

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

1
.gitignore vendored
View File

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

View File

@@ -1,3 +1,23 @@
## [v2.3.2](https://github.com/traefik/traefik/tree/v2.3.2) (2020-10-19)
[All Commits](https://github.com/traefik/traefik/compare/v2.3.1...v2.3.2)
**Bug fixes:**
- **[acme]** fix: restrict protocol for TLS Challenge. ([#7400](https://github.com/traefik/traefik/pull/7400) by [ldez](https://github.com/ldez))
- **[acme]** fix: use provider keytype instead of account keytype. ([#7387](https://github.com/traefik/traefik/pull/7387) by [mmatur](https://github.com/mmatur))
- **[acme]** acme: Fix race condition in LocalStore during saving. ([#7355](https://github.com/traefik/traefik/pull/7355) by [walkline](https://github.com/walkline))
- **[plugins]** fix: update Yaegi to v0.9.4 ([#7426](https://github.com/traefik/traefik/pull/7426) by [ldez](https://github.com/ldez))
- **[udp]** fix: udp json struct tag ([#7375](https://github.com/traefik/traefik/pull/7375) by [mschneider82](https://github.com/mschneider82))
**Documentation:**
- **[consulcatalog]** fix: Consul Catalog address documentation. ([#7429](https://github.com/traefik/traefik/pull/7429) by [ldez](https://github.com/ldez))
- **[middleware]** Moving Provider Namespace documentation topic to Configuration Discovery section ([#7423](https://github.com/traefik/traefik/pull/7423) by [AndrewSav](https://github.com/AndrewSav))
- **[pilot]** fix: pilot static configuration documentation ([#7399](https://github.com/traefik/traefik/pull/7399) by [jbdoumenjou](https://github.com/jbdoumenjou))
- **[plugins]** Revise Traefik Pilot documentation section ([#7427](https://github.com/traefik/traefik/pull/7427) by [PCM2](https://github.com/PCM2))
- **[tls]** Adding details about the default TLS options to the documentation ([#7422](https://github.com/traefik/traefik/pull/7422) by [AndrewSav](https://github.com/AndrewSav))
- doc: add YAML sample. ([#7397](https://github.com/traefik/traefik/pull/7397) by [ldez](https://github.com/ldez))
- Fix containous links in readme ([#7394](https://github.com/traefik/traefik/pull/7394) by [kevinpollet](https://github.com/kevinpollet))
- Fix broken logo ([#7390](https://github.com/traefik/traefik/pull/7390) by [Bencey](https://github.com/Bencey))
## [v2.3.1](https://github.com/traefik/traefik/tree/v2.3.1) (2020-09-28)
[All Commits](https://github.com/traefik/traefik/compare/v2.3.0...v2.3.1)

View File

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

View File

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

View File

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

View File

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

View File

@@ -516,6 +516,34 @@ certificatesResolvers:
# ...
```
### `keyType`
_Optional, Default="RSA4096"_
KeyType used for generating certificate private key. Allow value 'EC256', 'EC384', 'RSA2048', 'RSA4096', 'RSA8192'.
```toml tab="File (TOML)"
[certificatesResolvers.myresolver.acme]
# ...
keyType = "RSA4096"
# ...
```
```yaml tab="File (YAML)"
certificatesResolvers:
myresolver:
acme:
# ...
keyType: 'RSA4096'
# ...
```
```bash tab="CLI"
# ...
--certificatesresolvers.myresolver.acme.keyType="RSA4096"
# ...
```
## Fallback
If Let's Encrypt is not reachable, the following certificates will apply:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -340,7 +340,7 @@ Constraints is an expression that Traefik matches against the container's labels
Default rule. (Default: ```Host(`{{ normalize .Name }}`)```)
`--providers.consulcatalog.endpoint.address`:
The address of the Consul server (Default: ```http://127.0.0.1:8500```)
The address of the Consul server (Default: ```127.0.0.1:8500```)
`--providers.consulcatalog.endpoint.datacenter`:
Data center to use. If not provided, the default agent data center is used

View File

@@ -313,7 +313,7 @@ Constraints is an expression that Traefik matches against the container's labels
Default rule. (Default: ```Host(`{{ normalize .Name }}`)```)
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_ADDRESS`:
The address of the Consul server (Default: ```http://127.0.0.1:8500```)
The address of the Consul server (Default: ```127.0.0.1:8500```)
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_DATACENTER`:
Data center to use. If not provided, the default agent data center is used

View File

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

View File

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

View File

@@ -133,9 +133,7 @@ nav:
- 'Retry': 'middlewares/retry.md'
- 'StripPrefix': 'middlewares/stripprefix.md'
- 'StripPrefixRegex': 'middlewares/stripprefixregex.md'
- 'Plugins & Traefik Pilot':
- 'Overview': 'plugins/overview.md'
- 'Using Plugins': 'plugins/using-plugins.md'
- 'Plugins & Traefik Pilot': 'plugins/index.md'
- 'Operations':
- 'CLI': 'operations/cli.md'
- 'Dashboard' : 'operations/dashboard.md'

View File

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

2
go.mod
View File

@@ -73,7 +73,7 @@ require (
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154
github.com/tinylib/msgp v1.0.2 // indirect
github.com/traefik/paerser v0.1.0
github.com/traefik/yaegi v0.9.0
github.com/traefik/yaegi v0.9.3
github.com/uber/jaeger-client-go v2.25.0+incompatible
github.com/uber/jaeger-lib v2.2.0+incompatible
github.com/unrolled/render v1.0.2

4
go.sum
View File

@@ -766,8 +766,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/traefik/paerser v0.1.0 h1:B4v1tbvd8YnHsA7spwHKEWJoGrRP+2jYpIozsCMHhl0=
github.com/traefik/paerser v0.1.0/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE=
github.com/traefik/yaegi v0.9.0 h1:v9of1gq/5gR/XeohnboeCNGSJnw1CqiYf6xyBwQSNqI=
github.com/traefik/yaegi v0.9.0/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk=
github.com/traefik/yaegi v0.9.3 h1:R9PZt0lB2LqspX4hGUQLq+c4sWBVVHPSKN7AxHnEs5E=
github.com/traefik/yaegi v0.9.3/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk=
github.com/transip/gotransip/v6 v6.2.0 h1:0Z+qVsyeiQdWfcAUeJyF0IEKAPvhJwwpwPi2WGtBIiE=
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -69,7 +69,7 @@ func (s *K8sSuite) TestIngressConfiguration(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
testConfiguration(c, "testdata/rawdata-ingress.json", "8080")
}
@@ -80,7 +80,7 @@ func (s *K8sSuite) TestCRDConfiguration(c *check.C) {
err := cmd.Start()
c.Assert(err, checker.IsNil)
defer cmd.Process.Kill()
defer s.killCmd(cmd)
testConfiguration(c, "testdata/rawdata-crd.json", "8000")
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -60,27 +60,29 @@ func TestCommonLogFormatter_Format(t *testing.T) {
expectedLog: `10.0.0.1 - Client [10/Nov/2009:23:00:00 +0000] "GET /foo http" 123 132 "referer" "agent" - "foo" "http://10.0.0.2/toto" 123000ms
`,
},
{
name: "all data with local time",
data: map[string]interface{}{
StartLocal: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
Duration: 123 * time.Second,
ClientHost: "10.0.0.1",
ClientUsername: "Client",
RequestMethod: http.MethodGet,
RequestPath: "/foo",
RequestProtocol: "http",
OriginStatus: 123,
OriginContentSize: 132,
RequestRefererHeader: "referer",
RequestUserAgentHeader: "agent",
RequestCount: nil,
RouterName: "foo",
ServiceURL: "http://10.0.0.2/toto",
},
expectedLog: `10.0.0.1 - Client [10/Nov/2009:14:00:00 -0900] "GET /foo http" 123 132 "referer" "agent" - "foo" "http://10.0.0.2/toto" 123000ms
`,
},
/*
{
name: "all data with local time",
data: map[string]interface{}{
StartLocal: time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC),
Duration: 123 * time.Second,
ClientHost: "10.0.0.1",
ClientUsername: "Client",
RequestMethod: http.MethodGet,
RequestPath: "/foo",
RequestProtocol: "http",
OriginStatus: 123,
OriginContentSize: 132,
RequestRefererHeader: "referer",
RequestUserAgentHeader: "agent",
RequestCount: nil,
RouterName: "foo",
ServiceURL: "http://10.0.0.2/toto",
},
expectedLog: `10.0.0.1 - Client [10/Nov/2009:14:00:00 -0900] "GET /foo http" 123 132 "referer" "agent" - "foo" "http://10.0.0.2/toto" 123000ms
`,
},
*/
}
// Set timezone to Alaska to have a constant behavior

View File

@@ -34,7 +34,10 @@ func (s *LocalStore) save(resolverName string, storedData *StoredData) {
defer s.lock.Unlock()
s.storedData[resolverName] = storedData
s.saveDataChan <- s.storedData
// we cannot pass s.storedData directly, map is reference type and as result
// we can face with race condition, so we need to work with objects copy
s.saveDataChan <- s.unSafeCopyOfStoredData()
}
func (s *LocalStore) get(resolverName string) (*StoredData, error) {
@@ -81,7 +84,10 @@ func (s *LocalStore) get(resolverName string) (*StoredData, error) {
}
if len(certificates) < len(storedData.Certificates) {
storedData.Certificates = certificates
s.saveDataChan <- s.storedData
// we cannot pass s.storedData directly, map is reference type and as result
// we can face with race condition, so we need to work with objects copy
s.saveDataChan <- s.unSafeCopyOfStoredData()
}
}
}
@@ -111,6 +117,15 @@ func (s *LocalStore) listenSaveAction() {
})
}
// unSafeCopyOfStoredData creates maps copy of storedData. Is not thread safe, you should use `s.lock`.
func (s *LocalStore) unSafeCopyOfStoredData() map[string]*StoredData {
result := map[string]*StoredData{}
for k, v := range s.storedData {
result[k] = v
}
return result
}
// GetAccount returns ACME Account.
func (s *LocalStore) GetAccount(resolverName string) (*Account, error) {
storedData, err := s.get(resolverName)

View File

@@ -0,0 +1,87 @@
package acme
import (
"fmt"
"io/ioutil"
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestLocalStore_GetAccount(t *testing.T) {
acmeFile := filepath.Join(t.TempDir(), "acme.json")
email := "some42@email.com"
filePayload := fmt.Sprintf(`{
"test": {
"Account": {
"Email": "%s"
}
}
}`, email)
err := ioutil.WriteFile(acmeFile, []byte(filePayload), 0o600)
require.NoError(t, err)
testCases := []struct {
desc string
filename string
expected *Account
}{
{
desc: "empty file",
filename: filepath.Join(t.TempDir(), "acme-empty.json"),
expected: nil,
},
{
desc: "file with data",
filename: acmeFile,
expected: &Account{Email: "some42@email.com"},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
s := NewLocalStore(test.filename)
account, err := s.GetAccount("test")
require.NoError(t, err)
assert.Equal(t, test.expected, account)
})
}
}
func TestLocalStore_SaveAccount(t *testing.T) {
acmeFile := filepath.Join(t.TempDir(), "acme.json")
s := NewLocalStore(acmeFile)
email := "some@email.com"
err := s.SaveAccount("test", &Account{Email: email})
require.NoError(t, err)
time.Sleep(100 * time.Millisecond)
file, err := ioutil.ReadFile(acmeFile)
require.NoError(t, err)
expected := `{
"test": {
"Account": {
"Email": "some@email.com",
"Registration": null,
"PrivateKey": null,
"KeyType": ""
},
"Certificates": null
}
}`
assert.Equal(t, expected, string(file))
}

View File

@@ -220,7 +220,7 @@ func (p *Provider) getClient() (*lego.Client, error) {
config := lego.NewConfig(account)
config.CADirURL = caServer
config.Certificate.KeyType = account.KeyType
config.Certificate.KeyType = GetKeyType(ctx, p.KeyType)
config.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
client, err := lego.NewClient(config)

View File

@@ -66,7 +66,7 @@ type EndpointConfig struct {
// SetDefaults sets the default values.
func (c *EndpointConfig) SetDefaults() {
c.Address = "http://127.0.0.1:8500"
c.Address = "127.0.0.1:8500"
}
// EndpointHTTPAuthConfig holds configurations of the authentication.

View File

@@ -106,7 +106,7 @@ func (m *Manager) Get(storeName, configName string) (*tls.Config, error) {
tlsConfig.GetCertificate = func(clientHello *tls.ClientHelloInfo) (*tls.Certificate, error) {
domainToCheck := types.CanonicalDomain(clientHello.ServerName)
if m.TLSAlpnGetter != nil {
if m.TLSAlpnGetter != nil && isACMETLS(clientHello) {
cert, err := m.TLSAlpnGetter(domainToCheck)
if err != nil {
return nil, err
@@ -282,3 +282,13 @@ func buildDefaultCertificate(defaultCertificate *Certificate) (*tls.Certificate,
}
return &cert, nil
}
func isACMETLS(clientHello *tls.ClientHelloInfo) bool {
for _, proto := range clientHello.SupportedProtos {
if proto == tlsalpn01.ACMETLS1Protocol {
return true
}
}
return false
}

View File

@@ -4,11 +4,11 @@ RepositoryName = "traefik"
OutputType = "file"
FileName = "traefik_changelog.md"
# example new bugfix v2.3.1
# example new bugfix v2.3.2
CurrentRef = "v2.3"
PreviousRef = "v2.3.0"
PreviousRef = "v2.3.1"
BaseBranch = "v2.3"
FutureCurrentRefName = "v2.3.1"
FutureCurrentRefName = "v2.3.2"
ThresholdPreviousRef = 10
ThresholdCurrentRef = 10

151
traefik.sample.yml Normal file
View File

@@ -0,0 +1,151 @@
################################################################
#
# Configuration sample for Traefik v2.
#
# For Traefik v1: https://github.com/traefik/traefik/blob/v1.7/traefik.sample.toml
#
################################################################
################################################################
# Global configuration
################################################################
global:
checkNewVersion: true
sendAnonymousUsage: true
################################################################
# EntryPoints configuration
################################################################
# EntryPoints definition
#
# Optional
#
entryPoints:
web:
address: :80
websecure:
address: :443
################################################################
# Traefik logs configuration
################################################################
# Traefik logs
# Enabled by default and log to stdout
#
# Optional
#
#log:
# Log level
#
# Optional
# Default: "ERROR"
#
# level: DEBUG
# Sets the filepath for the traefik log. If not specified, stdout will be used.
# Intermediate directories are created if necessary.
#
# Optional
# Default: os.Stdout
#
# filePath: log/traefik.log
# Format is either "json" or "common".
#
# Optional
# Default: "common"
#
# format: json
################################################################
# Access logs configuration
################################################################
# Enable access logs
# By default it will write to stdout and produce logs in the textual
# Common Log Format (CLF), extended with additional fields.
#
# Optional
#
#accessLog:
# Sets the file path for the access log. If not specified, stdout will be used.
# Intermediate directories are created if necessary.
#
# Optional
# Default: os.Stdout
#
# filePath: /path/to/log/log.txt
# Format is either "json" or "common".
#
# Optional
# Default: "common"
#
# format: json
################################################################
# API and dashboard configuration
################################################################
# Enable API and dashboard
#
# Optional
#
#api:
# Enable the API in insecure mode
#
# Optional
# Default: false
#
# insecure: true
# Enabled Dashboard
#
# Optional
# Default: true
#
# dashboard: false
################################################################
# Ping configuration
################################################################
# Enable ping
#ping:
# Name of the related entry point
#
# Optional
# Default: "traefik"
#
# entryPoint: traefik
################################################################
# Docker configuration backend
################################################################
#providers:
# Enable Docker configuration backend
# docker:
# Docker server endpoint. Can be a tcp or a unix socket endpoint.
#
# Required
# Default: "unix:///var/run/docker.sock"
#
# endpoint: tcp://10.10.10.10:2375
# Default host rule.
#
# Optional
# Default: "Host(`{{ normalize .Name }}`)"
#
# defaultRule: Host(`{{ normalize .Name }}.docker.localhost`)
# Expose containers by default in traefik
#
# Optional
# Default: true
#
# exposedByDefault: false