diff --git a/docs/content/providers/consul-catalog.md b/docs/content/providers/consul-catalog.md index 0a8486b9e..c5fb286b0 100644 --- a/docs/content/providers/consul-catalog.md +++ b/docs/content/providers/consul-catalog.md @@ -39,65 +39,6 @@ See the dedicated section in [routing](../routing/providers/consul-catalog.md). ## Provider Configuration -### `exposedByDefault` - -_Optional, Default=true_ - -```toml tab="File (TOML)" -[providers.consulCatalog] - exposedByDefault = false - # ... -``` - -```yaml tab="File (YAML)" -providers: - consulCatalog: - exposedByDefault: false - # ... -``` - -```bash tab="CLI" ---providers.consulcatalog.exposedByDefault=false -# ... -``` - -Expose Consul Catalog services by default in Traefik. -If set to false, services that don't have a `traefik.enable=true` label will be ignored from the resulting routing configuration. - -See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). - -### `defaultRule` - -_Optional, Default=```Host(`{{ normalize .Name }}`)```_ - -```toml tab="File (TOML)" -[providers.consulCatalog] - defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" - # ... -``` - -```yaml tab="File (YAML)" -providers: - consulCatalog: - defaultRule: "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" - # ... -``` - -```bash tab="CLI" ---providers.consulcatalog.defaultRule="Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" -# ... -``` - -The default host rule for all services. - -For a given container if no routing rule was defined by a label, it is defined by this defaultRule instead. -It must be a valid [Go template](https://golang.org/pkg/text/template/), -augmented with the [sprig template functions](http://masterminds.github.io/sprig/). -The service name can be accessed as the `Name` identifier, -and the template has access to all the labels defined on this container. - -This option can be overridden on a container basis with the `traefik.http.routers.Router1.rule` label. - ### `refreshInterval` _Optional, Default=15s_ @@ -135,78 +76,88 @@ _Optional, Default=/latest_ ```yaml tab="File (YAML)" providers: consulCatalog: - prefix: "/test" + prefix: /test # ... ``` ```bash tab="CLI" ---providers.consulcatalog.prefix="/test" +--providers.consulcatalog.prefix=/test # ... ``` Prefix used for accessing the Consul service metadata. -### `constraints` +### `requireConsistent` -_Optional, Default=""_ +_Optional, Default=false_ ```toml tab="File (TOML)" [providers.consulCatalog] - constraints = "Label(`a.label.name`, `foo`)" + requireConsistent = true # ... ``` ```yaml tab="File (YAML)" providers: consulCatalog: - constraints: "Label(`a.label.name`, `foo`)" + requireConsistent: true # ... ``` ```bash tab="CLI" ---providers.consulcatalog.constraints="Label(`a.label.name`, `foo`)" +--providers.consulcatalog.requireConsistent=true # ... ``` -Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container. -That is to say, if none of the container's labels match the expression, no route for the container is created. -If the expression is empty, all detected containers are included. +Forces the read to be fully consistent. -The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions, as well as the usual boolean logic, as shown in examples below. +### `stale` -??? example "Constraints Expression Examples" +_Optional, Default=false_ - ```toml - # Includes only containers having a label with key `a.label.name` and value `foo` - constraints = "Label(`a.label.name`, `foo`)" - ``` - - ```toml - # Excludes containers having any label with key `a.label.name` and value `foo` - constraints = "!Label(`a.label.name`, `value`)" - ``` - - ```toml - # With logical AND. - constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)" - ``` - - ```toml - # With logical OR. - constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)" - ``` - - ```toml - # With logical AND and OR, with precedence set by parentheses. - constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))" - ``` - - ```toml - # Includes only containers having a label with key `a.label.name` and a value matching the `a.+` regular expression. - constraints = "LabelRegex(`a.label.name`, `a.+`)" - ``` +```toml tab="File (TOML)" +[providers.consulCatalog] + stale = true + # ... +``` -See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). +```yaml tab="File (YAML)" +providers: + consulCatalog: + stale: true + # ... +``` + +```bash tab="CLI" +--providers.consulcatalog.stale=true +# ... +``` + +Use stale consistency for catalog reads. + +### `cache` + +_Optional, Default=false_ + +```toml tab="File (TOML)" +[providers.consulCatalog] + cache = true + # ... +``` + +```yaml tab="File (YAML)" +providers: + consulCatalog: + cache: true + # ... +``` + +```bash tab="CLI" +--providers.consulcatalog.cache=true +# ... +``` + +Use local agent caching for catalog reads. ### `endpoint` @@ -529,3 +480,124 @@ providers: ``` If `insecureSkipVerify` is `true`, TLS for the connection to Consul server accepts any certificate presented by the server and any host name in that certificate. + +### `exposedByDefault` + +_Optional, Default=true_ + +```toml tab="File (TOML)" +[providers.consulCatalog] + exposedByDefault = false + # ... +``` + +```yaml tab="File (YAML)" +providers: + consulCatalog: + exposedByDefault: false + # ... +``` + +```bash tab="CLI" +--providers.consulcatalog.exposedByDefault=false +# ... +``` + +Expose Consul Catalog services by default in Traefik. +If set to false, services that don't have a `traefik.enable=true` label will be ignored from the resulting routing configuration. + +See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). + +### `defaultRule` + +_Optional, Default=```Host(`{{ normalize .Name }}`)```_ + +```toml tab="File (TOML)" +[providers.consulCatalog] + defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" + # ... +``` + +```yaml tab="File (YAML)" +providers: + consulCatalog: + defaultRule: "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" + # ... +``` + +```bash tab="CLI" +--providers.consulcatalog.defaultRule="Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" +# ... +``` + +The default host rule for all services. + +For a given container if no routing rule was defined by a label, it is defined by this defaultRule instead. +It must be a valid [Go template](https://golang.org/pkg/text/template/), +augmented with the [sprig template functions](http://masterminds.github.io/sprig/). +The service name can be accessed as the `Name` identifier, +and the template has access to all the labels defined on this container. + +This option can be overridden on a container basis with the `traefik.http.routers.Router1.rule` label. + +### `constraints` + +_Optional, Default=""_ + +```toml tab="File (TOML)" +[providers.consulCatalog] + constraints = "Label(`a.label.name`, `foo`)" + # ... +``` + +```yaml tab="File (YAML)" +providers: + consulCatalog: + constraints: "Label(`a.label.name`, `foo`)" + # ... +``` + +```bash tab="CLI" +--providers.consulcatalog.constraints="Label(`a.label.name`, `foo`)" +# ... +``` + +Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container. +That is to say, if none of the container's labels match the expression, no route for the container is created. +If the expression is empty, all detected containers are included. + +The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions, as well as the usual boolean logic, as shown in examples below. + +??? example "Constraints Expression Examples" + + ```toml + # Includes only containers having a label with key `a.label.name` and value `foo` + constraints = "Label(`a.label.name`, `foo`)" + ``` + + ```toml + # Excludes containers having any label with key `a.label.name` and value `foo` + constraints = "!Label(`a.label.name`, `value`)" + ``` + + ```toml + # With logical AND. + constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)" + ``` + + ```toml + # With logical OR. + constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)" + ``` + + ```toml + # With logical AND and OR, with precedence set by parentheses. + constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))" + ``` + + ```toml + # Includes only containers having a label with key `a.label.name` and a value matching the `a.+` regular expression. + constraints = "LabelRegex(`a.label.name`, `a.+`)" + ``` + +See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index f7456553c..ed6c70a6e 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -234,6 +234,9 @@ Enable ping. (Default: ```false```) `--ping.entrypoint`: EntryPoint (Default: ```traefik```) +`--providers.consulcatalog.cache`: +Use local agent caching for catalog reads. (Default: ```false```) + `--providers.consulcatalog.constraints`: Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container. @@ -285,6 +288,12 @@ Prefix for consul service tags. Default 'traefik' (Default: ```traefik```) `--providers.consulcatalog.refreshinterval`: Interval for check Consul API. Default 100ms (Default: ```15```) +`--providers.consulcatalog.requireconsistent`: +Forces the read to be fully consistent. (Default: ```false```) + +`--providers.consulcatalog.stale`: +Use stale consistency for catalog reads. (Default: ```false```) + `--providers.docker`: Enable Docker backend with default settings. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index 91d8dcca5..115540ec6 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -234,6 +234,9 @@ Enable ping. (Default: ```false```) `TRAEFIK_PING_ENTRYPOINT`: EntryPoint (Default: ```traefik```) +`TRAEFIK_PROVIDERS_CONSULCATALOG_CACHE`: +Use local agent caching for catalog reads. (Default: ```false```) + `TRAEFIK_PROVIDERS_CONSULCATALOG_CONSTRAINTS`: Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container. @@ -285,6 +288,12 @@ Prefix for consul service tags. Default 'traefik' (Default: ```traefik```) `TRAEFIK_PROVIDERS_CONSULCATALOG_REFRESHINTERVAL`: Interval for check Consul API. Default 100ms (Default: ```15```) +`TRAEFIK_PROVIDERS_CONSULCATALOG_REQUIRECONSISTENT`: +Forces the read to be fully consistent. (Default: ```false```) + +`TRAEFIK_PROVIDERS_CONSULCATALOG_STALE`: +Use stale consistency for catalog reads. (Default: ```false```) + `TRAEFIK_PROVIDERS_DOCKER`: Enable Docker backend with default settings. (Default: ```false```) diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index 7a2f4e0e4..f409dffcb 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -114,6 +114,9 @@ defaultRule = "foobar" exposedByDefault = true refreshInterval = 15 + requireConsistent = true + stale = true + cache = true [providers.consulCatalog.endpoint] address = "foobar" scheme = "foobar" diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml index 5b9d5f5bc..23d813ac8 100644 --- a/docs/content/reference/static-configuration/file.yaml +++ b/docs/content/reference/static-configuration/file.yaml @@ -121,6 +121,9 @@ providers: defaultRule: foobar exposedByDefault: true refreshInterval: 15 + requireConsistent: true + stale: true + cache: true endpoint: address: foobar scheme: foobar diff --git a/pkg/provider/consulcatalog/consul_catalog.go b/pkg/provider/consulcatalog/consul_catalog.go index 255d4116f..a0a9cdb9c 100644 --- a/pkg/provider/consulcatalog/consul_catalog.go +++ b/pkg/provider/consulcatalog/consul_catalog.go @@ -34,12 +34,15 @@ type itemData struct { // Provider holds configurations of the provider. type Provider struct { - Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` - Endpoint *EndpointConfig `description:"Consul endpoint settings" json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty" export:"true"` - Prefix string `description:"Prefix for consul service tags. Default 'traefik'" json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty" export:"true"` - RefreshInterval types.Duration `description:"Interval for check Consul API. Default 100ms" json:"refreshInterval,omitempty" toml:"refreshInterval,omitempty" yaml:"refreshInterval,omitempty" export:"true"` - ExposedByDefault bool `description:"Expose containers by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` - DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` + Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` + Endpoint *EndpointConfig `description:"Consul endpoint settings" json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty" export:"true"` + Prefix string `description:"Prefix for consul service tags. Default 'traefik'" json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty" export:"true"` + RefreshInterval types.Duration `description:"Interval for check Consul API. Default 100ms" json:"refreshInterval,omitempty" toml:"refreshInterval,omitempty" yaml:"refreshInterval,omitempty" export:"true"` + RequireConsistent bool `description:"Forces the read to be fully consistent." json:"requireConsistent,omitempty" toml:"requireConsistent,omitempty" yaml:"requireConsistent,omitempty" export:"true"` + Stale bool `description:"Use stale consistency for catalog reads." json:"stale,omitempty" toml:"stale,omitempty" yaml:"stale,omitempty" export:"true"` + Cache bool `description:"Use local agent caching for catalog reads." json:"cache,omitempty" toml:"cache,omitempty" yaml:"cache,omitempty" export:"true"` + ExposedByDefault bool `description:"Expose containers by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` + DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` client *api.Client defaultRuleTpl *template.Template @@ -110,7 +113,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe. case <-ticker.C: data, err := p.getConsulServicesData(routineCtx) if err != nil { - logger.Errorf("error get consulCatalog data, %v", err) + logger.Errorf("error get consul catalog data, %v", err) return err } @@ -132,7 +135,7 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe. err := backoff.RetryNotify(safe.OperationWithRecover(operation), backoff.WithContext(job.NewBackOff(backoff.NewExponentialBackOff()), ctxLog), notify) if err != nil { - logger.Errorf("Cannot connect to consulcatalog server %+v", err) + logger.Errorf("Cannot connect to consul catalog server %+v", err) } }) @@ -182,12 +185,14 @@ func (p *Provider) fetchService(ctx context.Context, name string) ([]*api.Catalo tagFilter = p.Prefix + ".enable=true" } - consulServices, _, err := p.client.Catalog().Service(name, tagFilter, &api.QueryOptions{}) + opts := &api.QueryOptions{AllowStale: p.Stale, RequireConsistent: p.RequireConsistent, UseCache: p.Cache} + consulServices, _, err := p.client.Catalog().Service(name, tagFilter, opts) return consulServices, err } func (p *Provider) fetchServices(ctx context.Context) (map[string][]string, error) { - serviceNames, _, err := p.client.Catalog().Services(&api.QueryOptions{}) + opts := &api.QueryOptions{AllowStale: p.Stale, RequireConsistent: p.RequireConsistent, UseCache: p.Cache} + serviceNames, _, err := p.client.Catalog().Services(opts) return serviceNames, err }