diff --git a/docs/content/providers/ecs.md b/docs/content/providers/ecs.md index feb3f6454..ab860c524 100644 --- a/docs/content/providers/ecs.md +++ b/docs/content/providers/ecs.md @@ -13,18 +13,15 @@ Attach labels to your ECS containers and let Traefik do the rest! ```toml tab="File (TOML)" [providers.ecs] - clusters = ["default"] ``` ```yaml tab="File (YAML)" providers: - ecs: - clusters: - - default + ecs: {} ``` ```bash tab="CLI" - --providers.ecs.clusters=default + --providers.ecs=true ``` ## Policy diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index d7486781a..8ecd20175 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -330,6 +330,9 @@ TLS key `--providers.consul.username`: KV Username +`--providers.consulcatalog`: +Enable ConsulCatalog backend with default settings. (Default: ```false```) + `--providers.consulcatalog.cache`: Use local agent caching for catalog reads. (Default: ```false```) @@ -435,6 +438,9 @@ Use the ip address from the bound port, rather than from the inner network. (Def `--providers.docker.watch`: Watch Docker Swarm events. (Default: ```true```) +`--providers.ecs`: +Enable AWS ECS backend with default settings. (Default: ```false```) + `--providers.ecs.accesskeyid`: The AWS credentials access key to use for making requests diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index 885c29111..83c5e8480 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -303,6 +303,9 @@ Terminating status code (Default: ```503```) `TRAEFIK_PROVIDERS_CONSUL`: Enable Consul backend with default settings. (Default: ```false```) +`TRAEFIK_PROVIDERS_CONSULCATALOG`: +Enable ConsulCatalog backend with default settings. (Default: ```false```) + `TRAEFIK_PROVIDERS_CONSULCATALOG_CACHE`: Use local agent caching for catalog reads. (Default: ```false```) @@ -435,6 +438,9 @@ Use the ip address from the bound port, rather than from the inner network. (Def `TRAEFIK_PROVIDERS_DOCKER_WATCH`: Watch Docker Swarm events. (Default: ```true```) +`TRAEFIK_PROVIDERS_ECS`: +Enable AWS ECS backend with default settings. (Default: ```false```) + `TRAEFIK_PROVIDERS_ECS_ACCESSKEYID`: The AWS credentials access key to use for making requests diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go index dca54c219..65505fbee 100644 --- a/pkg/config/static/static_config.go +++ b/pkg/config/static/static_config.go @@ -176,8 +176,8 @@ type Providers struct { KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesCRD,omitempty" toml:"kubernetesCRD,omitempty" yaml:"kubernetesCRD,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Rest *rest.Provider `description:"Enable Rest backend with default settings." json:"rest,omitempty" toml:"rest,omitempty" yaml:"rest,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Rancher *rancher.Provider `description:"Enable Rancher backend with default settings." json:"rancher,omitempty" toml:"rancher,omitempty" yaml:"rancher,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - ConsulCatalog *consulcatalog.Provider `description:"Enable ConsulCatalog backend with default settings." json:"consulCatalog,omitempty" toml:"consulCatalog,omitempty" yaml:"consulCatalog,omitempty" export:"true"` - Ecs *ecs.Provider `description:"Enable AWS ECS backend with default settings." json:"ecs,omitempty" toml:"ecs,omitempty" yaml:"ecs,omitempty" export:"true"` + ConsulCatalog *consulcatalog.Provider `description:"Enable ConsulCatalog backend with default settings." json:"consulCatalog,omitempty" toml:"consulCatalog,omitempty" yaml:"consulCatalog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + Ecs *ecs.Provider `description:"Enable AWS ECS backend with default settings." json:"ecs,omitempty" toml:"ecs,omitempty" yaml:"ecs,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Consul *consul.Provider `description:"Enable Consul backend with default settings." json:"consul,omitempty" toml:"consul,omitempty" yaml:"consul,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Etcd *etcd.Provider `description:"Enable Etcd backend with default settings." json:"etcd,omitempty" toml:"etcd,omitempty" yaml:"etcd,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` diff --git a/pkg/provider/ecs/ecs.go b/pkg/provider/ecs/ecs.go index 8e1b4b089..73bfe47f8 100644 --- a/pkg/provider/ecs/ecs.go +++ b/pkg/provider/ecs/ecs.go @@ -151,35 +151,25 @@ func (p Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.P operation := func() error { awsClient, err := p.createClient(logger) if err != nil { - return err + return fmt.Errorf("unable to create AWS client: %w", err) } - configuration, err := p.loadECSConfig(ctxLog, awsClient) + err = p.loadConfiguration(ctxLog, awsClient, configurationChan) if err != nil { - return err + return fmt.Errorf("failed to get ECS configuration: %w", err) } - configurationChan <- dynamic.Message{ - ProviderName: "ecs", - Configuration: configuration, - } - - reload := time.NewTicker(time.Second * time.Duration(p.RefreshSeconds)) - defer reload.Stop() + ticker := time.NewTicker(time.Second * time.Duration(p.RefreshSeconds)) + defer ticker.Stop() for { select { - case <-reload.C: - configuration, err := p.loadECSConfig(ctxLog, awsClient) + case <-ticker.C: + err = p.loadConfiguration(ctxLog, awsClient, configurationChan) if err != nil { - logger.Errorf("Failed to load ECS configuration, error %s", err) - return err + return fmt.Errorf("failed to refresh ECS configuration: %w", err) } - configurationChan <- dynamic.Message{ - ProviderName: "ecs", - Configuration: configuration, - } case <-routineCtx.Done(): return nil } @@ -198,6 +188,20 @@ func (p Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.P return nil } +func (p *Provider) loadConfiguration(ctx context.Context, client *awsClient, configurationChan chan<- dynamic.Message) error { + instances, err := p.listInstances(ctx, client) + if err != nil { + return err + } + + configurationChan <- dynamic.Message{ + ProviderName: "ecs", + Configuration: p.buildConfiguration(ctx, instances), + } + + return nil +} + // Find all running Provider tasks in a cluster, also collect the task definitions (for docker labels) // and the EC2 instance data. func (p *Provider) listInstances(ctx context.Context, client *awsClient) ([]ecsInstance, error) { @@ -365,15 +369,6 @@ func (p *Provider) listInstances(ctx context.Context, client *awsClient) ([]ecsI return instances, nil } -func (p *Provider) loadECSConfig(ctx context.Context, client *awsClient) (*dynamic.Configuration, error) { - instances, err := p.listInstances(ctx, client) - if err != nil { - return nil, err - } - - return p.buildConfiguration(ctx, instances), nil -} - func (p *Provider) lookupEc2Instances(ctx context.Context, client *awsClient, clusterName *string, ecsDatas map[string]*ecs.Task) (map[string]*ec2.Instance, error) { logger := log.FromContext(ctx) instanceIds := make(map[string]string)