diff --git a/docs/index.md b/docs/index.md
index 188104170..6ab689904 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -2,25 +2,25 @@
-# Documentation
+# Documentation
- [Basics](#basics)
-- [Launch configuration](#launch)
-- [Global configuration](#global)
-- [File backend](#file)
-- [API backend](#api)
-- [Docker backend](#docker)
-- [Mesos/Marathon backend](#marathon)
-- [Consul backend](#consul)
-- [Consul catalog backend](#consulcatalog)
-- [Etcd backend](#etcd)
-- [Zookeeper backend](#zk)
-- [Boltdb backend](#boltdb)
-- [Atomic configuration changes](#atomicconfig)
+- [Launch configuration](#launch-configuration)
+- [Global configuration](#global-configuration)
+- [File backend](#file-backend)
+- [API backend](#api-backend)
+- [Docker backend](#docker-backend)
+- [Mesos/Marathon backend](#marathon-backend)
+- [Consul backend](#consul-backend)
+- [Consul catalog backend](#consul-catalog-backend)
+- [Etcd backend](#etcd-backend)
+- [Zookeeper backend](#zookeeper-backend)
+- [Boltdb backend](#boltdb-backend)
+- [Atomic configuration changes](#atomic-configuration-changes)
- [Benchmarks](#benchmarks)
-## Basics
+## Basics
Træfɪk is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease.
@@ -28,12 +28,12 @@ It supports several backends ([Docker :whale:](https://www.docker.com/), [Mesos/
Basically, Træfɪk is a http router, which sends traffic from frontends to http backends, following rules you have configured.
-### Frontends
+### Frontends
Frontends can be defined using the following rules:
-- `Headers`: Headers adds a matcher for request header values. It accepts a sequence of key/value pairs to be matched. For example: `application/json`
-- `HeadersRegexp`: Regular expressions can be used with headers as well. It accepts a sequence of key/value pairs, where the value has regex support. For example: `application/(text|json)`
+- `Headers`: Headers adds a matcher for request header values. It accepts a sequence of key/value pairs to be matched. For example: `Content-Type, application/json`
+- `HeadersRegexp`: Regular expressions can be used with headers as well. It accepts a sequence of key/value pairs, where the value has regex support. For example: `Content-Type, application/(text|json)`
- `Host`: Host adds a matcher for the URL host. It accepts a template with zero or more URL variables enclosed by `{}`. Variables can define an optional regexp pattern to be matched: `www.traefik.io`, `{subdomain:[a-z]+}.traefik.io`
- `Methods`: Methods adds a matcher for HTTP methods. It accepts a sequence of one or more methods to be matched, e.g.: `GET`, `POST`, `PUT`
- `Path`: Path adds a matcher for the URL path. It accepts a template with zero or more URL variables enclosed by `{}`. The template must start with a `/`. For exemple `/products/` `/articles/{category}/{id:[0-9]+}`
@@ -70,7 +70,7 @@ For example:
- `ResponseCodeRatio(500, 600, 0, 600) > 0.5`: ratio of response codes in range [500-600) to [0-600)
-## Launch configuration
+## Launch configuration
Træfɪk can be configured using a TOML file configuration, arguments, or both.
By default, Træfɪk will try to find a `traefik.toml` in the following places:
@@ -176,7 +176,7 @@ Flags:
Use "traefik [command] --help" for more information about a command.
```
-## Global configuration
+## Global configuration
```toml
# traefik.toml
@@ -432,24 +432,21 @@ entryPoint = "https"
[frontends.frontend1]
backend = "backend2"
[frontends.frontend1.routes.test_1]
- rule = "Host"
- value = "test.localhost"
+ rule = "Host:test.localhost"
[frontends.frontend2]
backend = "backend1"
passHostHeader = true
entrypoints = ["https"] # overrides defaultEntryPoints
[frontends.frontend2.routes.test_1]
- rule = "Host"
- value = "{subdomain:[a-z]+}.localhost"
+ rule = "Host:{subdomain:[a-z]+}.localhost"
[frontends.frontend3]
entrypoints = ["http", "https"] # overrides defaultEntryPoints
backend = "backend2"
- rule = "Path"
- value = "/test"
+ rule = "Path:/test"
```
-## File backend
+## File backend
Like any other reverse proxy, Træfɪk can be configured with a file. You have two choices:
@@ -502,20 +499,17 @@ logLevel = "DEBUG"
[frontends.frontend1]
backend = "backend2"
[frontends.frontend1.routes.test_1]
- rule = "Host"
- value = "test.localhost"
+ rule = "Host:test.localhost"
[frontends.frontend2]
backend = "backend1"
passHostHeader = true
entrypoints = ["https"] # overrides defaultEntryPoints
[frontends.frontend2.routes.test_1]
- rule = "Host"
- value = "{subdomain:[a-z]+}.localhost"
+ rule = "Host:{subdomain:[a-z]+}.localhost"
[frontends.frontend3]
entrypoints = ["http", "https"] # overrides defaultEntryPoints
backend = "backend2"
- rule = "Path"
- value = "/test"
+ rule = "Path:/test"
```
- or put your rules in a separate file, for example `rules.tml`:
@@ -569,20 +563,17 @@ filename = "rules.toml"
[frontends.frontend1]
backend = "backend2"
[frontends.frontend1.routes.test_1]
- rule = "Host"
- value = "test.localhost"
+ rule = "Host:test.localhost"
[frontends.frontend2]
backend = "backend1"
passHostHeader = true
entrypoints = ["https"] # overrides defaultEntryPoints
[frontends.frontend2.routes.test_1]
- rule = "Host"
- value = "{subdomain:[a-z]+}.localhost"
+ rule = "Host:{subdomain:[a-z]+}.localhost"
[frontends.frontend3]
entrypoints = ["http", "https"] # overrides defaultEntryPoints
backend = "backend2"
- rule = "Path"
- value = "/test"
+ rule = "Path:/test"
```
If you want Træfɪk to watch file changes automatically, just add:
@@ -592,7 +583,7 @@ If you want Træfɪk to watch file changes automatically, just add:
watch = true
```
-## API backend
+## API backend
Træfik can be configured using a restful api.
To enable it:
@@ -669,8 +660,7 @@ $ curl -s "http://localhost:8080/api" | jq .
"frontend2": {
"routes": {
"test_2": {
- "value": "/test",
- "rule": "Path"
+ "rule": "Path:/test"
}
},
"backend": "backend1"
@@ -678,8 +668,7 @@ $ curl -s "http://localhost:8080/api" | jq .
"frontend1": {
"routes": {
"test_1": {
- "value": "test.localhost",
- "rule": "Host"
+ "rule": "Host:test.localhost"
}
},
"backend": "backend2"
@@ -736,7 +725,7 @@ $ curl -s "http://localhost:8080/api" | jq .
- `/api/providers/{provider}/frontends/{frontend}/routes/{route}`: `GET` a route in a frontend
-## Docker backend
+## Docker backend
Træfɪk can be configured to use Docker as a backend configuration:
@@ -792,14 +781,13 @@ Labels can be used on containers to override default behaviour:
- `traefik.protocol=https`: override the default `http` protocol
- `traefik.weight=10`: assign this weight to the container
- `traefik.enable=false`: disable this container in Træfɪk
-- `traefik.frontend.rule=Host`: override the default frontend rule (Default: Host). See [frontends](#frontends).
-- `traefik.frontend.value=test.example.com`: override the default frontend value (Default: `{containerName}.{domain}`) See [frontends](#frontends). Must be associated with label traefik.frontend.rule.
+- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). See [frontends](#frontends).
- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend.
- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`.
* `traefik.domain=traefik.localhost`: override the default domain
-## Marathon backend
+## Marathon backend
Træfɪk can be configured to use Marathon as a backend configuration:
@@ -873,13 +861,12 @@ Labels can be used on containers to override default behaviour:
- `traefik.protocol=https`: override the default `http` protocol
- `traefik.weight=10`: assign this weight to the application
- `traefik.enable=false`: disable this application in Træfɪk
-- `traefik.frontend.rule=Host`: override the default frontend rule (Default: Host). See [frontends](#frontends).
-- `traefik.frontend.value=test.example.com`: override the default frontend value (Default: `{appName}.{domain}`) See [frontends](#frontends). Must be associated with label traefik.frontend.rule.
+- `traefik.frontend.rule=Host:test.traefik.io`: override the default frontend rule (Default: `Host:{containerName}.{domain}`). See [frontends](#frontends).
- `traefik.frontend.passHostHeader=true`: forward client `Host` header to the backend.
- `traefik.frontend.entryPoints=http,https`: assign this frontend to entry points `http` and `https`. Overrides `defaultEntryPoints`.
* `traefik.domain=traefik.localhost`: override the default domain
-## Consul backend
+## Consul backend
Træfɪk can be configured to use Consul as a backend configuration:
@@ -929,48 +916,41 @@ prefix = "traefik"
# insecureskipverify = true
```
-The Keys-Values structure should look (using `prefix = "/traefik"`):
+Please refer to the [Key Value storage structure](#key-value-storage-structure) section to get documentation en traefik KV structure.
-- backend 1
+## Consul catalog backend
-| Key | Value |
-|--------------------------------------------------------|-----------------------------|
-| `/traefik/backends/backend1/circuitbreaker/expression` | `NetworkErrorRatio() > 0.5` |
-| `/traefik/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
-| `/traefik/backends/backend1/servers/server1/weight` | `10` |
-| `/traefik/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
-| `/traefik/backends/backend1/servers/server2/weight` | `1` |
+Træfɪk can be configured to use service discovery catalog of Consul as a backend configuration:
-- backend 2
+```toml
+################################################################
+# Consul Catalog configuration backend
+################################################################
-| Key | Value |
-|-----------------------------------------------------|------------------------|
-| `/traefik/backends/backend2/loadbalancer/method` | `drr` |
-| `/traefik/backends/backend2/servers/server1/url` | `http://172.17.0.4:80` |
-| `/traefik/backends/backend2/servers/server1/weight` | `1` |
-| `/traefik/backends/backend2/servers/server2/url` | `http://172.17.0.5:80` |
-| `/traefik/backends/backend2/servers/server2/weight` | `2` |
+# Enable Consul Catalog configuration backend
+#
+# Optional
+#
+[consulCatalog]
-- frontend 1
+# Consul server endpoint
+#
+# Required
+#
+endpoint = "127.0.0.1:8500"
-| Key | Value |
-|----------------------------------------------------|------------------|
-| `/traefik/frontends/frontend1/backend` | `backend2` |
-| `/traefik/frontends/frontend1/routes/test_1/rule` | `Host` |
-| `/traefik/frontends/frontend1/routes/test_1/value` | `test.localhost` |
+# Default domain used.
+#
+# Optional
+#
+domain = "consul.localhost"
+```
-- frontend 2
-
-| Key | Value |
-|----------------------------------------------------|------------|
-| `/traefik/frontends/frontend2/backend` | `backend1` |
-| `/traefik/frontends/frontend2/passHostHeader` | `true` |
-| `/traefik/frontends/frontend2/entrypoints` |`http,https`|
-| `/traefik/frontends/frontend2/routes/test_2/rule` | `Path` |
-| `/traefik/frontends/frontend2/routes/test_2/value` | `/test` |
+This backend will create routes matching on hostname based on the service name
+used in consul.
-## Etcd backend
+## Etcd backend
Træfɪk can be configured to use Etcd as a backend configuration:
@@ -1020,79 +1000,10 @@ Træfɪk can be configured to use Etcd as a backend configuration:
# insecureskipverify = true
```
-The Keys-Values structure should look (using `prefix = "/traefik"`):
-
-- backend 1
-
-| Key | Value |
-|--------------------------------------------------------|-----------------------------|
-| `/traefik/backends/backend1/circuitbreaker/expression` | `NetworkErrorRatio() > 0.5` |
-| `/traefik/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
-| `/traefik/backends/backend1/servers/server1/weight` | `10` |
-| `/traefik/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
-| `/traefik/backends/backend1/servers/server2/weight` | `1` |
-
-- backend 2
-
-| Key | Value |
-|-----------------------------------------------------|------------------------|
-| `/traefik/backends/backend2/loadbalancer/method` | `drr` |
-| `/traefik/backends/backend2/servers/server1/url` | `http://172.17.0.4:80` |
-| `/traefik/backends/backend2/servers/server1/weight` | `1` |
-| `/traefik/backends/backend2/servers/server2/url` | `http://172.17.0.5:80` |
-| `/traefik/backends/backend2/servers/server2/weight` | `2` |
-
-- frontend 1
-
-| Key | Value |
-|----------------------------------------------------|------------------|
-| `/traefik/frontends/frontend1/backend` | `backend2` |
-| `/traefik/frontends/frontend1/routes/test_1/rule` | `Host` |
-| `/traefik/frontends/frontend1/routes/test_1/value` | `test.localhost` |
-
-- frontend 2
-
-| Key | Value |
-|----------------------------------------------------|------------|
-| `/traefik/frontends/frontend2/backend` | `backend1` |
-| `/traefik/frontends/frontend2/passHostHeader` | `true` |
-| `/traefik/frontends/frontend2/entrypoints` |`http,https`|
-| `/traefik/frontends/frontend2/routes/test_2/rule` | `Path` |
-| `/traefik/frontends/frontend2/routes/test_2/value` | `/test` |
+Please refer to the [Key Value storage structure](#key-value-storage-structure) section to get documentation en traefik KV structure.
-## Consul catalog backend
-
-Træfɪk can be configured to use service discovery catalog of Consul as a backend configuration:
-
-```toml
-################################################################
-# Consul Catalog configuration backend
-################################################################
-
-# Enable Consul Catalog configuration backend
-#
-# Optional
-#
-[consulCatalog]
-
-# Consul server endpoint
-#
-# Required
-#
-endpoint = "127.0.0.1:8500"
-
-# Default domain used.
-#
-# Optional
-#
-domain = "consul.localhost"
-```
-
-This backend will create routes matching on hostname based on the service name
-used in consul.
-
-## Zookeeper backend
+## Zookeeper backend
Træfɪk can be configured to use Zookeeper as a backend configuration:
@@ -1131,48 +1042,10 @@ Træfɪk can be configured to use Zookeeper as a backend configuration:
#
# filename = "zookeeper.tmpl"
```
-The Keys-Values structure should look (using `prefix = "/traefik"`):
-- backend 1
+Please refer to the [Key Value storage structure](#key-value-storage-structure) section to get documentation en traefik KV structure.
-| Key | Value |
-|--------------------------------------------------------|-----------------------------|
-| `/traefik/backends/backend1/circuitbreaker/expression` | `NetworkErrorRatio() > 0.5` |
-| `/traefik/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
-| `/traefik/backends/backend1/servers/server1/weight` | `10` |
-| `/traefik/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
-| `/traefik/backends/backend1/servers/server2/weight` | `1` |
-
-- backend 2
-
-| Key | Value |
-|-----------------------------------------------------|------------------------|
-| `/traefik/backends/backend2/loadbalancer/method` | `drr` |
-| `/traefik/backends/backend2/servers/server1/url` | `http://172.17.0.4:80` |
-| `/traefik/backends/backend2/servers/server1/weight` | `1` |
-| `/traefik/backends/backend2/servers/server2/url` | `http://172.17.0.5:80` |
-| `/traefik/backends/backend2/servers/server2/weight` | `2` |
-
-- frontend 1
-
-| Key | Value |
-|---------------------------------------------------|------------------|
-| `/traefik/frontends/frontend1/backend | `backend2` |
-| `/traefik/frontends/frontend1/routes/test_1/rule | `Host` |
-| `/traefik/frontends/frontend1/routes/test_1/value | `test.localhost` |
-
-- frontend 2
-
-| Key | Value |
-|----------------------------------------------------|------------|
-| `/traefik/frontends/frontend2/backend` | `backend1` |
-| `/traefik/frontends/frontend2/passHostHeader` | `true` |
-| `/traefik/frontends/frontend2/entrypoints` |`http,https`|
-| `/traefik/frontends/frontend2/routes/test_2/rule` | `Path` |
-| `/traefik/frontends/frontend2/routes/test_2/value` | `/test` |
-
-
-## BoltDB backend
+## BoltDB backend
Træfɪk can be configured to use BoltDB as a backend configuration:
@@ -1212,7 +1085,49 @@ Træfɪk can be configured to use BoltDB as a backend configuration:
# filename = "boltdb.tmpl"
```
-## Atomic configuration changes
+Please refer to the [Key Value storage structure](#key-value-storage-structure) section to get documentation en traefik KV structure.
+
+## Key-value storage structure
+
+The Keys-Values structure should look (using `prefix = "/traefik"`):
+
+- backend 1
+
+| Key | Value |
+|--------------------------------------------------------|-----------------------------|
+| `/traefik/backends/backend1/circuitbreaker/expression` | `NetworkErrorRatio() > 0.5` |
+| `/traefik/backends/backend1/servers/server1/url` | `http://172.17.0.2:80` |
+| `/traefik/backends/backend1/servers/server1/weight` | `10` |
+| `/traefik/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
+| `/traefik/backends/backend1/servers/server2/weight` | `1` |
+
+- backend 2
+
+| Key | Value |
+|-----------------------------------------------------|------------------------|
+| `/traefik/backends/backend2/loadbalancer/method` | `drr` |
+| `/traefik/backends/backend2/servers/server1/url` | `http://172.17.0.4:80` |
+| `/traefik/backends/backend2/servers/server1/weight` | `1` |
+| `/traefik/backends/backend2/servers/server2/url` | `http://172.17.0.5:80` |
+| `/traefik/backends/backend2/servers/server2/weight` | `2` |
+
+- frontend 1
+
+| Key | Value |
+|---------------------------------------------------|-----------------------|
+| `/traefik/frontends/frontend1/backend` | `backend2` |
+| `/traefik/frontends/frontend1/routes/test_1/rule` | `Host:test.localhost` |
+
+- frontend 2
+
+| Key | Value |
+|----------------------------------------------------|--------------|
+| `/traefik/frontends/frontend2/backend` | `backend1` |
+| `/traefik/frontends/frontend2/passHostHeader` | `true` |
+| `/traefik/frontends/frontend2/entrypoints` | `http,https` |
+| `/traefik/frontends/frontend2/routes/test_2/rule` | `Path:/test` |
+
+## Atomic configuration changes
The [Etcd](https://github.com/coreos/etcd/issues/860) and [Consul](https://github.com/hashicorp/consul/issues/886) backends do not support updating multiple keys atomically. As a result, it may be possible for Træfɪk to read an intermediate configuration state despite judicious use of the `--providersThrottleDuration` flag. To solve this problem, Træfɪk supports a special key called `/traefik/alias`. If set, Træfɪk use the value as an alternative key prefix.
@@ -1251,7 +1166,7 @@ Once the `/traefik/alias` key is updated, the new `/traefik_configurations/2` co
Note that Træfɪk *will not watch for key changes in the `/traefik_configurations` prefix*. It will only watch for changes in the `/traefik` prefix. Further, if the `/traefik/alias` key is set, all other sibling keys with the `/traefik` prefix are ignored.
-## Benchmarks
+## Benchmarks
Here are some early Benchmarks between Nginx, HA-Proxy and Træfɪk acting as simple load balancers between two servers.
diff --git a/glide.lock b/glide.lock
index 07939a6a6..22a3d782f 100644
--- a/glide.lock
+++ b/glide.lock
@@ -1,5 +1,5 @@
-hash: 21d4e8dc80c87101568a719ecf01d1af9a1b58f03c5c9dc864a8cb1005ddc160
-updated: 2016-03-29T21:50:20.577439177+02:00
+hash: a8cca3f2e5bde6b96d0c195402b14606877bc8630cd7f2f06e65e0884c6a008b
+updated: 2016-03-29T23:24:08.772606184+02:00
imports:
- name: github.com/alecthomas/template
version: b867cc6ab45cece8143cfcc6fc9c77cf3f2c23c0
@@ -264,7 +264,7 @@ imports:
subpackages:
- bson
- name: gopkg.in/square/go-jose.v1
- version: 7d9df93c5ee8a09ed250b3b2360972fa29b4bb3c
+ version: 40d457b439244b546f023d056628e5184136899b
subpackages:
- cipher
- json
diff --git a/glide.yaml b/glide.yaml
index 77db5e230..40d65a62e 100644
--- a/glide.yaml
+++ b/glide.yaml
@@ -44,7 +44,7 @@ import:
ref: 6b4e7dc5e3143b85ea77909c72caf89416fc2915
- package: github.com/gambol99/go-marathon
ref: ade11d1dc2884ee1f387078fc28509559b6235d1
- - package: github.com/mailgun/predicate
+ - package: github.com/vulcand/predicate
ref: cb0bff91a7ab7cf7571e661ff883fc997bc554a3
- package: github.com/thoas/stats
ref: 54ed61c2b47e263ae2f01b86837b0c4bd1da28e8
diff --git a/integration/docker_test.go b/integration/docker_test.go
index 5293dbb4a..f06406acb 100644
--- a/integration/docker_test.go
+++ b/integration/docker_test.go
@@ -133,8 +133,7 @@ func (s *DockerSuite) TestDockerContainersWithLabels(c *check.C) {
defer os.Remove(file)
// Start a container with some labels
labels := map[string]string{
- "traefik.frontend.rule": "Host",
- "traefik.frontend.value": "my.super.host",
+ "traefik.frontend.rule": "Host:my.super.host",
}
s.startContainerWithLabels(c, "swarm:1.0.0", labels, "manage", "token://blabla")
diff --git a/integration/fixtures/file/simple.toml b/integration/fixtures/file/simple.toml
index bcdc07c6e..e9cb7cc67 100644
--- a/integration/fixtures/file/simple.toml
+++ b/integration/fixtures/file/simple.toml
@@ -33,10 +33,8 @@ logLevel = "DEBUG"
[frontends.frontend1]
backend = "backend2"
[frontends.frontend1.routes.test_1]
- rule = "Host"
- value = "test.localhost"
+ rule = "Host:test.localhost"
[frontends.frontend2]
backend = "backend1"
[frontends.frontend2.routes.test_2]
- rule = "Path"
- value = "/test"
+ rule = "Path:/test"
diff --git a/integration/fixtures/https/https_sni.toml b/integration/fixtures/https/https_sni.toml
index 2a1fa04a9..66f737a36 100644
--- a/integration/fixtures/https/https_sni.toml
+++ b/integration/fixtures/https/https_sni.toml
@@ -27,10 +27,8 @@ defaultEntryPoints = ["https"]
[frontends.frontend1]
backend = "backend1"
[frontends.frontend1.routes.test_1]
- rule = "Host"
- value = "snitest.com"
+ rule = "Host:snitest.com"
[frontends.frontend2]
backend = "backend2"
[frontends.frontend2.routes.test_2]
- rule = "Host"
- value = "snitest.org"
+ rule = "Host:snitest.org"
diff --git a/middlewares/StripPrefix.go b/middlewares/stripPrefix.go
similarity index 81%
rename from middlewares/StripPrefix.go
rename to middlewares/stripPrefix.go
index 244d2862a..92eb7a5f1 100644
--- a/middlewares/StripPrefix.go
+++ b/middlewares/stripPrefix.go
@@ -20,3 +20,8 @@ func (s *StripPrefix) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.NotFound(w, r)
}
}
+
+// SetHandler sets handler
+func (s *StripPrefix) SetHandler(Handler http.Handler) {
+ s.Handler = Handler
+}
diff --git a/provider/consul_catalog.go b/provider/consul_catalog.go
index c77d2dd23..01c823058 100644
--- a/provider/consul_catalog.go
+++ b/provider/consul_catalog.go
@@ -89,7 +89,7 @@ func (provider *ConsulCatalog) getBackend(node *api.ServiceEntry) string {
}
func (provider *ConsulCatalog) getFrontendValue(service string) string {
- return service + "." + provider.Domain
+ return "Host:" + service + "." + provider.Domain
}
func (provider *ConsulCatalog) buildConfig(catalog []catalogUpdate) *types.Configuration {
diff --git a/provider/consul_catalog_test.go b/provider/consul_catalog_test.go
index c5086e627..9cf309838 100644
--- a/provider/consul_catalog_test.go
+++ b/provider/consul_catalog_test.go
@@ -8,7 +8,7 @@ import (
"github.com/hashicorp/consul/api"
)
-func TestConsulCatalogGetFrontendValue(t *testing.T) {
+func TestConsulCatalogGetFrontendRule(t *testing.T) {
provider := &ConsulCatalog{
Domain: "localhost",
}
@@ -19,7 +19,7 @@ func TestConsulCatalogGetFrontendValue(t *testing.T) {
}{
{
service: "foo",
- expected: "foo.localhost",
+ expected: "Host:foo.localhost",
},
}
@@ -78,8 +78,7 @@ func TestConsulCatalogBuildConfig(t *testing.T) {
Backend: "backend-test",
Routes: map[string]types.Route{
"route-host-test": {
- Rule: "Host",
- Value: "test.localhost",
+ Rule: "Host:test.localhost",
},
},
},
diff --git a/provider/docker.go b/provider/docker.go
index 58939554f..e4190990b 100644
--- a/provider/docker.go
+++ b/provider/docker.go
@@ -2,7 +2,6 @@ package provider
import (
"errors"
- "fmt"
"strconv"
"strings"
"text/template"
@@ -108,7 +107,6 @@ func (provider *Docker) loadDockerConfig(containersInspected []docker.Container)
"getProtocol": provider.getProtocol,
"getPassHostHeader": provider.getPassHostHeader,
"getEntryPoints": provider.getEntryPoints,
- "getFrontendValue": provider.getFrontendValue,
"getFrontendRule": provider.getFrontendRule,
"replace": replace,
}
@@ -154,47 +152,37 @@ func containerFilter(container docker.Container) bool {
return false
}
- labels, err := getLabels(container, []string{"traefik.frontend.rule", "traefik.frontend.value"})
- if len(labels) != 0 && err != nil {
- log.Debugf("Filtering bad labeled container %s", container.Name)
- return false
- }
-
return true
}
func (provider *Docker) getFrontendName(container docker.Container) string {
// Replace '.' with '-' in quoted keys because of this issue https://github.com/BurntSushi/toml/issues/78
- frontendName := fmt.Sprintf("%s-%s", provider.getFrontendRule(container), provider.getFrontendValue(container))
- frontendName = strings.Replace(frontendName, "[", "", -1)
- frontendName = strings.Replace(frontendName, "]", "", -1)
-
- return strings.Replace(frontendName, ".", "-", -1)
-}
-
-// GetFrontendValue returns the frontend value for the specified container, using
-// it's label. It returns a default one if the label is not present.
-func (provider *Docker) getFrontendValue(container docker.Container) string {
- if label, err := getLabel(container, "traefik.frontend.value"); err == nil {
- return label
- }
- return getEscapedName(container.Name) + "." + provider.Domain
+ return normalize(provider.getFrontendRule(container))
}
// GetFrontendRule returns the frontend rule for the specified container, using
// it's label. It returns a default one (Host) if the label is not present.
func (provider *Docker) getFrontendRule(container docker.Container) string {
+ // ⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
+ // TODO: backwards compatibility with DEPRECATED rule.Value
+ if value, ok := container.Config.Labels["traefik.frontend.value"]; ok {
+ log.Warnf("Label traefik.frontend.value=%s is DEPRECATED (will be removed in v1.0.0), please refer to the rule label: https://github.com/containous/traefik/blob/master/docs/index.md#docker", value)
+ rule, _ := container.Config.Labels["traefik.frontend.rule"]
+ return rule + ":" + value
+ }
+ // ⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
+
if label, err := getLabel(container, "traefik.frontend.rule"); err == nil {
return label
}
- return "Host"
+ return "Host:" + getEscapedName(container.Name) + "." + provider.Domain
}
func (provider *Docker) getBackend(container docker.Container) string {
if label, err := getLabel(container, "traefik.backend"); err == nil {
return label
}
- return getEscapedName(container.Name)
+ return normalize(container.Name)
}
func (provider *Docker) getPort(container docker.Container) string {
@@ -211,7 +199,7 @@ func (provider *Docker) getWeight(container docker.Container) string {
if label, err := getLabel(container, "traefik.weight"); err == nil {
return label
}
- return "0"
+ return "1"
}
func (provider *Docker) getDomain(container docker.Container) string {
diff --git a/provider/docker_test.go b/provider/docker_test.go
index 2c51c0670..0dfb585f3 100644
--- a/provider/docker_test.go
+++ b/provider/docker_test.go
@@ -30,18 +30,18 @@ func TestDockerGetFrontendName(t *testing.T) {
Name: "bar",
Config: &docker.Config{
Labels: map[string]string{
- "traefik.frontend.rule": "Header",
+ "traefik.frontend.rule": "Headers:User-Agent,bat/0.1.0",
},
},
},
- expected: "Header-bar-docker-localhost",
+ expected: "Headers-User-Agent-bat-0-1-0",
},
{
container: docker.Container{
Name: "test",
Config: &docker.Config{
Labels: map[string]string{
- "traefik.frontend.value": "foo.bar",
+ "traefik.frontend.rule": "Host:foo.bar",
},
},
},
@@ -52,24 +52,22 @@ func TestDockerGetFrontendName(t *testing.T) {
Name: "test",
Config: &docker.Config{
Labels: map[string]string{
- "traefik.frontend.value": "foo.bar",
- "traefik.frontend.rule": "Header",
+ "traefik.frontend.rule": "Path:/test",
},
},
},
- expected: "Header-foo-bar",
+ expected: "Path-test",
},
{
container: docker.Container{
Name: "test",
Config: &docker.Config{
Labels: map[string]string{
- "traefik.frontend.value": "[foo.bar]",
- "traefik.frontend.rule": "Header",
+ "traefik.frontend.rule": "PathPrefix:/test2",
},
},
},
- expected: "Header-foo-bar",
+ expected: "PathPrefix-test2",
},
}
@@ -81,7 +79,7 @@ func TestDockerGetFrontendName(t *testing.T) {
}
}
-func TestDockerGetFrontendValue(t *testing.T) {
+func TestDockerGetFrontendRule(t *testing.T) {
provider := &Docker{
Domain: "docker.localhost",
}
@@ -95,60 +93,36 @@ func TestDockerGetFrontendValue(t *testing.T) {
Name: "foo",
Config: &docker.Config{},
},
- expected: "foo.docker.localhost",
+ expected: "Host:foo.docker.localhost",
},
{
container: docker.Container{
Name: "bar",
Config: &docker.Config{},
},
- expected: "bar.docker.localhost",
+ expected: "Host:bar.docker.localhost",
},
{
container: docker.Container{
Name: "test",
Config: &docker.Config{
Labels: map[string]string{
- "traefik.frontend.value": "foo.bar",
+ "traefik.frontend.rule": "Host:foo.bar",
},
},
},
- expected: "foo.bar",
- },
- }
-
- for _, e := range containers {
- actual := provider.getFrontendValue(e.container)
- if actual != e.expected {
- t.Fatalf("expected %q, got %q", e.expected, actual)
- }
- }
-}
-
-func TestDockerGetFrontendRule(t *testing.T) {
- provider := &Docker{}
-
- containers := []struct {
- container docker.Container
- expected string
- }{
- {
- container: docker.Container{
- Name: "foo",
- Config: &docker.Config{},
- },
- expected: "Host",
+ expected: "Host:foo.bar",
},
{
container: docker.Container{
Name: "test",
Config: &docker.Config{
Labels: map[string]string{
- "traefik.frontend.rule": "foo",
+ "traefik.frontend.rule": "Path:/test",
},
},
},
- expected: "foo",
+ expected: "Path:/test",
},
}
@@ -281,7 +255,7 @@ func TestDockerGetWeight(t *testing.T) {
Name: "foo",
Config: &docker.Config{},
},
- expected: "0",
+ expected: "1",
},
{
container: docker.Container{
@@ -535,7 +509,7 @@ func TestDockerTraefikFilter(t *testing.T) {
container: docker.Container{
Config: &docker.Config{
Labels: map[string]string{
- "traefik.frontend.rule": "Host",
+ "traefik.frontend.rule": "Host:foo.bar",
},
},
NetworkSettings: &docker.NetworkSettings{
@@ -544,22 +518,7 @@ func TestDockerTraefikFilter(t *testing.T) {
},
},
},
- expected: false,
- },
- {
- container: docker.Container{
- Config: &docker.Config{
- Labels: map[string]string{
- "traefik.frontend.value": "foo.bar",
- },
- },
- NetworkSettings: &docker.NetworkSettings{
- Ports: map[docker.Port][]docker.PortBinding{
- "80/tcp": {},
- },
- },
- },
- expected: false,
+ expected: true,
},
{
container: docker.Container{
@@ -634,8 +593,7 @@ func TestDockerTraefikFilter(t *testing.T) {
container: docker.Container{
Config: &docker.Config{
Labels: map[string]string{
- "traefik.frontend.rule": "Host",
- "traefik.frontend.value": "foo.bar",
+ "traefik.frontend.rule": "Host:foo.bar",
},
},
NetworkSettings: &docker.NetworkSettings{
@@ -651,7 +609,7 @@ func TestDockerTraefikFilter(t *testing.T) {
for _, e := range containers {
actual := containerFilter(e.container)
if actual != e.expected {
- t.Fatalf("expected %v, got %v", e.expected, actual)
+ t.Fatalf("expected %v for %+v, got %+v", e.expected, e, actual)
}
}
}
@@ -690,8 +648,7 @@ func TestDockerLoadDockerConfig(t *testing.T) {
EntryPoints: []string{},
Routes: map[string]types.Route{
`"route-frontend-Host-test-docker-localhost"`: {
- Rule: "Host",
- Value: "test.docker.localhost",
+ Rule: "Host:test.docker.localhost",
},
},
},
@@ -700,7 +657,8 @@ func TestDockerLoadDockerConfig(t *testing.T) {
"backend-test": {
Servers: map[string]types.Server{
"server-test": {
- URL: "http://127.0.0.1:80",
+ URL: "http://127.0.0.1:80",
+ Weight: 1,
},
},
CircuitBreaker: nil,
@@ -741,7 +699,7 @@ func TestDockerLoadDockerConfig(t *testing.T) {
"80/tcp": {},
},
Networks: map[string]docker.ContainerNetwork{
- "bridgde": {
+ "bridge": {
IPAddress: "127.0.0.1",
},
},
@@ -754,8 +712,7 @@ func TestDockerLoadDockerConfig(t *testing.T) {
EntryPoints: []string{"http", "https"},
Routes: map[string]types.Route{
`"route-frontend-Host-test1-docker-localhost"`: {
- Rule: "Host",
- Value: "test1.docker.localhost",
+ Rule: "Host:test1.docker.localhost",
},
},
},
@@ -764,8 +721,7 @@ func TestDockerLoadDockerConfig(t *testing.T) {
EntryPoints: []string{},
Routes: map[string]types.Route{
`"route-frontend-Host-test2-docker-localhost"`: {
- Rule: "Host",
- Value: "test2.docker.localhost",
+ Rule: "Host:test2.docker.localhost",
},
},
},
@@ -774,10 +730,12 @@ func TestDockerLoadDockerConfig(t *testing.T) {
"backend-foobar": {
Servers: map[string]types.Server{
"server-test1": {
- URL: "http://127.0.0.1:80",
+ URL: "http://127.0.0.1:80",
+ Weight: 1,
},
"server-test2": {
- URL: "http://127.0.0.1:80",
+ URL: "http://127.0.0.1:80",
+ Weight: 1,
},
},
CircuitBreaker: nil,
diff --git a/provider/marathon.go b/provider/marathon.go
index 787b8e8fd..b255bbe5f 100644
--- a/provider/marathon.go
+++ b/provider/marathon.go
@@ -96,7 +96,6 @@ func (provider *Marathon) loadMarathonConfig() *types.Configuration {
"getProtocol": provider.getProtocol,
"getPassHostHeader": provider.getPassHostHeader,
"getEntryPoints": provider.getEntryPoints,
- "getFrontendValue": provider.getFrontendValue,
"getFrontendRule": provider.getFrontendRule,
"getFrontendBackend": provider.getFrontendBackend,
"replace": replace,
@@ -309,22 +308,21 @@ func (provider *Marathon) getEntryPoints(application marathon.Application) []str
return []string{}
}
-// getFrontendValue returns the frontend value for the specified application, using
-// it's label. It returns a default one if the label is not present.
-func (provider *Marathon) getFrontendValue(application marathon.Application) string {
- if label, err := provider.getLabel(application, "traefik.frontend.value"); err == nil {
- return label
- }
- return getEscapedName(application.ID) + "." + provider.Domain
-}
-
// getFrontendRule returns the frontend rule for the specified application, using
// it's label. It returns a default one (Host) if the label is not present.
func (provider *Marathon) getFrontendRule(application marathon.Application) string {
+ // ⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
+ // TODO: backwards compatibility with DEPRECATED rule.Value
+ if value, err := provider.getLabel(application, "traefik.frontend.value"); err == nil {
+ log.Warnf("Label traefik.frontend.value=%s is DEPRECATED, please refer to the rule label: https://github.com/containous/traefik/blob/master/docs/index.md#marathon", value)
+ rule, _ := provider.getLabel(application, "traefik.frontend.rule")
+ return rule + ":" + value
+ }
+ // ⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
if label, err := provider.getLabel(application, "traefik.frontend.rule"); err == nil {
return label
}
- return "Host"
+ return "Host:" + getEscapedName(application.ID) + "." + provider.Domain
}
func (provider *Marathon) getBackend(task marathon.Task, applications []marathon.Application) string {
diff --git a/provider/marathon_test.go b/provider/marathon_test.go
index 32fd00698..def8d5595 100644
--- a/provider/marathon_test.go
+++ b/provider/marathon_test.go
@@ -86,8 +86,7 @@ func TestMarathonLoadConfig(t *testing.T) {
EntryPoints: []string{},
Routes: map[string]types.Route{
`route-host-test`: {
- Rule: "Host",
- Value: "test.docker.localhost",
+ Rule: "Host:test.docker.localhost",
},
},
},
@@ -831,7 +830,7 @@ func TestMarathonGetEntryPoints(t *testing.T) {
}
}
-func TestMarathonGetFrontendValue(t *testing.T) {
+func TestMarathonGetFrontendRule(t *testing.T) {
provider := &Marathon{
Domain: "docker.localhost",
}
@@ -842,50 +841,21 @@ func TestMarathonGetFrontendValue(t *testing.T) {
}{
{
application: marathon.Application{},
- expected: ".docker.localhost",
+ expected: "Host:.docker.localhost",
},
{
application: marathon.Application{
ID: "test",
},
- expected: "test.docker.localhost",
+ expected: "Host:test.docker.localhost",
},
{
application: marathon.Application{
Labels: map[string]string{
- "traefik.frontend.value": "foo.bar",
+ "traefik.frontend.rule": "Host:foo.bar",
},
},
- expected: "foo.bar",
- },
- }
-
- for _, a := range applications {
- actual := provider.getFrontendValue(a.application)
- if actual != a.expected {
- t.Fatalf("expected %q, got %q", a.expected, actual)
- }
- }
-}
-
-func TestMarathonGetFrontendRule(t *testing.T) {
- provider := &Marathon{}
-
- applications := []struct {
- application marathon.Application
- expected string
- }{
- {
- application: marathon.Application{},
- expected: "Host",
- },
- {
- application: marathon.Application{
- Labels: map[string]string{
- "traefik.frontend.rule": "Header",
- },
- },
- expected: "Header",
+ expected: "Host:foo.bar",
},
}
diff --git a/provider/provider.go b/provider/provider.go
index 0213b5034..a1c0c660e 100644
--- a/provider/provider.go
+++ b/provider/provider.go
@@ -9,6 +9,7 @@ import (
"github.com/BurntSushi/toml"
"github.com/containous/traefik/autogen"
"github.com/containous/traefik/types"
+ "unicode"
)
// Provider defines methods of a provider.
@@ -67,3 +68,11 @@ func replace(s1 string, s2 string, s3 string) string {
func getEscapedName(name string) string {
return strings.Replace(strings.TrimPrefix(name, "/"), "/", "-", -1)
}
+
+func normalize(name string) string {
+ fargs := func(c rune) bool {
+ return !unicode.IsLetter(c) && !unicode.IsNumber(c)
+ }
+ // get function
+ return strings.Join(strings.FieldsFunc(name, fargs), "-")
+}
diff --git a/rules.go b/rules.go
new file mode 100644
index 000000000..8d43a884c
--- /dev/null
+++ b/rules.go
@@ -0,0 +1,92 @@
+package main
+
+import (
+ "errors"
+ "github.com/gorilla/mux"
+ "reflect"
+ "strings"
+)
+
+// Rules holds rule parsing and configuration
+type Rules struct {
+ route *serverRoute
+}
+
+func (r *Rules) host(host string) *mux.Route {
+ return r.route.route.Host(host)
+}
+
+func (r *Rules) path(path string) *mux.Route {
+ return r.route.route.Path(path)
+}
+
+func (r *Rules) pathPrefix(path string) *mux.Route {
+ return r.route.route.PathPrefix(path)
+}
+
+func (r *Rules) pathStrip(path string) *mux.Route {
+ r.route.stripPrefix = path
+ return r.route.route.Path(path)
+}
+
+func (r *Rules) pathPrefixStrip(path string) *mux.Route {
+ r.route.stripPrefix = path
+ return r.route.route.PathPrefix(path)
+}
+
+func (r *Rules) methods(methods ...string) *mux.Route {
+ return r.route.route.Methods(methods...)
+}
+
+func (r *Rules) headers(headers ...string) *mux.Route {
+ return r.route.route.Headers(headers...)
+}
+
+func (r *Rules) headersRegexp(headers ...string) *mux.Route {
+ return r.route.route.HeadersRegexp(headers...)
+}
+
+// Parse parses rules expressions
+func (r *Rules) Parse(expression string) (*mux.Route, error) {
+ functions := map[string]interface{}{
+ "Host": r.host,
+ "Path": r.path,
+ "PathStrip": r.pathStrip,
+ "PathPrefix": r.pathPrefix,
+ "PathPrefixStrip": r.pathPrefixStrip,
+ "Methods": r.methods,
+ "Headers": r.headers,
+ "HeadersRegexp": r.headersRegexp,
+ }
+ f := func(c rune) bool {
+ return c == ':' || c == '='
+ }
+ // get function
+ parsedFunctions := strings.FieldsFunc(expression, f)
+ if len(parsedFunctions) != 2 {
+ return nil, errors.New("Error parsing rule: " + expression)
+ }
+ parsedFunction, ok := functions[parsedFunctions[0]]
+ if !ok {
+ return nil, errors.New("Error parsing rule: " + expression + ". Unknow function: " + parsedFunctions[0])
+ }
+
+ fargs := func(c rune) bool {
+ return c == ',' || c == ';'
+ }
+ // get function
+ parsedArgs := strings.FieldsFunc(parsedFunctions[1], fargs)
+ if len(parsedArgs) == 0 {
+ return nil, errors.New("Error parsing args from rule: " + expression)
+ }
+
+ inputs := make([]reflect.Value, len(parsedArgs))
+ for i := range parsedArgs {
+ inputs[i] = reflect.ValueOf(parsedArgs[i])
+ }
+ method := reflect.ValueOf(parsedFunction)
+ if method.IsValid() {
+ return method.Call(inputs)[0].Interface().(*mux.Route), nil
+ }
+ return nil, errors.New("Method not found: " + parsedFunctions[0])
+}
diff --git a/script/deploy.sh b/script/deploy.sh
index 2671c0fb4..c906d4531 100755
--- a/script/deploy.sh
+++ b/script/deploy.sh
@@ -21,20 +21,18 @@ git config --global user.email "emile@vauge.com"
git config --global user.name "Emile Vauge"
git clone https://github.com/containous/traefik-library-image.git
cd traefik-library-image
-git remote rm origin
-git remote add origin https://emilevauge:${GITHUB_TOKEN}@github.com/containous/traefik-library-image.git
./update.sh $VERSION
git add -A
echo $VERSION | git commit --file -
echo $VERSION | git tag -a $VERSION --file -
-git push --follow-tags -u origin master
+git push -q --follow-tags https://emilevauge:${GITHUB_TOKEN}@github.com/containous/traefik-library-image.git
# create docker image emilevauge/traefik (compatibility)
docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
docker tag containous/traefik emilevauge/traefik:latest
docker push emilevauge/traefik:latest
docker tag emilevauge/traefik:latest emilevauge/traefik:${VERSION}
-docker push emilevauge/traefik:${VERSION}
+docker push -q emilevauge/traefik:${VERSION}
cd ..
rm -Rf traefik-library-image/
diff --git a/server.go b/server.go
index 4f3f28489..95f8eb0be 100644
--- a/server.go
+++ b/server.go
@@ -55,6 +55,11 @@ type serverEntryPoint struct {
httpRouter *middlewares.HandlerSwitcher
}
+type serverRoute struct {
+ route *mux.Route
+ stripPrefix string
+}
+
// NewServer returns an initialized Server.
func NewServer(globalConfiguration GlobalConfiguration) *Server {
server := new(Server)
@@ -354,23 +359,22 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo
if _, ok := serverEntryPoints[entryPointName]; !ok {
return nil, errors.New("Undefined entrypoint: " + entryPointName)
}
- newRoute := serverEntryPoints[entryPointName].httpRouter.GetHandler().NewRoute().Name(frontendName)
+ newServerRoute := &serverRoute{route: serverEntryPoints[entryPointName].httpRouter.GetHandler().NewRoute().Name(frontendName)}
for routeName, route := range frontend.Routes {
- log.Debugf("Creating route %s %s:%s", routeName, route.Rule, route.Value)
- route, err := getRoute(newRoute, route.Rule, route.Value)
+ err := getRoute(newServerRoute, &route)
if err != nil {
return nil, err
}
- newRoute = route
+ log.Debugf("Creating route %s %s", routeName, route.Rule)
}
entryPoint := globalConfiguration.EntryPoints[entryPointName]
if entryPoint.Redirect != nil {
if redirectHandlers[entryPointName] != nil {
- newRoute.Handler(redirectHandlers[entryPointName])
+ newServerRoute.route.Handler(redirectHandlers[entryPointName])
} else if handler, err := server.loadEntryPointConfig(entryPointName, entryPoint); err != nil {
return nil, err
} else {
- newRoute.Handler(handler)
+ newServerRoute.route.Handler(handler)
redirectHandlers[entryPointName] = handler
}
} else {
@@ -448,9 +452,9 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo
} else {
log.Debugf("Reusing backend %s", frontend.Backend)
}
- server.wireFrontendBackend(frontend.Routes, newRoute, backends[frontend.Backend])
+ server.wireFrontendBackend(newServerRoute, backends[frontend.Backend])
}
- err := newRoute.GetError()
+ err := newServerRoute.route.GetError()
if err != nil {
log.Errorf("Error building route: %s", err)
}
@@ -460,29 +464,15 @@ func (server *Server) loadConfig(configurations configs, globalConfiguration Glo
return serverEntryPoints, nil
}
-func (server *Server) wireFrontendBackend(routes map[string]types.Route, newRoute *mux.Route, handler http.Handler) {
+func (server *Server) wireFrontendBackend(serverRoute *serverRoute, handler http.Handler) {
// strip prefix
- var strip bool
- for _, route := range routes {
- switch route.Rule {
- case "PathStrip":
- newRoute.Handler(&middlewares.StripPrefix{
- Prefix: route.Value,
- Handler: handler,
- })
- strip = true
- break
- case "PathPrefixStrip":
- newRoute.Handler(&middlewares.StripPrefix{
- Prefix: route.Value,
- Handler: handler,
- })
- strip = true
- break
- }
- }
- if !strip {
- newRoute.Handler(handler)
+ if len(serverRoute.stripPrefix) > 0 {
+ serverRoute.route.Handler(&middlewares.StripPrefix{
+ Prefix: serverRoute.stripPrefix,
+ Handler: handler,
+ })
+ } else {
+ serverRoute.route.Handler(handler)
}
}
@@ -522,32 +512,29 @@ func (server *Server) buildDefaultHTTPRouter() *mux.Router {
return router
}
-func getRoute(any interface{}, rule string, value ...interface{}) (*mux.Route, error) {
- switch rule {
- case "PathStrip":
- rule = "Path"
- case "PathPrefixStrip":
- rule = "PathPrefix"
+func getRoute(serverRoute *serverRoute, route *types.Route) error {
+ // ⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
+ // TODO: backwards compatibility with DEPRECATED rule.Value
+ if len(route.Value) > 0 {
+ route.Rule += ":" + route.Value
+ log.Warnf("Value %s is DEPRECATED (will be removed in v1.0.0), please refer to the new frontend notation: https://github.com/containous/traefik/blob/master/docs/index.md#-frontends", route.Value)
}
- inputs := make([]reflect.Value, len(value))
- for i := range value {
- inputs[i] = reflect.ValueOf(value[i])
+ // ⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
+
+ rules := Rules{route: serverRoute}
+ newRoute, err := rules.Parse(route.Rule)
+ if err != nil {
+ return err
}
- method := reflect.ValueOf(any).MethodByName(rule)
- if method.IsValid() {
- return method.Call(inputs)[0].Interface().(*mux.Route), nil
- }
- return nil, errors.New("Method not found: " + rule)
+ serverRoute.route = newRoute
+ return nil
}
func sortedFrontendNamesForConfig(configuration *types.Configuration) []string {
keys := []string{}
-
for key := range configuration.Frontends {
keys = append(keys, key)
}
-
sort.Strings(keys)
-
return keys
}
diff --git a/templates/consul_catalog.tmpl b/templates/consul_catalog.tmpl
index 65a7a0d3c..a51cd341b 100644
--- a/templates/consul_catalog.tmpl
+++ b/templates/consul_catalog.tmpl
@@ -8,6 +8,5 @@
backend = "backend-{{.}}"
passHostHeader = false
[frontends.frontend-{{.}}.routes.route-host-{{.}}]
- rule = "Host"
- value = "{{getFrontendValue .}}"
+ rule = "{{getFrontendValue .}}"
{{end}}
diff --git a/templates/docker.tmpl b/templates/docker.tmpl
index 7826acc56..f43bef8b4 100644
--- a/templates/docker.tmpl
+++ b/templates/docker.tmpl
@@ -13,5 +13,4 @@
{{end}}]
[frontends."frontend-{{$frontend}}".routes."route-frontend-{{$frontend}}"]
rule = "{{getFrontendRule $container}}"
- value = "{{getFrontendValue $container}}"
{{end}}
diff --git a/templates/kv.tmpl b/templates/kv.tmpl
index 9fd770d24..97793784f 100644
--- a/templates/kv.tmpl
+++ b/templates/kv.tmpl
@@ -37,6 +37,5 @@
{{range $routes}}
[frontends.{{$frontend}}.routes.{{Last .}}]
rule = "{{Get "" . "/rule"}}"
- value = "{{Get "" . "/value"}}"
{{end}}
{{end}}
diff --git a/templates/marathon.tmpl b/templates/marathon.tmpl
index ba60b5012..d2243cf47 100644
--- a/templates/marathon.tmpl
+++ b/templates/marathon.tmpl
@@ -14,5 +14,4 @@
{{end}}]
[frontends.frontend{{.ID | replace "/" "-"}}.routes.route-host{{.ID | replace "/" "-"}}]
rule = "{{getFrontendRule .}}"
- value = "{{getFrontendValue .}}"
{{end}}
diff --git a/tests/whoami.json b/tests/whoami.json
index 138a2264d..daebbfa26 100644
--- a/tests/whoami.json
+++ b/tests/whoami.json
@@ -25,6 +25,7 @@
],
"labels": {
"traefik.weight": "1",
- "traefik.protocole": "http"
+ "traefik.protocole": "http",
+ "traefik.frontend.rule" : "Headers:Host,test.localhost"
}
}
diff --git a/traefik.sample.toml b/traefik.sample.toml
index 6985d55f8..945f963a3 100644
--- a/traefik.sample.toml
+++ b/traefik.sample.toml
@@ -513,17 +513,14 @@
# [frontends.frontend1]
# backend = "backend2"
# [frontends.frontend1.routes.test_1]
-# rule = "Host"
-# value = "test.localhost"
+# rule = "Host:test.localhost"
# [frontends.frontend2]
# backend = "backend1"
# passHostHeader = true
# entrypoints = ["https"] # overrides defaultEntryPoints
# [frontends.frontend2.routes.test_1]
-# rule = "Host"
-# value = "{subdomain:[a-z]+}.localhost"
+# rule = "Host:{subdomain:[a-z]+}.localhost"
# [frontends.frontend3]
# entrypoints = ["http", "https"] # overrides defaultEntryPoints
# backend = "backend2"
-# rule = "Path"
-# value = "/test"
+# rule = "Path:/test"
\ No newline at end of file
diff --git a/types/types.go b/types/types.go
index 30bfbf483..2168ac49f 100644
--- a/types/types.go
+++ b/types/types.go
@@ -30,8 +30,11 @@ type Server struct {
// Route holds route configuration.
type Route struct {
- Rule string `json:"rule,omitempty"`
+ Rule string `json:"rule,omitempty"`
+ // ⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
+ // TODO: backwards compatibility with DEPRECATED rule.Value
Value string `json:"value,omitempty"`
+ // ⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠⚠
}
// Frontend holds frontend configuration.
diff --git a/webui/src/app/sections/providers/frontend-monitor/frontend-monitor.html b/webui/src/app/sections/providers/frontend-monitor/frontend-monitor.html
index 48c8e67ba..6881c4bd8 100644
--- a/webui/src/app/sections/providers/frontend-monitor/frontend-monitor.html
+++ b/webui/src/app/sections/providers/frontend-monitor/frontend-monitor.html
@@ -7,12 +7,10 @@
Route |
Rule |
- Value |
{{routeId}} |
- {{route.rule}} |
- {{route.value}} |
+ {{route.rule}} |
diff --git a/webui/src/index.html b/webui/src/index.html
index fbb832c71..20d356187 100644
--- a/webui/src/index.html
+++ b/webui/src/index.html
@@ -30,7 +30,7 @@