Fix contraint store/read from KV

Signed-off-by: Emile Vauge <emile@vauge.com>
This commit is contained in:
Emile Vauge 2016-11-09 19:27:04 +01:00
parent 00c7e5c72b
commit c9cc3c9895
No known key found for this signature in database
GPG key ID: D808B4C167352E59
19 changed files with 58 additions and 41 deletions

View file

@ -329,54 +329,54 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration {
defaultMarathon.Watch = true defaultMarathon.Watch = true
defaultMarathon.Endpoint = "http://127.0.0.1:8080" defaultMarathon.Endpoint = "http://127.0.0.1:8080"
defaultMarathon.ExposedByDefault = true defaultMarathon.ExposedByDefault = true
defaultMarathon.Constraints = []types.Constraint{} defaultMarathon.Constraints = types.Constraints{}
// default Consul // default Consul
var defaultConsul provider.Consul var defaultConsul provider.Consul
defaultConsul.Watch = true defaultConsul.Watch = true
defaultConsul.Endpoint = "127.0.0.1:8500" defaultConsul.Endpoint = "127.0.0.1:8500"
defaultConsul.Prefix = "traefik" defaultConsul.Prefix = "traefik"
defaultConsul.Constraints = []types.Constraint{} defaultConsul.Constraints = types.Constraints{}
// default ConsulCatalog // default ConsulCatalog
var defaultConsulCatalog provider.ConsulCatalog var defaultConsulCatalog provider.ConsulCatalog
defaultConsulCatalog.Endpoint = "127.0.0.1:8500" defaultConsulCatalog.Endpoint = "127.0.0.1:8500"
defaultConsulCatalog.Constraints = []types.Constraint{} defaultConsulCatalog.Constraints = types.Constraints{}
// default Etcd // default Etcd
var defaultEtcd provider.Etcd var defaultEtcd provider.Etcd
defaultEtcd.Watch = true defaultEtcd.Watch = true
defaultEtcd.Endpoint = "127.0.0.1:2379" defaultEtcd.Endpoint = "127.0.0.1:2379"
defaultEtcd.Prefix = "/traefik" defaultEtcd.Prefix = "/traefik"
defaultEtcd.Constraints = []types.Constraint{} defaultEtcd.Constraints = types.Constraints{}
//default Zookeeper //default Zookeeper
var defaultZookeeper provider.Zookepper var defaultZookeeper provider.Zookepper
defaultZookeeper.Watch = true defaultZookeeper.Watch = true
defaultZookeeper.Endpoint = "127.0.0.1:2181" defaultZookeeper.Endpoint = "127.0.0.1:2181"
defaultZookeeper.Prefix = "/traefik" defaultZookeeper.Prefix = "/traefik"
defaultZookeeper.Constraints = []types.Constraint{} defaultZookeeper.Constraints = types.Constraints{}
//default Boltdb //default Boltdb
var defaultBoltDb provider.BoltDb var defaultBoltDb provider.BoltDb
defaultBoltDb.Watch = true defaultBoltDb.Watch = true
defaultBoltDb.Endpoint = "127.0.0.1:4001" defaultBoltDb.Endpoint = "127.0.0.1:4001"
defaultBoltDb.Prefix = "/traefik" defaultBoltDb.Prefix = "/traefik"
defaultBoltDb.Constraints = []types.Constraint{} defaultBoltDb.Constraints = types.Constraints{}
//default Kubernetes //default Kubernetes
var defaultKubernetes provider.Kubernetes var defaultKubernetes provider.Kubernetes
defaultKubernetes.Watch = true defaultKubernetes.Watch = true
defaultKubernetes.Endpoint = "" defaultKubernetes.Endpoint = ""
defaultKubernetes.LabelSelector = "" defaultKubernetes.LabelSelector = ""
defaultKubernetes.Constraints = []types.Constraint{} defaultKubernetes.Constraints = types.Constraints{}
// default Mesos // default Mesos
var defaultMesos provider.Mesos var defaultMesos provider.Mesos
defaultMesos.Watch = true defaultMesos.Watch = true
defaultMesos.Endpoint = "http://127.0.0.1:5050" defaultMesos.Endpoint = "http://127.0.0.1:5050"
defaultMesos.ExposedByDefault = true defaultMesos.ExposedByDefault = true
defaultMesos.Constraints = []types.Constraint{} defaultMesos.Constraints = types.Constraints{}
defaultConfiguration := GlobalConfiguration{ defaultConfiguration := GlobalConfiguration{
Docker: &defaultDocker, Docker: &defaultDocker,
@ -406,7 +406,7 @@ func NewTraefikConfiguration() *TraefikConfiguration {
TraefikLogsFile: "", TraefikLogsFile: "",
LogLevel: "ERROR", LogLevel: "ERROR",
EntryPoints: map[string]*EntryPoint{}, EntryPoints: map[string]*EntryPoint{},
Constraints: []types.Constraint{}, Constraints: types.Constraints{},
DefaultEntryPoints: []string{}, DefaultEntryPoints: []string{},
ProvidersThrottleDuration: time.Duration(2 * time.Second), ProvidersThrottleDuration: time.Duration(2 * time.Second),
MaxIdleConnsPerHost: 200, MaxIdleConnsPerHost: 200,

8
glide.lock generated
View file

@ -1,5 +1,5 @@
hash: d771fbae9fc9c496859ab384f3f70de11dbdbbb63af7bc4fa208ff6192b33635 hash: 1bbeb842ee639ccc6e2edf8cc13fc2759cb96e3d839a1aec7b7f6af4fb89c8e1
updated: 2016-11-08T09:30:22.184334518+01:00 updated: 2016-11-09T19:24:00.762904389+01:00
imports: imports:
- name: github.com/abbot/go-http-auth - name: github.com/abbot/go-http-auth
version: cb4372376e1e00e9f6ab9ec142e029302c9e7140 version: cb4372376e1e00e9f6ab9ec142e029302c9e7140
@ -24,7 +24,7 @@ imports:
- name: github.com/containous/mux - name: github.com/containous/mux
version: a819b77bba13f0c0cbe36e437bc2e948411b3996 version: a819b77bba13f0c0cbe36e437bc2e948411b3996
- name: github.com/containous/staert - name: github.com/containous/staert
version: 92329254783dc01174f03302d51d7cf2c9ff84cf version: 1e26a71803e428fd933f5f9c8e50a26878f53147
- name: github.com/coreos/etcd - name: github.com/coreos/etcd
version: 1c9e0a0e33051fed6c05c141e6fcbfe5c7f2a899 version: 1c9e0a0e33051fed6c05c141e6fcbfe5c7f2a899
subpackages: subpackages:
@ -277,6 +277,8 @@ imports:
- codec - codec
- name: github.com/unrolled/render - name: github.com/unrolled/render
version: 526faf80cd4b305bb8134abea8d20d5ced74faa6 version: 526faf80cd4b305bb8134abea8d20d5ced74faa6
- name: github.com/urfave/negroni
version: e0e50f7dc431c043cb33f91b09c3419d48b7cff5
- name: github.com/vdemeester/docker-events - name: github.com/vdemeester/docker-events
version: be74d4929ec1ad118df54349fda4b0cba60f849b version: be74d4929ec1ad118df54349fda4b0cba60f849b
- name: github.com/vdemeester/shakers - name: github.com/vdemeester/shakers

View file

@ -6,7 +6,7 @@ import:
- fun - fun
- package: github.com/Sirupsen/logrus - package: github.com/Sirupsen/logrus
- package: github.com/cenk/backoff - package: github.com/cenk/backoff
- package: github.com/codegangsta/negroni - package: github.com/urfave/negroni
- package: github.com/containous/flaeg - package: github.com/containous/flaeg
version: a731c034dda967333efce5f8d276aeff11f8ff87 version: a731c034dda967333efce5f8d276aeff11f8ff87
- package: github.com/vulcand/oxy - package: github.com/vulcand/oxy
@ -21,7 +21,7 @@ import:
- stream - stream
- utils - utils
- package: github.com/containous/staert - package: github.com/containous/staert
version: 92329254783dc01174f03302d51d7cf2c9ff84cf version: 1e26a71803e428fd933f5f9c8e50a26878f53147
- package: github.com/docker/engine-api - package: github.com/docker/engine-api
version: 62043eb79d581a32ea849645277023c550732e52 version: 62043eb79d581a32ea849645277023c550732e52
subpackages: subpackages:

View file

@ -17,7 +17,7 @@ type BoltDb struct {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *BoltDb) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error { func (provider *BoltDb) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
store, err := provider.CreateStore() store, err := provider.CreateStore()
if err != nil { if err != nil {
return fmt.Errorf("Failed to Connect to KV store: %v", err) return fmt.Errorf("Failed to Connect to KV store: %v", err)

View file

@ -17,7 +17,7 @@ type Consul struct {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *Consul) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error { func (provider *Consul) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
store, err := provider.CreateStore() store, err := provider.CreateStore()
if err != nil { if err != nil {
return fmt.Errorf("Failed to Connect to KV store: %v", err) return fmt.Errorf("Failed to Connect to KV store: %v", err)

View file

@ -317,7 +317,7 @@ func (provider *ConsulCatalog) watch(configurationChan chan<- types.ConfigMessag
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *ConsulCatalog) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error { func (provider *ConsulCatalog) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
config := api.DefaultConfig() config := api.DefaultConfig()
config.Address = provider.Endpoint config.Address = provider.Endpoint
client, err := api.NewClient(config) client, err := api.NewClient(config)

View file

@ -114,7 +114,7 @@ func (provider *Docker) createClient() (client.APIClient, error) {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *Docker) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error { func (provider *Docker) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
provider.Constraints = append(provider.Constraints, constraints...) provider.Constraints = append(provider.Constraints, constraints...)
// TODO register this routine in pool, and watch for stop channel // TODO register this routine in pool, and watch for stop channel
safe.Go(func() { safe.Go(func() {

View file

@ -17,7 +17,7 @@ type Etcd struct {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *Etcd) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error { func (provider *Etcd) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
store, err := provider.CreateStore() store, err := provider.CreateStore()
if err != nil { if err != nil {
return fmt.Errorf("Failed to Connect to KV store: %v", err) return fmt.Errorf("Failed to Connect to KV store: %v", err)

View file

@ -21,7 +21,7 @@ type File struct {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *File) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, _ []types.Constraint) error { func (provider *File) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
watcher, err := fsnotify.NewWatcher() watcher, err := fsnotify.NewWatcher()
if err != nil { if err != nil {
log.Error("Error creating file watcher", err) log.Error("Error creating file watcher", err)

View file

@ -94,7 +94,7 @@ func (provider *Kubernetes) createClient() (k8s.Client, error) {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *Kubernetes) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error { func (provider *Kubernetes) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
k8sClient, err := provider.createClient() k8sClient, err := provider.createClient()
if err != nil { if err != nil {
return err return err

View file

@ -83,7 +83,7 @@ func (provider *Kv) watchKv(configurationChan chan<- types.ConfigMessage, prefix
return nil return nil
} }
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.Constraints) error {
provider.Constraints = append(provider.Constraints, constraints...) 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 {

View file

@ -50,7 +50,7 @@ type lightMarathonClient interface {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *Marathon) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error { func (provider *Marathon) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
provider.Constraints = append(provider.Constraints, constraints...) provider.Constraints = append(provider.Constraints, constraints...)
operation := func() error { operation := func() error {
config := marathon.NewDefaultConfig() config := marathon.NewDefaultConfig()

View file

@ -740,7 +740,7 @@ func TestMarathonAppConstraints(t *testing.T) {
MarathonLBCompatibility: c.marathonLBCompatibility, MarathonLBCompatibility: c.marathonLBCompatibility,
} }
constraint, _ := types.NewConstraint("tag==valid") constraint, _ := types.NewConstraint("tag==valid")
provider.Constraints = []types.Constraint{*constraint} provider.Constraints = types.Constraints{constraint}
actual := provider.applicationFilter(c.application, c.filteredTasks) actual := provider.applicationFilter(c.application, c.filteredTasks)
if actual != c.expected { if actual != c.expected {
t.Fatalf("expected %v, got %v: %v", c.expected, actual, c.application) t.Fatalf("expected %v, got %v: %v", c.expected, actual, c.application)
@ -820,7 +820,7 @@ func TestMarathonTaskConstraints(t *testing.T) {
MarathonLBCompatibility: c.marathonLBCompatibility, MarathonLBCompatibility: c.marathonLBCompatibility,
} }
constraint, _ := types.NewConstraint("tag==valid") constraint, _ := types.NewConstraint("tag==valid")
provider.Constraints = []types.Constraint{*constraint} provider.Constraints = types.Constraints{constraint}
apps := new(marathon.Applications) apps := new(marathon.Applications)
apps.Apps = c.applications apps.Apps = c.applications
actual := provider.taskFilter(c.filteredTask, apps, true) actual := provider.taskFilter(c.filteredTask, apps, true)

View file

@ -42,7 +42,7 @@ type Mesos struct {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *Mesos) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error { func (provider *Mesos) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
operation := func() error { operation := func() error {
// initialize logging // initialize logging

View file

@ -23,7 +23,7 @@ import (
type Provider interface { type Provider interface {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error
} }
// BaseProvider should be inherited by providers // BaseProvider should be inherited by providers
@ -44,7 +44,7 @@ func (p *BaseProvider) MatchConstraints(tags []string) (bool, *types.Constraint)
for _, constraint := range p.Constraints { for _, constraint := range p.Constraints {
// xor: if ok and constraint.MustMatch are equal, then no tag is currently matching with the constraint // xor: if ok and constraint.MustMatch are equal, then no tag is currently matching with the constraint
if ok := constraint.MatchConstraintWithAtLeastOneTag(tags); ok != constraint.MustMatch { if ok := constraint.MatchConstraintWithAtLeastOneTag(tags); ok != constraint.MustMatch {
return false, &constraint return false, constraint
} }
} }

View file

@ -230,13 +230,13 @@ func TestNilClientTLS(t *testing.T) {
func TestMatchingConstraints(t *testing.T) { func TestMatchingConstraints(t *testing.T) {
cases := []struct { cases := []struct {
constraints []types.Constraint constraints types.Constraints
tags []string tags []string
expected bool expected bool
}{ }{
// simple test: must match // simple test: must match
{ {
constraints: []types.Constraint{ constraints: types.Constraints{
{ {
Key: "tag", Key: "tag",
MustMatch: true, MustMatch: true,
@ -250,7 +250,7 @@ func TestMatchingConstraints(t *testing.T) {
}, },
// simple test: must match but does not match // simple test: must match but does not match
{ {
constraints: []types.Constraint{ constraints: types.Constraints{
{ {
Key: "tag", Key: "tag",
MustMatch: true, MustMatch: true,
@ -264,7 +264,7 @@ func TestMatchingConstraints(t *testing.T) {
}, },
// simple test: must not match // simple test: must not match
{ {
constraints: []types.Constraint{ constraints: types.Constraints{
{ {
Key: "tag", Key: "tag",
MustMatch: false, MustMatch: false,
@ -278,7 +278,7 @@ func TestMatchingConstraints(t *testing.T) {
}, },
// complex test: globbing // complex test: globbing
{ {
constraints: []types.Constraint{ constraints: types.Constraints{
{ {
Key: "tag", Key: "tag",
MustMatch: true, MustMatch: true,
@ -292,7 +292,7 @@ func TestMatchingConstraints(t *testing.T) {
}, },
// complex test: multiple constraints // complex test: multiple constraints
{ {
constraints: []types.Constraint{ constraints: types.Constraints{
{ {
Key: "tag", Key: "tag",
MustMatch: true, MustMatch: true,

View file

@ -17,7 +17,7 @@ type Zookepper struct {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *Zookepper) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints []types.Constraint) error { func (provider *Zookepper) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
store, err := provider.CreateStore() store, err := provider.CreateStore()
if err != nil { if err != nil {
return fmt.Errorf("Failed to Connect to KV store: %v", err) return fmt.Errorf("Failed to Connect to KV store: %v", err)

View file

@ -1,6 +1,7 @@
package types package types
import ( import (
"encoding"
"errors" "errors"
"fmt" "fmt"
"github.com/docker/libkv/store" "github.com/docker/libkv/store"
@ -141,12 +142,26 @@ func (c *Constraint) String() string {
return c.Key + "!=" + c.Regex return c.Key + "!=" + c.Regex
} }
var _ encoding.TextUnmarshaler = (*Constraint)(nil)
// UnmarshalText define how unmarshal in TOML parsing // UnmarshalText define how unmarshal in TOML parsing
func (c *Constraint) UnmarshalText(text []byte) error { func (c *Constraint) UnmarshalText(text []byte) error {
constraint, err := NewConstraint(string(text)) constraint, err := NewConstraint(string(text))
*c = *constraint if err != nil {
return err return err
} }
c.Key = constraint.Key
c.MustMatch = constraint.MustMatch
c.Regex = constraint.Regex
return nil
}
var _ encoding.TextMarshaler = (*Constraint)(nil)
// MarshalText encodes the receiver into UTF-8-encoded text and returns the result.
func (c *Constraint) MarshalText() (text []byte, err error) {
return []byte(c.String()), nil
}
// MatchConstraintWithAtLeastOneTag tests a constraint for one single service // MatchConstraintWithAtLeastOneTag tests a constraint for one single service
func (c *Constraint) MatchConstraintWithAtLeastOneTag(tags []string) bool { func (c *Constraint) MatchConstraintWithAtLeastOneTag(tags []string) bool {
@ -169,16 +184,16 @@ func (cs *Constraints) Set(str string) error {
if err != nil { if err != nil {
return err return err
} }
*cs = append(*cs, *constraint) *cs = append(*cs, constraint)
} }
return nil return nil
} }
// Constraints holds a Constraint parser // Constraints holds a Constraint parser
type Constraints []Constraint type Constraints []*Constraint
//Get []*Constraint //Get []*Constraint
func (cs *Constraints) Get() interface{} { return []Constraint(*cs) } func (cs *Constraints) Get() interface{} { return []*Constraint(*cs) }
//String returns []*Constraint in string //String returns []*Constraint in string
func (cs *Constraints) String() string { return fmt.Sprintf("%+v", *cs) } func (cs *Constraints) String() string { return fmt.Sprintf("%+v", *cs) }

2
web.go
View file

@ -50,7 +50,7 @@ func goroutines() interface{} {
// Provide allows the provider to provide configurations to traefik // Provide allows the provider to provide configurations to traefik
// using the given configuration channel. // using the given configuration channel.
func (provider *WebProvider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, _ []types.Constraint) error { func (provider *WebProvider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, _ types.Constraints) error {
systemRouter := mux.NewRouter() systemRouter := mux.NewRouter()