Skip to content

Commit

Permalink
Create init method on provider interface
Browse files Browse the repository at this point in the history
  • Loading branch information
juliens authored and traefiker committed Jul 11, 2018
1 parent b2a57ca commit 027093a
Show file tree
Hide file tree
Showing 52 changed files with 2,760 additions and 131 deletions.
24 changes: 21 additions & 3 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@

[[constraint]]
name = "github.com/containous/traefik-extra-service-fabric"
version = "1.2.0"
branch = "init-provider"

[[constraint]]
name = "github.com/coreos/go-systemd"
Expand Down
6 changes: 5 additions & 1 deletion cmd/traefik/traefik.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,11 @@ func runCmd(globalConfiguration *configuration.GlobalConfiguration, configFile s

acmeprovider := globalConfiguration.InitACMEProvider()
if acmeprovider != nil {
providerAggregator.AddProvider(acmeprovider)
err := providerAggregator.AddProvider(acmeprovider)
if err != nil {
log.Errorf("Error initializing provider ACME: %v", err)
acmeprovider = nil
}
}

entryPoints := map[string]server.EntryPoint{}
Expand Down
70 changes: 44 additions & 26 deletions configuration/provider_aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package configuration

import (
"encoding/json"
"reflect"

"github.com/containous/traefik/log"
"github.com/containous/traefik/provider"
Expand All @@ -12,82 +11,101 @@ import (

// ProviderAggregator aggregate providers
type ProviderAggregator struct {
providers []provider.Provider
providers []provider.Provider
constraints types.Constraints
}

// NewProviderAggregator return an aggregate of all the providers configured in GlobalConfiguration
func NewProviderAggregator(gc *GlobalConfiguration) ProviderAggregator {
provider := ProviderAggregator{}
provider := ProviderAggregator{
constraints: gc.Constraints,
}
if gc.Docker != nil {
provider.providers = append(provider.providers, gc.Docker)
provider.quietAddProvider(gc.Docker)
}
if gc.Marathon != nil {
provider.providers = append(provider.providers, gc.Marathon)
provider.quietAddProvider(gc.Marathon)
}
if gc.File != nil {
provider.providers = append(provider.providers, gc.File)
provider.quietAddProvider(gc.File)
}
if gc.Rest != nil {
provider.providers = append(provider.providers, gc.Rest)
provider.quietAddProvider(gc.Rest)
}
if gc.Consul != nil {
provider.providers = append(provider.providers, gc.Consul)
provider.quietAddProvider(gc.Consul)
}
if gc.ConsulCatalog != nil {
provider.providers = append(provider.providers, gc.ConsulCatalog)
provider.quietAddProvider(gc.ConsulCatalog)
}
if gc.Etcd != nil {
provider.providers = append(provider.providers, gc.Etcd)
provider.quietAddProvider(gc.Etcd)
}
if gc.Zookeeper != nil {
provider.providers = append(provider.providers, gc.Zookeeper)
provider.quietAddProvider(gc.Zookeeper)
}
if gc.Boltdb != nil {
provider.providers = append(provider.providers, gc.Boltdb)
provider.quietAddProvider(gc.Boltdb)
}
if gc.Kubernetes != nil {
provider.providers = append(provider.providers, gc.Kubernetes)
provider.quietAddProvider(gc.Kubernetes)
}
if gc.Mesos != nil {
provider.providers = append(provider.providers, gc.Mesos)
provider.quietAddProvider(gc.Mesos)
}
if gc.Eureka != nil {
provider.providers = append(provider.providers, gc.Eureka)
provider.quietAddProvider(gc.Eureka)
}
if gc.ECS != nil {
provider.providers = append(provider.providers, gc.ECS)
provider.quietAddProvider(gc.ECS)
}
if gc.Rancher != nil {
provider.providers = append(provider.providers, gc.Rancher)
provider.quietAddProvider(gc.Rancher)
}
if gc.DynamoDB != nil {
provider.providers = append(provider.providers, gc.DynamoDB)
provider.quietAddProvider(gc.DynamoDB)
}
if gc.ServiceFabric != nil {
provider.providers = append(provider.providers, gc.ServiceFabric)
provider.quietAddProvider(gc.ServiceFabric)
}
return provider
}

func (p *ProviderAggregator) quietAddProvider(provider provider.Provider) {
err := p.AddProvider(provider)
if err != nil {
log.Errorf("Error initializing provider %T: %v", provider, err)
}
}

// AddProvider add a provider in the providers map
func (p *ProviderAggregator) AddProvider(provider provider.Provider) {
func (p *ProviderAggregator) AddProvider(provider provider.Provider) error {
err := provider.Init(p.constraints)
if err != nil {
return err
}
p.providers = append(p.providers, provider)
return nil
}

// Init the provider
func (p ProviderAggregator) Init(_ types.Constraints) error {
return nil
}

// Provide call the provide method of every providers
func (p ProviderAggregator) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
func (p ProviderAggregator) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool) error {
for _, p := range p.providers {
providerType := reflect.TypeOf(p)
jsonConf, err := json.Marshal(p)
if err != nil {
log.Debugf("Unable to marshal provider conf %v with error: %v", providerType, err)
log.Debugf("Unable to marshal provider conf %T with error: %v", p, err)
}
log.Infof("Starting provider %v %s", providerType, jsonConf)
log.Infof("Starting provider %T %s", p, jsonConf)
currentProvider := p
safe.Go(func() {
err := currentProvider.Provide(configurationChan, pool, constraints)
err := currentProvider.Provide(configurationChan, pool)
if err != nil {
log.Errorf("Error starting provider %v: %s", providerType, err)
log.Errorf("Error starting provider %T: %v", p, err)
}
})
}
Expand Down
75 changes: 36 additions & 39 deletions provider/acme/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,45 @@ func (p *Provider) ListenRequest(domain string) (*tls.Certificate, error) {
return &certificate, err
}

// Init for compatibility reason the BaseProvider implements an empty Init
func (p *Provider) Init(_ types.Constraints) error {
acme.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
if p.ACMELogging {
legolog.Logger = fmtlog.New(log.WriterLevel(logrus.InfoLevel), "legolog: ", 0)
} else {
legolog.Logger = fmtlog.New(ioutil.Discard, "", 0)
}

if p.Store == nil {
return errors.New("no store found for the ACME provider")
}

var err error
p.account, err = p.Store.GetAccount()
if err != nil {
return fmt.Errorf("unable to get ACME account : %v", err)
}

// Reset Account if caServer changed, thus registration URI can be updated
if p.account != nil && p.account.Registration != nil && !strings.HasPrefix(p.account.Registration.URI, p.CAServer) {
p.account = nil
}

p.certificates, err = p.Store.GetCertificates()
if err != nil {
return fmt.Errorf("unable to get ACME certificates : %v", err)
}

return nil
}

// Provide allows the file provider to provide configurations to traefik
// using the given Configuration channel.
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool) error {
p.pool = pool
err := p.init()
if err != nil {
return err
}

p.watchCertificate()
p.watchNewDomains()

p.configurationChan = configurationChan
p.refreshCertificates()
Expand Down Expand Up @@ -150,40 +181,6 @@ func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *s
return nil
}

func (p *Provider) init() error {
acme.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
if p.ACMELogging {
legolog.Logger = fmtlog.New(log.WriterLevel(logrus.InfoLevel), "legolog: ", 0)
} else {
legolog.Logger = fmtlog.New(ioutil.Discard, "", 0)
}

if p.Store == nil {
return errors.New("no store found for the ACME provider")
}

var err error
p.account, err = p.Store.GetAccount()
if err != nil {
return fmt.Errorf("unable to get ACME account : %v", err)
}

// Reset Account if caServer changed, thus registration URI can be updated
if p.account != nil && p.account.Registration != nil && !strings.HasPrefix(p.account.Registration.URI, p.CAServer) {
p.account = nil
}

p.certificates, err = p.Store.GetCertificates()
if err != nil {
return fmt.Errorf("unable to get ACME certificates : %v", err)
}

p.watchCertificate()
p.watchNewDomains()

return nil
}

func (p *Provider) getClient() (*acme.Client, error) {
p.clientMutex.Lock()
defer p.clientMutex.Unlock()
Expand Down
19 changes: 15 additions & 4 deletions provider/boltdb/boltdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,26 @@ type Provider struct {
kv.Provider `mapstructure:",squash" export:"true"`
}

// Provide allows the boltdb provider to Provide configurations to traefik
// using the given configuration channel.
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
// Init the provider
func (p *Provider) Init(constraints types.Constraints) error {
err := p.Provider.Init(constraints)
if err != nil {
return err
}

store, err := p.CreateStore()
if err != nil {
return fmt.Errorf("failed to Connect to KV store: %v", err)
}

p.SetKVClient(store)
return p.Provider.Provide(configurationChan, pool, constraints)
return nil
}

// Provide allows the boltdb provider to Provide configurations to traefik
// using the given configuration channel.
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool) error {
return p.Provider.Provide(configurationChan, pool)
}

// CreateStore creates the KV store
Expand Down
19 changes: 15 additions & 4 deletions provider/consul/consul.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,26 @@ type Provider struct {
kv.Provider `mapstructure:",squash" export:"true"`
}

// Provide allows the consul provider to provide configurations to traefik
// using the given configuration channel.
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
// Init the provider
func (p *Provider) Init(constraints types.Constraints) error {
err := p.Provider.Init(constraints)
if err != nil {
return err
}

store, err := p.CreateStore()
if err != nil {
return fmt.Errorf("failed to Connect to KV store: %v", err)
}

p.SetKVClient(store)
return p.Provider.Provide(configurationChan, pool, constraints)
return nil
}

// Provide allows the consul provider to provide configurations to traefik
// using the given configuration channel.
func (p *Provider) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool) error {
return p.Provider.Provide(configurationChan, pool)
}

// CreateStore creates the KV store
Expand Down

0 comments on commit 027093a

Please sign in to comment.