diff --git a/acme/acme.go b/acme/acme.go index 4ec96dd83..bd128a25a 100644 --- a/acme/acme.go +++ b/acme/acme.go @@ -253,7 +253,6 @@ func (a *ACME) CreateLocalConfig(tlsConfig *tls.Config, checkOnDemandDomain func needRegister = true } - log.Infof("buildACMEClient...") a.client, err = a.buildACMEClient(account) if err != nil { return err @@ -271,7 +270,7 @@ func (a *ACME) CreateLocalConfig(tlsConfig *tls.Config, checkOnDemandDomain func // The client has a URL to the current Let's Encrypt Subscriber // Agreement. The user will need to agree to it. - log.Infof("AgreeToTOS...") + log.Debugf("AgreeToTOS...") err = a.client.AgreeToTOS() if err != nil { // Let's Encrypt Subscriber Agreement renew ? @@ -375,11 +374,6 @@ func (a *ACME) renewCertificates() error { account := a.store.Get().(*Account) for _, certificateResource := range account.DomainsCertificate.Certs { if certificateResource.needRenew() { - transaction, object, err := a.store.Begin() - if err != nil { - return err - } - account = object.(*Account) log.Debugf("Renewing certificate %+v", certificateResource.Domains) renewedCert, err := a.client.RenewCertificate(acme.CertificateResource{ Domain: certificateResource.Certificate.Domain, @@ -400,6 +394,11 @@ func (a *ACME) renewCertificates() error { PrivateKey: renewedCert.PrivateKey, Certificate: renewedCert.Certificate, } + transaction, object, err := a.store.Begin() + if err != nil { + return err + } + account = object.(*Account) err = account.DomainsCertificate.renewCertificates(renewedACMECert, certificateResource.Domains) if err != nil { log.Errorf("Error renewing certificate: %v", err) diff --git a/configuration.go b/configuration.go index 2e55a4ec2..cf9e75175 100644 --- a/configuration.go +++ b/configuration.go @@ -329,54 +329,54 @@ func NewTraefikDefaultPointersConfiguration() *TraefikConfiguration { defaultMarathon.Watch = true defaultMarathon.Endpoint = "http://127.0.0.1:8080" defaultMarathon.ExposedByDefault = true - defaultMarathon.Constraints = []types.Constraint{} + defaultMarathon.Constraints = types.Constraints{} // default Consul var defaultConsul provider.Consul defaultConsul.Watch = true defaultConsul.Endpoint = "127.0.0.1:8500" defaultConsul.Prefix = "traefik" - defaultConsul.Constraints = []types.Constraint{} + defaultConsul.Constraints = types.Constraints{} // default ConsulCatalog var defaultConsulCatalog provider.ConsulCatalog defaultConsulCatalog.Endpoint = "127.0.0.1:8500" - defaultConsulCatalog.Constraints = []types.Constraint{} + defaultConsulCatalog.Constraints = types.Constraints{} // default Etcd var defaultEtcd provider.Etcd defaultEtcd.Watch = true defaultEtcd.Endpoint = "127.0.0.1:2379" defaultEtcd.Prefix = "/traefik" - defaultEtcd.Constraints = []types.Constraint{} + defaultEtcd.Constraints = types.Constraints{} //default Zookeeper var defaultZookeeper provider.Zookepper defaultZookeeper.Watch = true defaultZookeeper.Endpoint = "127.0.0.1:2181" defaultZookeeper.Prefix = "/traefik" - defaultZookeeper.Constraints = []types.Constraint{} + defaultZookeeper.Constraints = types.Constraints{} //default Boltdb var defaultBoltDb provider.BoltDb defaultBoltDb.Watch = true defaultBoltDb.Endpoint = "127.0.0.1:4001" defaultBoltDb.Prefix = "/traefik" - defaultBoltDb.Constraints = []types.Constraint{} + defaultBoltDb.Constraints = types.Constraints{} //default Kubernetes var defaultKubernetes provider.Kubernetes defaultKubernetes.Watch = true defaultKubernetes.Endpoint = "" defaultKubernetes.LabelSelector = "" - defaultKubernetes.Constraints = []types.Constraint{} + defaultKubernetes.Constraints = types.Constraints{} // default Mesos var defaultMesos provider.Mesos defaultMesos.Watch = true defaultMesos.Endpoint = "http://127.0.0.1:5050" defaultMesos.ExposedByDefault = true - defaultMesos.Constraints = []types.Constraint{} + defaultMesos.Constraints = types.Constraints{} defaultConfiguration := GlobalConfiguration{ Docker: &defaultDocker, @@ -406,7 +406,7 @@ func NewTraefikConfiguration() *TraefikConfiguration { TraefikLogsFile: "", LogLevel: "ERROR", EntryPoints: map[string]*EntryPoint{}, - Constraints: []types.Constraint{}, + Constraints: types.Constraints{}, DefaultEntryPoints: []string{}, ProvidersThrottleDuration: time.Duration(2 * time.Second), MaxIdleConnsPerHost: 200, diff --git a/glide.lock b/glide.lock index 574af3619..889a70a6d 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: d2bb370ffd3c0b528587581bc77d900c98921c02df581594bf19655968aa9849 -updated: 2016-10-27T15:54:07.397981259+02:00 +hash: 1bbeb842ee639ccc6e2edf8cc13fc2759cb96e3d839a1aec7b7f6af4fb89c8e1 +updated: 2016-11-09T19:24:00.762904389+01:00 imports: - name: github.com/abbot/go-http-auth version: cb4372376e1e00e9f6ab9ec142e029302c9e7140 @@ -24,7 +24,7 @@ imports: - name: github.com/containous/mux version: a819b77bba13f0c0cbe36e437bc2e948411b3996 - name: github.com/containous/staert - version: 92329254783dc01174f03302d51d7cf2c9ff84cf + version: 1e26a71803e428fd933f5f9c8e50a26878f53147 - name: github.com/coreos/etcd version: 1c9e0a0e33051fed6c05c141e6fcbfe5c7f2a899 subpackages: @@ -169,7 +169,7 @@ imports: - name: github.com/golang/glog version: fca8c8854093a154ff1eb580aae10276ad6b1b5f - name: github.com/google/go-github - version: ed33550bbf49ddffcc36e1309d3f58ed0b6c2305 + version: 55263f30529cb06f5b478efc333390b791cfe3b1 subpackages: - github - name: github.com/google/go-querystring @@ -185,7 +185,7 @@ imports: - name: github.com/hashicorp/go-cleanhttp version: ad28ea4487f05916463e2423a55166280e8254b5 - name: github.com/hashicorp/go-version - version: deeb027c13a95d56c7585df3fe29207208c6706e + version: e96d3840402619007766590ecea8dd7af1292276 - name: github.com/hashicorp/serf version: b03bf85930b2349eb04b97c8fac437495296e3e7 subpackages: @@ -277,12 +277,14 @@ imports: - codec - name: github.com/unrolled/render version: 526faf80cd4b305bb8134abea8d20d5ced74faa6 +- name: github.com/urfave/negroni + version: e0e50f7dc431c043cb33f91b09c3419d48b7cff5 - name: github.com/vdemeester/docker-events version: be74d4929ec1ad118df54349fda4b0cba60f849b - name: github.com/vdemeester/shakers version: 24d7f1d6a71aa5d9cbe7390e4afb66b7eef9e1b3 - name: github.com/vulcand/oxy - version: 4298f24d572dc554eb984f2ffdf6bdd54d4bd613 + version: fcc76b52eb8568540a020b7a99e854d9d752b364 repo: https://github.com/containous/oxy.git vcs: git subpackages: diff --git a/glide.yaml b/glide.yaml index 205fdf1eb..613664b57 100644 --- a/glide.yaml +++ b/glide.yaml @@ -6,11 +6,11 @@ import: - fun - package: github.com/Sirupsen/logrus - package: github.com/cenk/backoff -- package: github.com/codegangsta/negroni +- package: github.com/urfave/negroni - package: github.com/containous/flaeg version: a731c034dda967333efce5f8d276aeff11f8ff87 - package: github.com/vulcand/oxy - version: 4298f24d572dc554eb984f2ffdf6bdd54d4bd613 + version: fcc76b52eb8568540a020b7a99e854d9d752b364 repo: https://github.com/containous/oxy.git vcs: git subpackages: @@ -21,7 +21,7 @@ import: - stream - utils - package: github.com/containous/staert - version: 92329254783dc01174f03302d51d7cf2c9ff84cf + version: 1e26a71803e428fd933f5f9c8e50a26878f53147 - package: github.com/docker/engine-api version: 62043eb79d581a32ea849645277023c550732e52 subpackages: diff --git a/provider/boltdb.go b/provider/boltdb.go index 3347fe340..e604fd428 100644 --- a/provider/boltdb.go +++ b/provider/boltdb.go @@ -17,7 +17,7 @@ type BoltDb struct { // Provide allows the provider to provide configurations to traefik // 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() if err != nil { return fmt.Errorf("Failed to Connect to KV store: %v", err) diff --git a/provider/consul.go b/provider/consul.go index 1b628dd4f..9316c513a 100644 --- a/provider/consul.go +++ b/provider/consul.go @@ -17,7 +17,7 @@ type Consul struct { // Provide allows the provider to provide configurations to traefik // 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() if err != nil { return fmt.Errorf("Failed to Connect to KV store: %v", err) diff --git a/provider/consul_catalog.go b/provider/consul_catalog.go index aad2e8ae5..b83da3b1d 100644 --- a/provider/consul_catalog.go +++ b/provider/consul_catalog.go @@ -317,7 +317,7 @@ func (provider *ConsulCatalog) watch(configurationChan chan<- types.ConfigMessag // Provide allows the provider to provide configurations to traefik // 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.Address = provider.Endpoint client, err := api.NewClient(config) diff --git a/provider/docker.go b/provider/docker.go index faff0b6d2..e2b312044 100644 --- a/provider/docker.go +++ b/provider/docker.go @@ -114,7 +114,7 @@ func (provider *Docker) createClient() (client.APIClient, error) { // Provide allows the provider to provide configurations to traefik // 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...) // TODO register this routine in pool, and watch for stop channel safe.Go(func() { diff --git a/provider/etcd.go b/provider/etcd.go index 9c7726baa..7dc49d0aa 100644 --- a/provider/etcd.go +++ b/provider/etcd.go @@ -17,7 +17,7 @@ type Etcd struct { // Provide allows the provider to provide configurations to traefik // 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() if err != nil { return fmt.Errorf("Failed to Connect to KV store: %v", err) diff --git a/provider/file.go b/provider/file.go index aab244a89..c2c513f70 100644 --- a/provider/file.go +++ b/provider/file.go @@ -21,7 +21,7 @@ type File struct { // Provide allows the provider to provide configurations to traefik // 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() if err != nil { log.Error("Error creating file watcher", err) diff --git a/provider/kubernetes.go b/provider/kubernetes.go index 3ca6cd681..b50216636 100644 --- a/provider/kubernetes.go +++ b/provider/kubernetes.go @@ -94,7 +94,7 @@ func (provider *Kubernetes) createClient() (k8s.Client, error) { // Provide allows the provider to provide configurations to traefik // 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() if err != nil { return err diff --git a/provider/kv.go b/provider/kv.go index db8bac553..0e29ec2be 100644 --- a/provider/kv.go +++ b/provider/kv.go @@ -83,7 +83,7 @@ func (provider *Kv) watchKv(configurationChan chan<- types.ConfigMessage, prefix 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...) operation := func() error { if _, err := provider.kvclient.Exists("qmslkjdfmqlskdjfmqlksjazçueznbvbwzlkajzebvkwjdcqmlsfj"); err != nil { diff --git a/provider/marathon.go b/provider/marathon.go index f6cc85563..e2b3b7386 100644 --- a/provider/marathon.go +++ b/provider/marathon.go @@ -50,7 +50,7 @@ type lightMarathonClient interface { // Provide allows the provider to provide configurations to traefik // 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...) operation := func() error { config := marathon.NewDefaultConfig() diff --git a/provider/marathon_test.go b/provider/marathon_test.go index 6ce7c4009..bcc05404e 100644 --- a/provider/marathon_test.go +++ b/provider/marathon_test.go @@ -740,7 +740,7 @@ func TestMarathonAppConstraints(t *testing.T) { MarathonLBCompatibility: c.marathonLBCompatibility, } constraint, _ := types.NewConstraint("tag==valid") - provider.Constraints = []types.Constraint{*constraint} + provider.Constraints = types.Constraints{constraint} actual := provider.applicationFilter(c.application, c.filteredTasks) if actual != c.expected { t.Fatalf("expected %v, got %v: %v", c.expected, actual, c.application) @@ -820,7 +820,7 @@ func TestMarathonTaskConstraints(t *testing.T) { MarathonLBCompatibility: c.marathonLBCompatibility, } constraint, _ := types.NewConstraint("tag==valid") - provider.Constraints = []types.Constraint{*constraint} + provider.Constraints = types.Constraints{constraint} apps := new(marathon.Applications) apps.Apps = c.applications actual := provider.taskFilter(c.filteredTask, apps, true) diff --git a/provider/mesos.go b/provider/mesos.go index a99318249..fab03d422 100644 --- a/provider/mesos.go +++ b/provider/mesos.go @@ -42,7 +42,7 @@ type Mesos struct { // Provide allows the provider to provide configurations to traefik // 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 { // initialize logging diff --git a/provider/provider.go b/provider/provider.go index b2e7d5d09..a7ce0dad4 100644 --- a/provider/provider.go +++ b/provider/provider.go @@ -23,7 +23,7 @@ import ( type Provider interface { // Provide allows the provider to provide configurations to traefik // 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 @@ -44,7 +44,7 @@ func (p *BaseProvider) MatchConstraints(tags []string) (bool, *types.Constraint) for _, constraint := range p.Constraints { // 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 { - return false, &constraint + return false, constraint } } diff --git a/provider/provider_test.go b/provider/provider_test.go index d14d971a1..f7f321989 100644 --- a/provider/provider_test.go +++ b/provider/provider_test.go @@ -230,13 +230,13 @@ func TestNilClientTLS(t *testing.T) { func TestMatchingConstraints(t *testing.T) { cases := []struct { - constraints []types.Constraint + constraints types.Constraints tags []string expected bool }{ // simple test: must match { - constraints: []types.Constraint{ + constraints: types.Constraints{ { Key: "tag", MustMatch: true, @@ -250,7 +250,7 @@ func TestMatchingConstraints(t *testing.T) { }, // simple test: must match but does not match { - constraints: []types.Constraint{ + constraints: types.Constraints{ { Key: "tag", MustMatch: true, @@ -264,7 +264,7 @@ func TestMatchingConstraints(t *testing.T) { }, // simple test: must not match { - constraints: []types.Constraint{ + constraints: types.Constraints{ { Key: "tag", MustMatch: false, @@ -278,7 +278,7 @@ func TestMatchingConstraints(t *testing.T) { }, // complex test: globbing { - constraints: []types.Constraint{ + constraints: types.Constraints{ { Key: "tag", MustMatch: true, @@ -292,7 +292,7 @@ func TestMatchingConstraints(t *testing.T) { }, // complex test: multiple constraints { - constraints: []types.Constraint{ + constraints: types.Constraints{ { Key: "tag", MustMatch: true, diff --git a/provider/zk.go b/provider/zk.go index 19f3654e5..57ce396b3 100644 --- a/provider/zk.go +++ b/provider/zk.go @@ -17,7 +17,7 @@ type Zookepper struct { // Provide allows the provider to provide configurations to traefik // 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() if err != nil { return fmt.Errorf("Failed to Connect to KV store: %v", err) diff --git a/server.go b/server.go index fe7d83142..f3a98c03f 100644 --- a/server.go +++ b/server.go @@ -383,6 +383,9 @@ func (server *Server) createTLSConfig(entryPointName string, tlsOption *TLS, rou return nil, err } + // ensure http2 enabled + config.NextProtos = []string{"h2", "http/1.1"} + if len(tlsOption.ClientCAFiles) > 0 { pool := x509.NewCertPool() for _, caFile := range tlsOption.ClientCAFiles { diff --git a/types/types.go b/types/types.go index a8db1a6e3..15c4694b4 100644 --- a/types/types.go +++ b/types/types.go @@ -1,6 +1,7 @@ package types import ( + "encoding" "errors" "fmt" "github.com/docker/libkv/store" @@ -141,11 +142,25 @@ func (c *Constraint) String() string { return c.Key + "!=" + c.Regex } +var _ encoding.TextUnmarshaler = (*Constraint)(nil) + // UnmarshalText define how unmarshal in TOML parsing func (c *Constraint) UnmarshalText(text []byte) error { constraint, err := NewConstraint(string(text)) - *c = *constraint - return err + if err != nil { + 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 @@ -169,16 +184,16 @@ func (cs *Constraints) Set(str string) error { if err != nil { return err } - *cs = append(*cs, *constraint) + *cs = append(*cs, constraint) } return nil } // Constraints holds a Constraint parser -type Constraints []Constraint +type Constraints []*Constraint //Get []*Constraint -func (cs *Constraints) Get() interface{} { return []Constraint(*cs) } +func (cs *Constraints) Get() interface{} { return []*Constraint(*cs) } //String returns []*Constraint in string func (cs *Constraints) String() string { return fmt.Sprintf("%+v", *cs) } diff --git a/web.go b/web.go index 65a10f392..acfed0916 100644 --- a/web.go +++ b/web.go @@ -50,7 +50,7 @@ func goroutines() interface{} { // Provide allows the provider to provide configurations to traefik // 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()