commit
12c1131b0c
4 changed files with 121 additions and 5 deletions
77
docs/toml.md
77
docs/toml.md
|
@ -64,6 +64,55 @@
|
||||||
# defaultEntryPoints = ["http", "https"]
|
# defaultEntryPoints = ["http", "https"]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Constraints
|
||||||
|
|
||||||
|
In a micro-service architecture, with a central service discovery, setting constraints limits Træfɪk scope to a smaller number of routes.
|
||||||
|
|
||||||
|
Træfɪk filters services according to service attributes/tags set in your configuration backends.
|
||||||
|
|
||||||
|
Supported backends:
|
||||||
|
|
||||||
|
- Docker
|
||||||
|
- Consul K/V
|
||||||
|
- BoltDB
|
||||||
|
- Zookeeper
|
||||||
|
- Etcd
|
||||||
|
- Consul Catalog
|
||||||
|
|
||||||
|
Supported filters:
|
||||||
|
|
||||||
|
- ```tag```
|
||||||
|
|
||||||
|
```
|
||||||
|
# Constraints definition
|
||||||
|
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
#
|
||||||
|
|
||||||
|
# Simple matching constraint
|
||||||
|
# constraints = ["tag==api"]
|
||||||
|
|
||||||
|
# Simple mismatching constraint
|
||||||
|
# constraints = ["tag!=api"]
|
||||||
|
|
||||||
|
# Globbing
|
||||||
|
# constraints = ["tag==us-*"]
|
||||||
|
|
||||||
|
# Backend-specific constraint
|
||||||
|
# [consulCatalog]
|
||||||
|
# endpoint = 127.0.0.1:8500
|
||||||
|
# constraints = ["tag==api"]
|
||||||
|
|
||||||
|
# Multiple constraints
|
||||||
|
# - "tag==" must match with at least one tag
|
||||||
|
# - "tag!=" must match with none of tags
|
||||||
|
# constraints = ["tag!=us-*", "tag!=asia-*"]
|
||||||
|
# [consulCatalog]
|
||||||
|
# endpoint = 127.0.0.1:8500
|
||||||
|
# constraints = ["tag==api", "tag!=v*-beta"]
|
||||||
|
```
|
||||||
|
|
||||||
## Entrypoints definition
|
## Entrypoints definition
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
|
@ -834,6 +883,13 @@ prefix = "traefik"
|
||||||
# cert = "/etc/ssl/consul.crt"
|
# cert = "/etc/ssl/consul.crt"
|
||||||
# key = "/etc/ssl/consul.key"
|
# key = "/etc/ssl/consul.key"
|
||||||
# insecureskipverify = true
|
# insecureskipverify = true
|
||||||
|
|
||||||
|
# Constraint on ConsulKV tags
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
#
|
||||||
|
# constraints = ["tag==api", "tag==he*ld"]
|
||||||
|
# Matching with containers having a key "/traefik/backends/backend1/servers/server1/tags" equal to "api,helloworld"
|
||||||
```
|
```
|
||||||
|
|
||||||
Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure.
|
Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure.
|
||||||
|
@ -937,6 +993,13 @@ prefix = "/traefik"
|
||||||
# cert = "/etc/ssl/etcd.crt"
|
# cert = "/etc/ssl/etcd.crt"
|
||||||
# key = "/etc/ssl/etcd.key"
|
# key = "/etc/ssl/etcd.key"
|
||||||
# insecureskipverify = true
|
# insecureskipverify = true
|
||||||
|
|
||||||
|
# Constraint on Etcd tags
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
#
|
||||||
|
# constraints = ["tag==api", "tag==he*ld"]
|
||||||
|
# Matching with containers having a key "/traefik/backends/backend1/servers/server1/tags" equal to "api,helloworld"
|
||||||
```
|
```
|
||||||
|
|
||||||
Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure.
|
Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure.
|
||||||
|
@ -980,6 +1043,13 @@ prefix = "/traefik"
|
||||||
# Optional
|
# Optional
|
||||||
#
|
#
|
||||||
# filename = "zookeeper.tmpl"
|
# filename = "zookeeper.tmpl"
|
||||||
|
|
||||||
|
# Constraint on Zookeeper tags
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
#
|
||||||
|
# constraints = ["tag==api", "tag==he*ld"]
|
||||||
|
# Matching with containers having a key "/traefik/backends/backend1/servers/server1/tags" equal to "api,helloworld"
|
||||||
```
|
```
|
||||||
|
|
||||||
Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure.
|
Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure.
|
||||||
|
@ -1022,6 +1092,13 @@ prefix = "/traefik"
|
||||||
# Optional
|
# Optional
|
||||||
#
|
#
|
||||||
# filename = "boltdb.tmpl"
|
# filename = "boltdb.tmpl"
|
||||||
|
|
||||||
|
# Constraint on BoltDB tags
|
||||||
|
#
|
||||||
|
# Optional
|
||||||
|
#
|
||||||
|
# constraints = ["tag==api", "tag==he*ld"]
|
||||||
|
# Matching with containers having a key "/traefik/backends/backend1/servers/server1/tags" equal to "api,helloworld"
|
||||||
```
|
```
|
||||||
|
|
||||||
Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure.
|
Please refer to the [Key Value storage structure](/user-guide/kv-config/#key-value-storage-structure) section to get documentation on traefik KV structure.
|
||||||
|
|
|
@ -225,6 +225,7 @@ And there, the same dynamic configuration in a KV Store (using `prefix = "traefi
|
||||||
| `/traefik/backends/backend1/servers/server1/weight` | `10` |
|
| `/traefik/backends/backend1/servers/server1/weight` | `10` |
|
||||||
| `/traefik/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
|
| `/traefik/backends/backend1/servers/server2/url` | `http://172.17.0.3:80` |
|
||||||
| `/traefik/backends/backend1/servers/server2/weight` | `1` |
|
| `/traefik/backends/backend1/servers/server2/weight` | `1` |
|
||||||
|
| `/traefik/backends/backend1/servers/server2/tags` | `api,helloworld` |
|
||||||
|
|
||||||
- backend 2
|
- backend 2
|
||||||
|
|
||||||
|
@ -237,6 +238,7 @@ And there, the same dynamic configuration in a KV Store (using `prefix = "traefi
|
||||||
| `/traefik/backends/backend2/servers/server1/weight` | `1` |
|
| `/traefik/backends/backend2/servers/server1/weight` | `1` |
|
||||||
| `/traefik/backends/backend2/servers/server2/url` | `http://172.17.0.5:80` |
|
| `/traefik/backends/backend2/servers/server2/url` | `http://172.17.0.5:80` |
|
||||||
| `/traefik/backends/backend2/servers/server2/weight` | `2` |
|
| `/traefik/backends/backend2/servers/server2/weight` | `2` |
|
||||||
|
| `/traefik/backends/backend2/servers/server2/tags` | `web` |
|
||||||
|
|
||||||
- frontend 1
|
- frontend 1
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,7 @@ func (provider *Kv) watchKv(configurationChan chan<- types.ConfigMessage, prefix
|
||||||
}
|
}
|
||||||
|
|
||||||
func (provider *Kv) provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
|
func (provider *Kv) provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error {
|
||||||
|
provider.Constraints = append(provider.Constraints, constraints...)
|
||||||
operation := func() error {
|
operation := func() error {
|
||||||
if _, err := provider.kvclient.Exists("qmslkjdfmqlskdjfmqlksjazçueznbvbwzlkajzebvkwjdcqmlsfj"); err != nil {
|
if _, err := provider.kvclient.Exists("qmslkjdfmqlskdjfmqlksjazçueznbvbwzlkajzebvkwjdcqmlsfj"); err != nil {
|
||||||
return fmt.Errorf("Failed to test KV store connection: %v", err)
|
return fmt.Errorf("Failed to test KV store connection: %v", err)
|
||||||
|
@ -119,17 +120,26 @@ func (provider *Kv) loadConfig() *types.Configuration {
|
||||||
// Allow `/traefik/alias` to superesede `provider.Prefix`
|
// Allow `/traefik/alias` to superesede `provider.Prefix`
|
||||||
strings.TrimSuffix(provider.get(provider.Prefix, provider.Prefix+"/alias"), "/"),
|
strings.TrimSuffix(provider.get(provider.Prefix, provider.Prefix+"/alias"), "/"),
|
||||||
}
|
}
|
||||||
|
|
||||||
var KvFuncMap = template.FuncMap{
|
var KvFuncMap = template.FuncMap{
|
||||||
"List": provider.list,
|
"List": provider.list,
|
||||||
"Get": provider.get,
|
"ListServers": provider.listServers,
|
||||||
"SplitGet": provider.splitGet,
|
"Get": provider.get,
|
||||||
"Last": provider.last,
|
"SplitGet": provider.splitGet,
|
||||||
|
"Last": provider.last,
|
||||||
}
|
}
|
||||||
|
|
||||||
configuration, err := provider.getConfiguration("templates/kv.tmpl", KvFuncMap, templateObjects)
|
configuration, err := provider.getConfiguration("templates/kv.tmpl", KvFuncMap, templateObjects)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for key, frontend := range configuration.Frontends {
|
||||||
|
if _, ok := configuration.Backends[frontend.Backend]; ok == false {
|
||||||
|
delete(configuration.Frontends, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return configuration
|
return configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,6 +158,13 @@ func (provider *Kv) list(keys ...string) []string {
|
||||||
return fun.Values(directoryKeys).([]string)
|
return fun.Values(directoryKeys).([]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (provider *Kv) listServers(backend string) []string {
|
||||||
|
serverNames := provider.list(backend, "/servers/")
|
||||||
|
return fun.Filter(func(serverName string) bool {
|
||||||
|
return provider.checkConstraints(serverName, "/tags")
|
||||||
|
}, serverNames).([]string)
|
||||||
|
}
|
||||||
|
|
||||||
func (provider *Kv) get(defaultValue string, keys ...string) string {
|
func (provider *Kv) get(defaultValue string, keys ...string) string {
|
||||||
joinedKeys := strings.Join(keys, "")
|
joinedKeys := strings.Join(keys, "")
|
||||||
keyPair, err := provider.kvclient.Get(strings.TrimPrefix(joinedKeys, "/"))
|
keyPair, err := provider.kvclient.Get(strings.TrimPrefix(joinedKeys, "/"))
|
||||||
|
@ -178,3 +195,23 @@ func (provider *Kv) last(key string) string {
|
||||||
splittedKey := strings.Split(key, "/")
|
splittedKey := strings.Split(key, "/")
|
||||||
return splittedKey[len(splittedKey)-1]
|
return splittedKey[len(splittedKey)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (provider *Kv) checkConstraints(keys ...string) bool {
|
||||||
|
joinedKeys := strings.Join(keys, "")
|
||||||
|
keyPair, err := provider.kvclient.Get(joinedKeys)
|
||||||
|
|
||||||
|
value := ""
|
||||||
|
if err == nil && keyPair != nil && keyPair.Value != nil {
|
||||||
|
value = string(keyPair.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
constraintTags := strings.Split(value, ",")
|
||||||
|
ok, failingConstraint := provider.MatchConstraints(constraintTags)
|
||||||
|
if ok == false {
|
||||||
|
if failingConstraint != nil {
|
||||||
|
log.Debugf("Constraint %v not matching with following tags: %v", failingConstraint.String(), value)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
[backends]{{range $backends}}
|
[backends]{{range $backends}}
|
||||||
{{$backend := .}}
|
{{$backend := .}}
|
||||||
{{$servers := List $backend "/servers/" }}
|
{{$servers := ListServers $backend }}
|
||||||
|
|
||||||
{{$circuitBreaker := Get "" . "/circuitbreaker/" "expression"}}
|
{{$circuitBreaker := Get "" . "/circuitbreaker/" "expression"}}
|
||||||
{{with $circuitBreaker}}
|
{{with $circuitBreaker}}
|
||||||
|
|
Loading…
Reference in a new issue