mirror of
https://github.com/containous/traefik.git
synced 2025-09-15 13:44:21 +03:00
Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1f81260694 | ||
|
cbcd999257 | ||
|
a0724fd1ca | ||
|
3fe9c9ab58 |
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
4
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -3,11 +3,11 @@ PLEASE READ THIS MESSAGE.
|
||||
|
||||
Documentation fixes or enhancements:
|
||||
- for Traefik v1: use branch v1.7
|
||||
- for Traefik v2: use branch v2.1
|
||||
- for Traefik v2: use branch v2.0
|
||||
|
||||
Bug fixes:
|
||||
- for Traefik v1: use branch v1.7
|
||||
- for Traefik v2: use branch v2.1
|
||||
- for Traefik v2: use branch v2.0
|
||||
|
||||
Enhancements:
|
||||
- for Traefik v1: we only accept bug fixes
|
||||
|
@@ -10,7 +10,7 @@ else
|
||||
export VERSION=''
|
||||
fi
|
||||
|
||||
export CODENAME=cantal
|
||||
export CODENAME=montdor
|
||||
|
||||
export N_MAKE_JOBS=2
|
||||
|
||||
|
@@ -11,7 +11,7 @@ env:
|
||||
global:
|
||||
- REPO=$TRAVIS_REPO_SLUG
|
||||
- VERSION=$TRAVIS_TAG
|
||||
- CODENAME=cantal
|
||||
- CODENAME=montdor
|
||||
- GO111MODULE=on
|
||||
|
||||
script:
|
||||
|
130
CHANGELOG.md
130
CHANGELOG.md
@@ -1,85 +1,3 @@
|
||||
## [v2.1.2](https://github.com/containous/traefik/tree/v2.1.2) (2020-01-07)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v2.1.1...v2.1.2)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[authentication,middleware,tracing]** fix(tracing): makes sure tracing headers are being propagated when using forwardAuth ([#6072](https://github.com/containous/traefik/pull/6072) by [jcchavezs](https://github.com/jcchavezs))
|
||||
- **[cli]** fix: invalid label/flag parsing. ([#6028](https://github.com/containous/traefik/pull/6028) by [ldez](https://github.com/ldez))
|
||||
- **[consulcatalog]** Query consul catalog for service health separately ([#6046](https://github.com/containous/traefik/pull/6046) by [SantoDE](https://github.com/SantoDE))
|
||||
- **[k8s,k8s/crd]** Restore ExternalName https support for Kubernetes CRD ([#6037](https://github.com/containous/traefik/pull/6037) by [kpeiruza](https://github.com/kpeiruza))
|
||||
- **[k8s,k8s/crd]** Log the ignored namespace only when needed ([#6087](https://github.com/containous/traefik/pull/6087) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
- **[k8s,k8s/ingress]** k8s Ingress: fix crash on rules with nil http ([#6121](https://github.com/containous/traefik/pull/6121) by [grimmy](https://github.com/grimmy))
|
||||
- **[logs]** Improves error message when a configuration file is empty. ([#6135](https://github.com/containous/traefik/pull/6135) by [ldez](https://github.com/ldez))
|
||||
- **[server]** Handle respondingTimeout and better shutdown tests. ([#6115](https://github.com/containous/traefik/pull/6115) by [juliens](https://github.com/juliens))
|
||||
- **[server]** Don't set user-agent to Go-http-client/1.1 ([#6030](https://github.com/containous/traefik/pull/6030) by [sh7dm](https://github.com/sh7dm))
|
||||
- **[tracing]** fix: Malformed x-b3-traceid Header ([#6079](https://github.com/containous/traefik/pull/6079) by [ldez](https://github.com/ldez))
|
||||
- **[webui]** fix: dashboard redirect loop ([#6078](https://github.com/containous/traefik/pull/6078) by [ldez](https://github.com/ldez))
|
||||
|
||||
**Documentation:**
|
||||
- **[acme]** Use consistent name in ACME documentation ([#6019](https://github.com/containous/traefik/pull/6019) by [ldez](https://github.com/ldez))
|
||||
- **[api,k8s/crd]** Add a documentation example for dashboard and api for kubernetes CRD ([#6022](https://github.com/containous/traefik/pull/6022) by [dduportal](https://github.com/dduportal))
|
||||
- **[cli]** Fix examples for the use of websecure via CLI ([#6116](https://github.com/containous/traefik/pull/6116) by [tiagoboeing](https://github.com/tiagoboeing))
|
||||
- **[k8s,k8s/crd]** Improve documentation about Kubernetes IngressRoute ([#6058](https://github.com/containous/traefik/pull/6058) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
- **[middleware]** Improve sourceRange explanation for ipWhiteList ([#6070](https://github.com/containous/traefik/pull/6070) by [der-domi](https://github.com/der-domi))
|
||||
|
||||
## [v2.1.1](https://github.com/containous/traefik/tree/v2.1.1) (2019-12-12)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v2.1.0...v2.1.1)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[logs,middleware,metrics]** CloseNotifier: return pointer instead of value ([#6010](https://github.com/containous/traefik/pull/6010) by [mpl](https://github.com/mpl))
|
||||
|
||||
**Documentation:**
|
||||
- Add Migration Guide for Traefik v2.1 ([#6017](https://github.com/containous/traefik/pull/6017) by [SantoDE](https://github.com/SantoDE))
|
||||
|
||||
## [v2.1.0](https://github.com/containous/traefik/tree/v2.1.0) (2019-12-10)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v2.0.0-rc1...v2.1.0)
|
||||
|
||||
**Enhancements:**
|
||||
- **[consulcatalog]** Add consul catalog options: requireConsistent, stale, cache ([#5752](https://github.com/containous/traefik/pull/5752) by [ldez](https://github.com/ldez))
|
||||
- **[consulcatalog]** Add Consul Catalog provider ([#5395](https://github.com/containous/traefik/pull/5395) by [negasus](https://github.com/negasus))
|
||||
- **[k8s,k8s/crd,service]** Support for all services kinds (and sticky) in CRD ([#5711](https://github.com/containous/traefik/pull/5711) by [mpl](https://github.com/mpl))
|
||||
- **[metrics]** Added configurable prefix for statsd metrics collection ([#5336](https://github.com/containous/traefik/pull/5336) by [schulterklopfer](https://github.com/schulterklopfer))
|
||||
- **[middleware]** Conditional compression based on request Content-Type ([#5721](https://github.com/containous/traefik/pull/5721) by [ldez](https://github.com/ldez))
|
||||
- **[server]** Add internal provider ([#5815](https://github.com/containous/traefik/pull/5815) by [ldez](https://github.com/ldez))
|
||||
- **[tls]** Add support for MaxVersion in tls.Options ([#5650](https://github.com/containous/traefik/pull/5650) by [kmeekva](https://github.com/kmeekva))
|
||||
- **[tls]** Add tls option for Elliptic Curve Preferences ([#5466](https://github.com/containous/traefik/pull/5466) by [ksarink](https://github.com/ksarink))
|
||||
- **[tracing]** Update jaeger dependencies ([#5637](https://github.com/containous/traefik/pull/5637) by [mmatur](https://github.com/mmatur))
|
||||
|
||||
**Bug fixes:**
|
||||
- **[api]** fix: debug endpoint when insecure API. ([#5937](https://github.com/containous/traefik/pull/5937) by [ldez](https://github.com/ldez))
|
||||
- **[cli]** fix: sub command help ([#5887](https://github.com/containous/traefik/pull/5887) by [ldez](https://github.com/ldez))
|
||||
- **[consulcatalog]** fix: consul catalog constraints. ([#5913](https://github.com/containous/traefik/pull/5913) by [ldez](https://github.com/ldez))
|
||||
- **[consulcatalog]** Service registered with same id on Consul Catalog ([#5900](https://github.com/containous/traefik/pull/5900) by [mmatur](https://github.com/mmatur))
|
||||
- **[consulcatalog]** Fix empty address for registering service without IP ([#5826](https://github.com/containous/traefik/pull/5826) by [mmatur](https://github.com/mmatur))
|
||||
- **[logs,middleware,metrics]** detect CloseNotify capability in accesslog and metrics ([#5985](https://github.com/containous/traefik/pull/5985) by [mpl](https://github.com/mpl))
|
||||
- **[server]** fix: remove double call to server Close. ([#5960](https://github.com/containous/traefik/pull/5960) by [ldez](https://github.com/ldez))
|
||||
- **[webui]** Fix weighted service provider icon ([#5983](https://github.com/containous/traefik/pull/5983) by [sh7dm](https://github.com/sh7dm))
|
||||
- **[webui]** Fix http/tcp resources pagination ([#5986](https://github.com/containous/traefik/pull/5986) by [matthieuh](https://github.com/matthieuh))
|
||||
- **[webui]** Use valid condition in the service details panel UI ([#5984](https://github.com/containous/traefik/pull/5984) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
- **[webui]** Web UI: Avoid polling on /api/entrypoints ([#5863](https://github.com/containous/traefik/pull/5863) by [matthieuh](https://github.com/matthieuh))
|
||||
- **[webui]** Web UI: Sync toolbar table state with url query params ([#5861](https://github.com/containous/traefik/pull/5861) by [matthieuh](https://github.com/matthieuh))
|
||||
|
||||
**Documentation:**
|
||||
- **[consulcatalog]** fix: Consul Catalog documentation. ([#5725](https://github.com/containous/traefik/pull/5725) by [ldez](https://github.com/ldez))
|
||||
- **[consulcatalog]** Fix consul catalog documentation ([#5661](https://github.com/containous/traefik/pull/5661) by [mmatur](https://github.com/mmatur))
|
||||
- Prepare release v2.1.0-rc2 ([#5846](https://github.com/containous/traefik/pull/5846) by [ldez](https://github.com/ldez))
|
||||
- Prepare release v2.1.0-rc1 ([#5844](https://github.com/containous/traefik/pull/5844) by [jbdoumenjou](https://github.com/jbdoumenjou))
|
||||
- Several documentation fixes ([#5987](https://github.com/containous/traefik/pull/5987) by [ldez](https://github.com/ldez))
|
||||
- Prepare release v2.1.0-rc3 ([#5929](https://github.com/containous/traefik/pull/5929) by [ldez](https://github.com/ldez))
|
||||
|
||||
**Misc:**
|
||||
- **[cli]** Add custom help function to command ([#5923](https://github.com/containous/traefik/pull/5923) by [Ullaakut](https://github.com/Ullaakut))
|
||||
- **[server]** fix: use MaxInt32. ([#5845](https://github.com/containous/traefik/pull/5845) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.0 branch into master ([#5841](https://github.com/containous/traefik/pull/5841) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.0 branch into master ([#5749](https://github.com/containous/traefik/pull/5749) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.0 branch into master ([#5619](https://github.com/containous/traefik/pull/5619) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.0 branch into master ([#5464](https://github.com/containous/traefik/pull/5464) by [ldez](https://github.com/ldez))
|
||||
- Merge v2.0.0 into master ([#5402](https://github.com/containous/traefik/pull/5402) by [ldez](https://github.com/ldez))
|
||||
- Merge v2.0.0-rc3 into master ([#5354](https://github.com/containous/traefik/pull/5354) by [ldez](https://github.com/ldez))
|
||||
- Merge v2.0.0-rc1 into master ([#5253](https://github.com/containous/traefik/pull/5253) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.0 branch into v2.1 ([#5977](https://github.com/containous/traefik/pull/5977) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.0 branch into v2.1 ([#5931](https://github.com/containous/traefik/pull/5931) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.0 branch into v2.1 ([#5928](https://github.com/containous/traefik/pull/5928) by [ldez](https://github.com/ldez))
|
||||
|
||||
## [v2.0.7](https://github.com/containous/traefik/tree/v2.0.7) (2019-12-09)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v2.0.6...v2.0.7)
|
||||
|
||||
@@ -97,19 +15,6 @@
|
||||
- Fix Docker example in "Strip and Rewrite Path Prefixes" in migration guide ([#5949](https://github.com/containous/traefik/pull/5949) by [q210](https://github.com/q210))
|
||||
- readme: Fix link to file backend/provider documentation ([#5945](https://github.com/containous/traefik/pull/5945) by [hartwork](https://github.com/hartwork))
|
||||
|
||||
## [v2.1.0-rc3](https://github.com/containous/traefik/tree/v2.1.0-rc3) (2019-12-02)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v2.1.0-rc2...v2.1.0-rc3)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[cli]** fix: sub command help ([#5887](https://github.com/containous/traefik/pull/5887) by [ldez](https://github.com/ldez))
|
||||
- **[consulcatalog]** fix: consul catalog constraints. ([#5913](https://github.com/containous/traefik/pull/5913) by [ldez](https://github.com/ldez))
|
||||
- **[consulcatalog]** Service registered with same id on Consul Catalog ([#5900](https://github.com/containous/traefik/pull/5900) by [mmatur](https://github.com/mmatur))
|
||||
- **[webui]** Web UI: Avoid polling on /api/entrypoints ([#5863](https://github.com/containous/traefik/pull/5863) by [matthieuh](https://github.com/matthieuh))
|
||||
- **[webui]** Web UI: Sync toolbar table state with url query params ([#5861](https://github.com/containous/traefik/pull/5861) by [matthieuh](https://github.com/matthieuh))
|
||||
|
||||
**Misc:**
|
||||
- **[cli]** Add custom help function to command ([#5923](https://github.com/containous/traefik/pull/5923) by [Ullaakut](https://github.com/Ullaakut))
|
||||
|
||||
## [v2.0.6](https://github.com/containous/traefik/tree/v2.0.6) (2019-12-02)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v2.0.5...v2.0.6)
|
||||
|
||||
@@ -136,41 +41,6 @@
|
||||
- Fixed spelling error ([#5834](https://github.com/containous/traefik/pull/5834) by [blakebuthod](https://github.com/blakebuthod))
|
||||
- Add back the security section from v1 ([#5832](https://github.com/containous/traefik/pull/5832) by [pascalandy](https://github.com/pascalandy))
|
||||
|
||||
## [v2.1.0-rc2](https://github.com/containous/traefik/tree/v2.0.4) (2019-11-15)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v2.0.0-rc1...v2.1.0-rc2)
|
||||
|
||||
Fixes int overflow.
|
||||
Same changelog as v2.1.0-rc1
|
||||
|
||||
## [v2.1.0-rc1](https://github.com/containous/traefik/tree/v2.1.0-rc1) (2019-11-15)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v2.0.0-rc1...v2.1.0-rc1)
|
||||
|
||||
**Enhancements:**
|
||||
- **[consulcatalog]** Add consul catalog options: requireConsistent, stale, cache ([#5752](https://github.com/containous/traefik/pull/5752) by [ldez](https://github.com/ldez))
|
||||
- **[consulcatalog]** Add Consul Catalog provider ([#5395](https://github.com/containous/traefik/pull/5395) by [negasus](https://github.com/negasus))
|
||||
- **[k8s,k8s/crd,service]** Support for all services kinds (and sticky) in CRD ([#5711](https://github.com/containous/traefik/pull/5711) by [mpl](https://github.com/mpl))
|
||||
- **[metrics]** Added configurable prefix for statsd metrics collection ([#5336](https://github.com/containous/traefik/pull/5336) by [schulterklopfer](https://github.com/schulterklopfer))
|
||||
- **[middleware]** Conditional compression based on request Content-Type ([#5721](https://github.com/containous/traefik/pull/5721) by [ldez](https://github.com/ldez))
|
||||
- **[server]** Add internal provider ([#5815](https://github.com/containous/traefik/pull/5815) by [ldez](https://github.com/ldez))
|
||||
- **[tls]** Add support for MaxVersion in tls.Options ([#5650](https://github.com/containous/traefik/pull/5650) by [kmeekva](https://github.com/kmeekva))
|
||||
- **[tls]** Add tls option for Elliptic Curve Preferences ([#5466](https://github.com/containous/traefik/pull/5466) by [ksarink](https://github.com/ksarink))
|
||||
- **[tracing]** Update jaeger dependencies ([#5637](https://github.com/containous/traefik/pull/5637) by [mmatur](https://github.com/mmatur))
|
||||
|
||||
**Bug fixes:**
|
||||
- **[consulcatalog]** Fix empty address for registering service without IP ([#5826](https://github.com/containous/traefik/pull/5826) by [mmatur](https://github.com/mmatur))
|
||||
|
||||
**Documentation:**
|
||||
- **[consulcatalog]** fix: Consul Catalog documentation. ([#5725](https://github.com/containous/traefik/pull/5725) by [ldez](https://github.com/ldez))
|
||||
- **[consulcatalog]** Fix consul catalog documentation ([#5661](https://github.com/containous/traefik/pull/5661) by [mmatur](https://github.com/mmatur))
|
||||
|
||||
**Misc:**
|
||||
- Merge current v2.0 branch into master ([#5749](https://github.com/containous/traefik/pull/5749) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.0 branch into master ([#5619](https://github.com/containous/traefik/pull/5619) by [ldez](https://github.com/ldez))
|
||||
- Merge current v2.0 branch into master ([#5464](https://github.com/containous/traefik/pull/5464) by [ldez](https://github.com/ldez))
|
||||
- Merge v2.0.0 into master ([#5402](https://github.com/containous/traefik/pull/5402) by [ldez](https://github.com/ldez))
|
||||
- Merge v2.0.0-rc3 into master ([#5354](https://github.com/containous/traefik/pull/5354) by [ldez](https://github.com/ldez))
|
||||
- Merge v2.0.0-rc1 into master ([#5253](https://github.com/containous/traefik/pull/5253) by [ldez](https://github.com/ldez))
|
||||
|
||||
## [v2.0.5](https://github.com/containous/traefik/tree/v2.0.5) (2019-11-14)
|
||||
[All Commits](https://github.com/containous/traefik/compare/v2.0.4...v2.0.5)
|
||||
|
||||
|
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
stdlog "log"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -19,17 +20,12 @@ import (
|
||||
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||
"github.com/containous/traefik/v2/pkg/config/static"
|
||||
"github.com/containous/traefik/v2/pkg/log"
|
||||
"github.com/containous/traefik/v2/pkg/metrics"
|
||||
"github.com/containous/traefik/v2/pkg/middlewares/accesslog"
|
||||
"github.com/containous/traefik/v2/pkg/provider/acme"
|
||||
"github.com/containous/traefik/v2/pkg/provider/aggregator"
|
||||
"github.com/containous/traefik/v2/pkg/provider/traefik"
|
||||
"github.com/containous/traefik/v2/pkg/safe"
|
||||
"github.com/containous/traefik/v2/pkg/server"
|
||||
"github.com/containous/traefik/v2/pkg/server/middleware"
|
||||
"github.com/containous/traefik/v2/pkg/server/service"
|
||||
"github.com/containous/traefik/v2/pkg/server/router"
|
||||
traefiktls "github.com/containous/traefik/v2/pkg/tls"
|
||||
"github.com/containous/traefik/v2/pkg/types"
|
||||
"github.com/containous/traefik/v2/pkg/version"
|
||||
"github.com/coreos/go-systemd/daemon"
|
||||
assetfs "github.com/elazarl/go-bindata-assetfs"
|
||||
@@ -69,10 +65,10 @@ Complete documentation is available at https://traefik.io`,
|
||||
err = cli.Execute(cmdTraefik)
|
||||
if err != nil {
|
||||
stdlog.Println(err)
|
||||
logrus.Exit(1)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
logrus.Exit(0)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func runCmd(staticConfiguration *static.Configuration) error {
|
||||
@@ -81,7 +77,7 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
||||
http.DefaultTransport.(*http.Transport).Proxy = http.ProxyFromEnvironment
|
||||
|
||||
if err := roundrobin.SetDefaultWeight(0); err != nil {
|
||||
log.WithoutContext().Errorf("Could not set round robin default weight: %v", err)
|
||||
log.WithoutContext().Errorf("Could not set roundrobin default weight: %v", err)
|
||||
}
|
||||
|
||||
staticConfiguration.SetEffectiveConfiguration()
|
||||
@@ -109,11 +105,43 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
||||
|
||||
stats(staticConfiguration)
|
||||
|
||||
svr, err := setupServer(staticConfiguration)
|
||||
if err != nil {
|
||||
return err
|
||||
providerAggregator := aggregator.NewProviderAggregator(*staticConfiguration.Providers)
|
||||
|
||||
tlsManager := traefiktls.NewManager()
|
||||
|
||||
acmeProviders := initACMEProvider(staticConfiguration, &providerAggregator, tlsManager)
|
||||
|
||||
serverEntryPointsTCP := make(server.TCPEntryPoints)
|
||||
for entryPointName, config := range staticConfiguration.EntryPoints {
|
||||
ctx := log.With(context.Background(), log.Str(log.EntryPointName, entryPointName))
|
||||
serverEntryPointsTCP[entryPointName], err = server.NewTCPEntryPoint(ctx, config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error while building entryPoint %s: %v", entryPointName, err)
|
||||
}
|
||||
serverEntryPointsTCP[entryPointName].RouteAppenderFactory = router.NewRouteAppenderFactory(*staticConfiguration, entryPointName, acmeProviders)
|
||||
}
|
||||
|
||||
svr := server.NewServer(*staticConfiguration, providerAggregator, serverEntryPointsTCP, tlsManager)
|
||||
|
||||
resolverNames := map[string]struct{}{}
|
||||
|
||||
for _, p := range acmeProviders {
|
||||
resolverNames[p.ResolverName] = struct{}{}
|
||||
svr.AddListener(p.ListenConfiguration)
|
||||
}
|
||||
|
||||
svr.AddListener(func(config dynamic.Configuration) {
|
||||
for rtName, rt := range config.HTTP.Routers {
|
||||
if rt.TLS == nil || rt.TLS.CertResolver == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := resolverNames[rt.TLS.CertResolver]; !ok {
|
||||
log.WithoutContext().Errorf("the router %s uses a non-existent resolver: %s", rtName, rt.TLS.CertResolver)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
ctx := cmd.ContextWithSignal(context.Background())
|
||||
|
||||
if staticConfiguration.Ping != nil {
|
||||
@@ -140,7 +168,7 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
||||
for range tick {
|
||||
resp, errHealthCheck := healthcheck.Do(*staticConfiguration)
|
||||
if resp != nil {
|
||||
_ = resp.Body.Close()
|
||||
resp.Body.Close()
|
||||
}
|
||||
|
||||
if staticConfiguration.Ping == nil || errHealthCheck == nil {
|
||||
@@ -156,97 +184,10 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
||||
|
||||
svr.Wait()
|
||||
log.WithoutContext().Info("Shutting down")
|
||||
logrus.Exit(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupServer(staticConfiguration *static.Configuration) (*server.Server, error) {
|
||||
providerAggregator := aggregator.NewProviderAggregator(*staticConfiguration.Providers)
|
||||
|
||||
// adds internal provider
|
||||
err := providerAggregator.AddProvider(traefik.New(*staticConfiguration))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tlsManager := traefiktls.NewManager()
|
||||
|
||||
acmeProviders := initACMEProvider(staticConfiguration, &providerAggregator, tlsManager)
|
||||
|
||||
serverEntryPointsTCP, err := server.NewTCPEntryPoints(staticConfiguration.EntryPoints)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
routinesPool := safe.NewPool(ctx)
|
||||
|
||||
metricsRegistry := registerMetricClients(staticConfiguration.Metrics)
|
||||
accessLog := setupAccessLog(staticConfiguration.AccessLog)
|
||||
chainBuilder := middleware.NewChainBuilder(*staticConfiguration, metricsRegistry, accessLog)
|
||||
managerFactory := service.NewManagerFactory(*staticConfiguration, routinesPool, metricsRegistry)
|
||||
tcpRouterFactory := server.NewTCPRouterFactory(*staticConfiguration, managerFactory, tlsManager, chainBuilder)
|
||||
|
||||
watcher := server.NewConfigurationWatcher(routinesPool, providerAggregator, time.Duration(staticConfiguration.Providers.ProvidersThrottleDuration))
|
||||
|
||||
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||
ctx := context.Background()
|
||||
tlsManager.UpdateConfigs(ctx, conf.TLS.Stores, conf.TLS.Options, conf.TLS.Certificates)
|
||||
})
|
||||
|
||||
watcher.AddListener(func(_ dynamic.Configuration) {
|
||||
metricsRegistry.ConfigReloadsCounter().Add(1)
|
||||
metricsRegistry.LastConfigReloadSuccessGauge().Set(float64(time.Now().Unix()))
|
||||
})
|
||||
|
||||
watcher.AddListener(switchRouter(tcpRouterFactory, acmeProviders, serverEntryPointsTCP))
|
||||
|
||||
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||
if metricsRegistry.IsEpEnabled() || metricsRegistry.IsSvcEnabled() {
|
||||
var eps []string
|
||||
for key := range serverEntryPointsTCP {
|
||||
eps = append(eps, key)
|
||||
}
|
||||
|
||||
metrics.OnConfigurationUpdate(conf, eps)
|
||||
}
|
||||
})
|
||||
|
||||
resolverNames := map[string]struct{}{}
|
||||
for _, p := range acmeProviders {
|
||||
resolverNames[p.ResolverName] = struct{}{}
|
||||
watcher.AddListener(p.ListenConfiguration)
|
||||
}
|
||||
|
||||
watcher.AddListener(func(config dynamic.Configuration) {
|
||||
for rtName, rt := range config.HTTP.Routers {
|
||||
if rt.TLS == nil || rt.TLS.CertResolver == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := resolverNames[rt.TLS.CertResolver]; !ok {
|
||||
log.WithoutContext().Errorf("the router %s uses a non-existent resolver: %s", rtName, rt.TLS.CertResolver)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return server.NewServer(routinesPool, serverEntryPointsTCP, watcher, chainBuilder, accessLog), nil
|
||||
}
|
||||
|
||||
func switchRouter(tcpRouterFactory *server.TCPRouterFactory, acmeProviders []*acme.Provider, serverEntryPointsTCP server.TCPEntryPoints) func(conf dynamic.Configuration) {
|
||||
return func(conf dynamic.Configuration) {
|
||||
routers := tcpRouterFactory.CreateTCPRouters(conf)
|
||||
for entryPointName, rt := range routers {
|
||||
for _, p := range acmeProviders {
|
||||
if p != nil && p.HTTPChallenge != nil && p.HTTPChallenge.EntryPoint == entryPointName {
|
||||
rt.HTTPHandler(p.CreateHandler(rt.GetHTTPHandler()))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
serverEntryPointsTCP.Switch(routers)
|
||||
}
|
||||
}
|
||||
|
||||
// initACMEProvider creates an acme provider from the ACME part of globalConfiguration
|
||||
func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.ProviderAggregator, tlsManager *traefiktls.Manager) []*acme.Provider {
|
||||
challengeStore := acme.NewLocalChallengeStore()
|
||||
@@ -281,60 +222,6 @@ func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.Pr
|
||||
return resolvers
|
||||
}
|
||||
|
||||
func registerMetricClients(metricsConfig *types.Metrics) metrics.Registry {
|
||||
if metricsConfig == nil {
|
||||
return metrics.NewVoidRegistry()
|
||||
}
|
||||
|
||||
var registries []metrics.Registry
|
||||
|
||||
if metricsConfig.Prometheus != nil {
|
||||
ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "prometheus"))
|
||||
prometheusRegister := metrics.RegisterPrometheus(ctx, metricsConfig.Prometheus)
|
||||
if prometheusRegister != nil {
|
||||
registries = append(registries, prometheusRegister)
|
||||
log.FromContext(ctx).Debug("Configured Prometheus metrics")
|
||||
}
|
||||
}
|
||||
|
||||
if metricsConfig.Datadog != nil {
|
||||
ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "datadog"))
|
||||
registries = append(registries, metrics.RegisterDatadog(ctx, metricsConfig.Datadog))
|
||||
log.FromContext(ctx).Debugf("Configured Datadog metrics: pushing to %s once every %s",
|
||||
metricsConfig.Datadog.Address, metricsConfig.Datadog.PushInterval)
|
||||
}
|
||||
|
||||
if metricsConfig.StatsD != nil {
|
||||
ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "statsd"))
|
||||
registries = append(registries, metrics.RegisterStatsd(ctx, metricsConfig.StatsD))
|
||||
log.FromContext(ctx).Debugf("Configured StatsD metrics: pushing to %s once every %s",
|
||||
metricsConfig.StatsD.Address, metricsConfig.StatsD.PushInterval)
|
||||
}
|
||||
|
||||
if metricsConfig.InfluxDB != nil {
|
||||
ctx := log.With(context.Background(), log.Str(log.MetricsProviderName, "influxdb"))
|
||||
registries = append(registries, metrics.RegisterInfluxDB(ctx, metricsConfig.InfluxDB))
|
||||
log.FromContext(ctx).Debugf("Configured InfluxDB metrics: pushing to %s once every %s",
|
||||
metricsConfig.InfluxDB.Address, metricsConfig.InfluxDB.PushInterval)
|
||||
}
|
||||
|
||||
return metrics.NewMultiRegistry(registries)
|
||||
}
|
||||
|
||||
func setupAccessLog(conf *types.AccessLog) *accesslog.Handler {
|
||||
if conf == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
accessLoggerMiddleware, err := accesslog.NewHandler(conf)
|
||||
if err != nil {
|
||||
log.WithoutContext().Warnf("Unable to create access logger : %v", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
return accessLoggerMiddleware
|
||||
}
|
||||
|
||||
func configureLogging(staticConfiguration *static.Configuration) {
|
||||
// configure default log flags
|
||||
stdlog.SetFlags(stdlog.Lshortfile | stdlog.LstdFlags)
|
||||
|
@@ -1,5 +1,4 @@
|
||||
|
||||
FROM alpine:3.10 as alpine
|
||||
FROM alpine:3.15 as alpine
|
||||
|
||||
RUN apk --no-cache --no-progress add \
|
||||
libcurl \
|
||||
@@ -9,7 +8,7 @@ RUN apk --no-cache --no-progress add \
|
||||
ruby-ffi \
|
||||
ruby-json \
|
||||
ruby-nokogiri
|
||||
RUN gem install html-proofer --version 3.13.0 --no-document -- --use-system-libraries
|
||||
RUN gem install html-proofer --version 3.19.3 --no-document -- --use-system-libraries
|
||||
|
||||
# After Ruby, some NodeJS YAY!
|
||||
RUN apk --no-cache --no-progress add \
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB |
@@ -62,7 +62,7 @@ Requirements:
|
||||
|
||||
- `go` v1.13+
|
||||
- environment variable `GO111MODULE=on`
|
||||
- [go-bindata](https://github.com/containous/go-bindata) `GO111MODULE=off go get -u github.com/containous/go-bindata/...`
|
||||
- go-bindata `GO111MODULE=off go get -u github.com/containous/go-bindata/...`
|
||||
|
||||
!!! tip "Source Directory"
|
||||
|
||||
@@ -98,32 +98,30 @@ Requirements:
|
||||
#### Build Traefik
|
||||
|
||||
Once you've set up your go environment and cloned the source repository, you can build Traefik.
|
||||
|
||||
Beforehand, you need to get [go-bindata](https://github.com/containous/go-bindata) (the first time) in order to be able to use the `go generate` command (which is part of the build process).
|
||||
Beforehand, you need to get `go-bindata` (the first time) in order to be able to use the `go generate` command (which is part of the build process).
|
||||
|
||||
```bash
|
||||
cd ~/go/src/github.com/containous/traefik
|
||||
|
||||
# Get go-bindata. (Important: the ellipses are required.)
|
||||
GO111MODULE=off go get github.com/containous/go-bindata/...
|
||||
```
|
||||
|
||||
```bash
|
||||
# Generate UI static files
|
||||
rm -rf static/ autogen/; make generate-webui
|
||||
# Let's build
|
||||
|
||||
# required to merge non-code components into the final binary,
|
||||
# such as the web dashboard/UI
|
||||
# generate
|
||||
# (required to merge non-code components into the final binary, such as the web dashboard and the provider's templates)
|
||||
go generate
|
||||
```
|
||||
|
||||
```bash
|
||||
# Standard go build
|
||||
go build ./cmd/traefik
|
||||
```
|
||||
|
||||
You will find the Traefik executable (`traefik`) in the `~/go/src/github.com/containous/traefik` directory.
|
||||
|
||||
### Updating the templates
|
||||
|
||||
If you happen to update the provider's templates (located in `/templates`), you must run `go generate` to update the `autogen` package.
|
||||
|
||||
## Testing
|
||||
|
||||
### Method 1: `Docker` and `make`
|
||||
|
@@ -59,10 +59,10 @@ Please check the [configuration examples below](#configuration-examples) for mor
|
||||
[entryPoints.web-secure]
|
||||
address = ":443"
|
||||
|
||||
[certificatesResolvers.le.acme]
|
||||
[certificatesResolvers.sample.acme]
|
||||
email = "your-email@your-domain.org"
|
||||
storage = "acme.json"
|
||||
[certificatesResolvers.le.acme.httpChallenge]
|
||||
[certificatesResolvers.sample.acme.httpChallenge]
|
||||
# used during the challenge
|
||||
entryPoint = "web"
|
||||
```
|
||||
@@ -89,10 +89,10 @@ Please check the [configuration examples below](#configuration-examples) for mor
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
# ...
|
||||
--certificatesResolvers.le.acme.email=your-email@your-domain.org
|
||||
--certificatesResolvers.le.acme.storage=acme.json
|
||||
--certificatesResolvers.sample.acme.email=your-email@your-domain.org
|
||||
--certificatesResolvers.sample.acme.storage=acme.json
|
||||
# used during the challenge
|
||||
--certificatesResolvers.le.acme.httpChallenge.entryPoint=web
|
||||
--certificatesResolvers.sample.acme.httpChallenge.entryPoint=web
|
||||
```
|
||||
|
||||
!!! important "Defining a certificates resolver does not result in all routers automatically using it. Each router that is supposed to use the resolver must [reference](../routing/routers/index.md#certresolver) it."
|
||||
@@ -164,9 +164,9 @@ when using the `TLS-ALPN-01` challenge, Traefik must be reachable by Let's Encry
|
||||
??? example "Configuring the `tlsChallenge`"
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[certificatesResolvers.le.acme]
|
||||
[certificatesResolvers.sample.acme]
|
||||
# ...
|
||||
[certificatesResolvers.le.acme.tlsChallenge]
|
||||
[certificatesResolvers.sample.acme.tlsChallenge]
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
@@ -179,7 +179,7 @@ when using the `TLS-ALPN-01` challenge, Traefik must be reachable by Let's Encry
|
||||
|
||||
```bash tab="CLI"
|
||||
# ...
|
||||
--certificatesResolvers.le.acme.tlsChallenge=true
|
||||
--certificatesResolvers.sample.acme.tlsChallenge=true
|
||||
```
|
||||
|
||||
### `httpChallenge`
|
||||
@@ -187,7 +187,7 @@ when using the `TLS-ALPN-01` challenge, Traefik must be reachable by Let's Encry
|
||||
Use the `HTTP-01` challenge to generate and renew ACME certificates by provisioning an HTTP resource under a well-known URI.
|
||||
|
||||
As described on the Let's Encrypt [community forum](https://community.letsencrypt.org/t/support-for-ports-other-than-80-and-443/3419/72),
|
||||
when using the `HTTP-01` challenge, `certificatesResolvers.le.acme.httpChallenge.entryPoint` must be reachable by Let's Encrypt through port 80.
|
||||
when using the `HTTP-01` challenge, `certificatesResolvers.sample.acme.httpChallenge.entryPoint` must be reachable by Let's Encrypt through port 80.
|
||||
|
||||
??? example "Using an EntryPoint Called http for the `httpChallenge`"
|
||||
|
||||
@@ -199,9 +199,9 @@ when using the `HTTP-01` challenge, `certificatesResolvers.le.acme.httpChallenge
|
||||
[entryPoints.web-secure]
|
||||
address = ":443"
|
||||
|
||||
[certificatesResolvers.le.acme]
|
||||
[certificatesResolvers.sample.acme]
|
||||
# ...
|
||||
[certificatesResolvers.le.acme.httpChallenge]
|
||||
[certificatesResolvers.sample.acme.httpChallenge]
|
||||
entryPoint = "web"
|
||||
```
|
||||
|
||||
@@ -225,7 +225,7 @@ when using the `HTTP-01` challenge, `certificatesResolvers.le.acme.httpChallenge
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
# ...
|
||||
--certificatesResolvers.le.acme.httpChallenge.entryPoint=web
|
||||
--certificatesResolvers.sample.acme.httpChallenge.entryPoint=web
|
||||
```
|
||||
|
||||
!!! info ""
|
||||
@@ -238,9 +238,9 @@ Use the `DNS-01` challenge to generate and renew ACME certificates by provisioni
|
||||
??? example "Configuring a `dnsChallenge` with the DigitalOcean Provider"
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[certificatesResolvers.le.acme]
|
||||
[certificatesResolvers.sample.acme]
|
||||
# ...
|
||||
[certificatesResolvers.le.acme.dnsChallenge]
|
||||
[certificatesResolvers.sample.acme.dnsChallenge]
|
||||
provider = "digitalocean"
|
||||
delayBeforeCheck = 0
|
||||
# ...
|
||||
@@ -259,8 +259,8 @@ Use the `DNS-01` challenge to generate and renew ACME certificates by provisioni
|
||||
|
||||
```bash tab="CLI"
|
||||
# ...
|
||||
--certificatesResolvers.le.acme.dnsChallenge.provider=digitalocean
|
||||
--certificatesResolvers.le.acme.dnsChallenge.delayBeforeCheck=0
|
||||
--certificatesResolvers.sample.acme.dnsChallenge.provider=digitalocean
|
||||
--certificatesResolvers.sample.acme.dnsChallenge.delayBeforeCheck=0
|
||||
# ...
|
||||
```
|
||||
|
||||
@@ -357,9 +357,9 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used
|
||||
Use custom DNS servers to resolve the FQDN authority.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[certificatesResolvers.le.acme]
|
||||
[certificatesResolvers.sample.acme]
|
||||
# ...
|
||||
[certificatesResolvers.le.acme.dnsChallenge]
|
||||
[certificatesResolvers.sample.acme.dnsChallenge]
|
||||
# ...
|
||||
resolvers = ["1.1.1.1:53", "8.8.8.8:53"]
|
||||
```
|
||||
@@ -378,7 +378,7 @@ certificatesResolvers:
|
||||
|
||||
```bash tab="CLI"
|
||||
# ...
|
||||
--certificatesResolvers.le.acme.dnsChallenge.resolvers:=1.1.1.1:53,8.8.8.8:53
|
||||
--certificatesResolvers.sample.acme.dnsChallenge.resolvers:=1.1.1.1:53,8.8.8.8:53
|
||||
```
|
||||
|
||||
#### Wildcard Domains
|
||||
@@ -393,7 +393,7 @@ As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/stagi
|
||||
??? example "Using the Let's Encrypt staging server"
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[certificatesResolvers.le.acme]
|
||||
[certificatesResolvers.sample.acme]
|
||||
# ...
|
||||
caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
# ...
|
||||
@@ -410,7 +410,7 @@ As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/stagi
|
||||
|
||||
```bash tab="CLI"
|
||||
# ...
|
||||
--certificatesResolvers.le.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
--certificatesResolvers.sample.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
# ...
|
||||
```
|
||||
|
||||
@@ -419,7 +419,7 @@ As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/stagi
|
||||
The `storage` option sets the location where your ACME certificates are saved to.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[certificatesResolvers.le.acme]
|
||||
[certificatesResolvers.sample.acme]
|
||||
# ...
|
||||
storage = "acme.json"
|
||||
# ...
|
||||
@@ -436,7 +436,7 @@ certificatesResolvers:
|
||||
|
||||
```bash tab="CLI"
|
||||
# ...
|
||||
--certificatesResolvers.le.acme.storage=acme.json
|
||||
--certificatesResolvers.sample.acme.storage=acme.json
|
||||
# ...
|
||||
```
|
||||
|
||||
|
@@ -12,9 +12,9 @@ labels:
|
||||
deploy:
|
||||
labels:
|
||||
- traefik.http.routers.blog.rule=(Host(`company.com`) && Path(`/blog`)) || Host(`blog.company.org`)
|
||||
- traefik.http.services.blog-svc.loadbalancer.server.port=8080"
|
||||
- traefik.http.routers.blog.tls=true
|
||||
- traefik.http.routers.blog.tls.certresolver=le
|
||||
- traefik.http.services.blog-svc.loadbalancer.server.port=8080"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
|
@@ -12,9 +12,9 @@ labels:
|
||||
deploy:
|
||||
labels:
|
||||
- traefik.http.routers.blog.rule=Host(`company.com`) && Path(`/blog`)
|
||||
- traefik.http.services.blog-svc.loadbalancer.server.port=8080"
|
||||
- traefik.http.routers.blog.tls=true
|
||||
- traefik.http.routers.blog.tls.certresolver=le
|
||||
- traefik.http.services.blog-svc.loadbalancer.server.port=8080"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
|
@@ -35,13 +35,13 @@
|
||||
#
|
||||
# Optional (but recommended)
|
||||
#
|
||||
[certificatesResolvers.le.acme.tlsChallenge]
|
||||
[certificatesResolvers.sample.acme.tlsChallenge]
|
||||
|
||||
# Use a HTTP-01 ACME challenge.
|
||||
#
|
||||
# Optional
|
||||
#
|
||||
# [certificatesResolvers.le.acme.httpChallenge]
|
||||
# [certificatesResolvers.sample.acme.httpChallenge]
|
||||
|
||||
# EntryPoint to use for the HTTP-01 challenges.
|
||||
#
|
||||
@@ -54,7 +54,7 @@
|
||||
#
|
||||
# Optional
|
||||
#
|
||||
# [certificatesResolvers.le.acme.dnsChallenge]
|
||||
# [certificatesResolvers.sample.acme.dnsChallenge]
|
||||
|
||||
# DNS provider used.
|
||||
#
|
||||
|
@@ -4,13 +4,13 @@
|
||||
#
|
||||
# Required
|
||||
#
|
||||
--certificatesResolvers.le.acme.email=test@traefik.io
|
||||
--certificatesResolvers.sample.acme.email=test@traefik.io
|
||||
|
||||
# File or key used for certificates storage.
|
||||
#
|
||||
# Required
|
||||
#
|
||||
--certificatesResolvers.le.acme.storage=acme.json
|
||||
--certificatesResolvers.sample.acme.storage=acme.json
|
||||
|
||||
# CA server to use.
|
||||
# Uncomment the line to use Let's Encrypt's staging server,
|
||||
@@ -19,7 +19,7 @@
|
||||
# Optional
|
||||
# Default: "https://acme-v02.api.letsencrypt.org/directory"
|
||||
#
|
||||
--certificatesResolvers.le.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
--certificatesResolvers.sample.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
|
||||
# KeyType to use.
|
||||
#
|
||||
@@ -28,38 +28,38 @@
|
||||
#
|
||||
# Available values : "EC256", "EC384", "RSA2048", "RSA4096", "RSA8192"
|
||||
#
|
||||
--certificatesResolvers.le.acme.keyType=RSA4096
|
||||
--certificatesResolvers.sample.acme.keyType=RSA4096
|
||||
|
||||
# Use a TLS-ALPN-01 ACME challenge.
|
||||
#
|
||||
# Optional (but recommended)
|
||||
#
|
||||
--certificatesResolvers.le.acme.tlsChallenge=true
|
||||
--certificatesResolvers.sample.acme.tlsChallenge=true
|
||||
|
||||
# Use a HTTP-01 ACME challenge.
|
||||
#
|
||||
# Optional
|
||||
#
|
||||
--certificatesResolvers.le.acme.httpChallenge=true
|
||||
--certificatesResolvers.sample.acme.httpChallenge=true
|
||||
|
||||
# EntryPoint to use for the HTTP-01 challenges.
|
||||
#
|
||||
# Required
|
||||
#
|
||||
--certificatesResolvers.le.acme.httpChallenge.entryPoint=web
|
||||
--certificatesResolvers.sample.acme.httpChallenge.entryPoint=web
|
||||
|
||||
# Use a DNS-01 ACME challenge rather than HTTP-01 challenge.
|
||||
# Note: mandatory for wildcard certificate generation.
|
||||
#
|
||||
# Optional
|
||||
#
|
||||
--certificatesResolvers.le.acme.dnsChallenge=true
|
||||
--certificatesResolvers.sample.acme.dnsChallenge=true
|
||||
|
||||
# DNS provider used.
|
||||
#
|
||||
# Required
|
||||
#
|
||||
--certificatesResolvers.le.acme.dnsChallenge.provider=digitalocean
|
||||
--certificatesResolvers.sample.acme.dnsChallenge.provider=digitalocean
|
||||
|
||||
# By default, the provider will verify the TXT DNS challenge record before letting ACME verify.
|
||||
# If delayBeforeCheck is greater than zero, this check is delayed for the configured duration in seconds.
|
||||
@@ -68,14 +68,14 @@
|
||||
# Optional
|
||||
# Default: 0
|
||||
#
|
||||
--certificatesResolvers.le.acme.dnsChallenge.delayBeforeCheck=0
|
||||
--certificatesResolvers.sample.acme.dnsChallenge.delayBeforeCheck=0
|
||||
|
||||
# Use following DNS servers to resolve the FQDN authority.
|
||||
#
|
||||
# Optional
|
||||
# Default: empty
|
||||
#
|
||||
--certificatesResolvers.le.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53
|
||||
--certificatesResolvers.sample.acme.dnsChallenge.resolvers=1.1.1.1:53,8.8.8.8:53
|
||||
|
||||
# Disable the DNS propagation checks before notifying ACME that the DNS challenge is ready.
|
||||
#
|
||||
@@ -85,4 +85,4 @@
|
||||
# Optional
|
||||
# Default: false
|
||||
#
|
||||
--certificatesResolvers.le.acme.dnsChallenge.disablePropagationCheck=true
|
||||
--certificatesResolvers.sample.acme.dnsChallenge.disablePropagationCheck=true
|
||||
|
@@ -1,5 +1,5 @@
|
||||
certificatesResolvers:
|
||||
le:
|
||||
sample:
|
||||
# Enable ACME (Let's Encrypt): automatic SSL.
|
||||
acme:
|
||||
|
||||
|
@@ -40,7 +40,7 @@ tls:
|
||||
|
||||
In the above example, we've used the [file provider](../providers/file.md) to handle these definitions.
|
||||
It is the only available method to configure the certificates (as well as the options and the stores).
|
||||
However, in [Kubernetes](../providers/kubernetes-crd.md), the certificates can and must be provided by [secrets](https://kubernetes.io/docs/concepts/configuration/secret/).
|
||||
However, in [Kubernetes](../providers/kubernetes-crd.md), the certificates can and must be provided by [secrets](../routing/providers/kubernetes-crd.md#tls).
|
||||
|
||||
## Certificates Stores
|
||||
|
||||
@@ -181,57 +181,6 @@ spec:
|
||||
minVersion: VersionTLS13
|
||||
```
|
||||
|
||||
### Maximum TLS Version
|
||||
|
||||
We discourages the use of this setting to disable TLS1.3.
|
||||
|
||||
The right approach is to update the clients to support TLS1.3.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Dynamic configuration
|
||||
|
||||
[tls.options]
|
||||
|
||||
[tls.options.default]
|
||||
maxVersion = "VersionTLS13"
|
||||
|
||||
[tls.options.maxtls12]
|
||||
maxVersion = "VersionTLS12"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Dynamic configuration
|
||||
|
||||
tls:
|
||||
options:
|
||||
default:
|
||||
maxVersion: VersionTLS13
|
||||
|
||||
maxtls12:
|
||||
maxVersion: VersionTLS12
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TLSOption
|
||||
metadata:
|
||||
name: default
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
maxVersion: VersionTLS13
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TLSOption
|
||||
metadata:
|
||||
name: maxtls12
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
maxVersion: VersionTLS12
|
||||
```
|
||||
|
||||
### Cipher Suites
|
||||
|
||||
See [cipherSuites](https://godoc.org/crypto/tls#pkg-constants) for more information.
|
||||
@@ -274,46 +223,6 @@ spec:
|
||||
With TLS 1.3, the cipher suites are not configurable (all supported cipher suites are safe in this case).
|
||||
<https://golang.org/doc/go1.12#tls_1_3>
|
||||
|
||||
### Curve Preferences
|
||||
|
||||
This option allows to set the preferred elliptic curves in a specific order.
|
||||
|
||||
The names of the curves defined by [`crypto`](https://godoc.org/crypto/tls#CurveID) (e.g. `CurveP521`) and the [RFC defined names](https://tools.ietf.org/html/rfc8446#section-4.2.7) (e. g. `secp521r1`) can be used.
|
||||
|
||||
See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Dynamic configuration
|
||||
|
||||
[tls.options]
|
||||
[tls.options.default]
|
||||
curvePreferences = ["CurveP521", "CurveP384"]
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Dynamic configuration
|
||||
|
||||
tls:
|
||||
options:
|
||||
default:
|
||||
curvePreferences:
|
||||
- CurveP521
|
||||
- CurveP384
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TLSOption
|
||||
metadata:
|
||||
name: default
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
curvePreferences:
|
||||
- CurveP521
|
||||
- CurveP384
|
||||
```
|
||||
|
||||
### Strict SNI Checking
|
||||
|
||||
With strict SNI checking, Traefik won't allow connections from clients connections
|
||||
|
@@ -26,11 +26,6 @@ spec:
|
||||
prefix: /foo
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Prefixing with /foo
|
||||
- "traefik.http.middlewares.add-foo.addprefix.prefix=/foo"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.add-foo.addprefix.prefix": "/foo"
|
||||
|
@@ -30,10 +30,6 @@ spec:
|
||||
secret: secretName
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
||||
@@ -119,11 +115,6 @@ data:
|
||||
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Declaring the user list
|
||||
- "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"
|
||||
@@ -195,10 +186,6 @@ data:
|
||||
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.basicauth.usersfile=/path/to/my/usersfile"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.basicauth.usersfile": "/path/to/my/usersfile"
|
||||
@@ -250,10 +237,6 @@ spec:
|
||||
realm: MyRealm
|
||||
```
|
||||
|
||||
```json tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.basicauth.realm=MyRealm"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.basicauth.realm": "MyRealm"
|
||||
@@ -299,10 +282,6 @@ spec:
|
||||
headerField: X-WebAuth-User
|
||||
```
|
||||
|
||||
```json tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.my-auth.basicauth.headerField=X-WebAuth-User"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.my-auth.basicauth.headerField": "X-WebAuth-User"
|
||||
@@ -343,10 +322,6 @@ spec:
|
||||
removeHeader: true
|
||||
```
|
||||
|
||||
```json tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.basicauth.removeheader=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.basicauth.removeheader": "true"
|
||||
|
@@ -30,11 +30,6 @@ spec:
|
||||
maxRequestBodyBytes: 2000000
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Sets the maximum request body to 2Mb
|
||||
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.limit.buffering.maxRequestBodyBytes": "2000000"
|
||||
@@ -86,10 +81,6 @@ spec:
|
||||
maxRequestBodyBytes: 2000000
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.limit.buffering.maxRequestBodyBytes": "2000000"
|
||||
@@ -134,10 +125,6 @@ spec:
|
||||
memRequestBodyBytes: 2000000
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.limit.buffering.memRequestBodyBytes=2000000"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.limit.buffering.memRequestBodyBytes": "2000000"
|
||||
@@ -184,10 +171,6 @@ spec:
|
||||
maxResponseBodyBytes: 2000000
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.limit.buffering.maxResponseBodyBytes=2000000"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.limit.buffering.maxResponseBodyBytes": "2000000"
|
||||
@@ -232,10 +215,6 @@ spec:
|
||||
memResponseBodyBytes: 2000000
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.limit.buffering.memResponseBodyBytes=2000000"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.limit.buffering.memResponseBodyBytes": "2000000"
|
||||
@@ -282,10 +261,6 @@ You can have the Buffering middleware replay the request with the help of the `r
|
||||
retryExpression: "IsNetworkError() && Attempts() < 2"
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.limit.buffering.retryExpression=IsNetworkError() && Attempts() < 2"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.limit.buffering.retryExpression": "IsNetworkError() && Attempts() < 2"
|
||||
|
@@ -83,17 +83,6 @@ spec:
|
||||
- 127.0.0.1/32
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.routers.router1.service=service1"
|
||||
- "traefik.http.routers.router1.middlewares=secured"
|
||||
- "traefik.http.routers.router1.rule=Host(`mydomain`)"
|
||||
- "traefik.http.middlewares.secured.chain.middlewares=https-only,known-ips,auth-users"
|
||||
- "traefik.http.middlewares.auth-users.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/"
|
||||
- "traefik.http.middlewares.https-only.redirectscheme.scheme=https"
|
||||
- "traefik.http.middlewares.known-ips.ipwhitelist.sourceRange=192.168.1.7,127.0.0.1/32"
|
||||
- "http.services.service1.loadbalancer.server.port=80"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.routers.router1.service": "service1",
|
||||
|
@@ -45,11 +45,6 @@ spec:
|
||||
expression: LatencyAtQuantileMS(50.0) > 100
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Latency Check
|
||||
- "traefik.http.middlewares.latency-check.circuitbreaker.expression=LatencyAtQuantileMS(50.0) > 100"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.latency-check.circuitbreaker.expression": "LatencyAtQuantileMS(50.0) > 100"
|
||||
|
@@ -25,11 +25,6 @@ spec:
|
||||
compress: {}
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Enable gzip compression
|
||||
- "traefik.http.middlewares.test-compress.compress=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-compress.compress": "true"
|
||||
@@ -63,59 +58,3 @@ http:
|
||||
* The response body is larger than `1400` bytes.
|
||||
* The `Accept-Encoding` request header contains `gzip`.
|
||||
* The response is not already compressed, i.e. the `Content-Encoding` response header is not already set.
|
||||
|
||||
## Configuration Options
|
||||
|
||||
### `excludedContentTypes`
|
||||
|
||||
`excludedContentTypes` specifies a list of content types to compare the `Content-Type` header of the incoming requests to before compressing.
|
||||
|
||||
The requests with content types defined in `excludedContentTypes` are not compressed.
|
||||
|
||||
Content types are compared in a case-insensitive, whitespace-ignored manner.
|
||||
|
||||
```yaml tab="Docker"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: test-compress
|
||||
spec:
|
||||
compress:
|
||||
excludedContentTypes:
|
||||
- text/event-stream
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-compress.compress.excludedcontenttypes": "text/event-stream"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-compress.compress]
|
||||
excludedContentTypes = ["text/event-stream"]
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
http:
|
||||
middlewares:
|
||||
test-compress:
|
||||
compress:
|
||||
excludedContentTypes:
|
||||
- text/event-stream
|
||||
```
|
||||
|
@@ -26,11 +26,6 @@ spec:
|
||||
secret: userssecret
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Declaring the user list
|
||||
- "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.digestauth.users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
|
||||
@@ -105,10 +100,6 @@ data:
|
||||
dGVzdDp0cmFlZmlrOmEyNjg4ZTAzMWVkYjRiZTZhMzc5N2YzODgyNjU1YzA1CnRlc3QyOnRyYWVmaWs6NTE4ODQ1ODAwZjllMmJmYjFmMWY3NDBlYzI0ZjA3NGUKCg==
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.digestauth.users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e"
|
||||
@@ -177,10 +168,6 @@ data:
|
||||
aHI5SEJCJDRIeHdnVWlyM0hQNEVzZ2dQL1FObzAK
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.digestauth.usersfile=/path/to/my/usersfile"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.digestauth.usersfile": "/path/to/my/usersfile"
|
||||
@@ -232,10 +219,6 @@ spec:
|
||||
realm: MyRealm
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.digestauth.realm=MyRealm"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.digestauth.realm": "MyRealm"
|
||||
@@ -281,8 +264,9 @@ spec:
|
||||
headerField: X-WebAuth-User
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User"
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -291,11 +275,6 @@ spec:
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares.my-auth.digestAuth]
|
||||
# ...
|
||||
@@ -330,10 +309,6 @@ spec:
|
||||
removeHeader: true
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.digestauth.removeheader=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.digestauth.removeheader": "true"
|
||||
|
@@ -35,13 +35,6 @@ spec:
|
||||
port: 80
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Dynamic Custom Error Page for 5XX Status Code
|
||||
- "traefik.http.middlewares.test-errorpage.errors.status=500-599"
|
||||
- "traefik.http.middlewares.test-errorpage.errors.service=serviceError"
|
||||
- "traefik.http.middlewares.test-errorpage.errors.query=/{status}.html"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-errorpage.errors.status": "500-599",
|
||||
|
@@ -28,11 +28,6 @@ spec:
|
||||
address: https://authserver.com/auth
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Forward authentication to authserver.com
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.address=https://authserver.com/auth"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.address": "https://authserver.com/auth"
|
||||
@@ -82,10 +77,6 @@ spec:
|
||||
address: https://authserver.com/auth
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.address=https://authserver.com/auth"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.address": "https://authserver.com/auth"
|
||||
@@ -131,10 +122,6 @@ spec:
|
||||
trustForwardHeader: true
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader": "true"
|
||||
@@ -184,10 +171,6 @@ spec:
|
||||
- X-Secret
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders": "X-Auth-User,X-Secret"
|
||||
@@ -252,10 +235,6 @@ data:
|
||||
ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.tls.ca=path/to/local.crt"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.tls.ca": "path/to/local.crt"
|
||||
@@ -311,10 +290,6 @@ spec:
|
||||
caOptional: true
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.tls.caOptional=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.tls.caOptional": "true"
|
||||
@@ -377,11 +352,6 @@ data:
|
||||
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert",
|
||||
@@ -451,11 +421,6 @@ data:
|
||||
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0=
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert",
|
||||
@@ -513,10 +478,6 @@ spec:
|
||||
insecureSkipVerify: true
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-auth.forwardauth.tls.InsecureSkipVerify=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-auth.forwardauth.tls.insecureSkipVerify": "true"
|
||||
|
@@ -32,11 +32,6 @@ spec:
|
||||
X-Custom-Response-Header: "value"
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test"
|
||||
- "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=value"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test",
|
||||
@@ -96,10 +91,6 @@ spec:
|
||||
X-Custom-Response-Header: "" # Removes
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test",
|
||||
@@ -155,11 +146,6 @@ spec:
|
||||
sslRedirect: "true"
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.testheader.headers.framedeny=true"
|
||||
- "traefik.http.middlewares.testheader.headers.sslredirect=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.testheader.headers.framedeny": "true",
|
||||
@@ -218,13 +204,6 @@ spec:
|
||||
addVaryHeader: "true"
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT"
|
||||
- "traefik.http.middlewares.testheader.headers.accesscontrolalloworigin=origin-list-or-null"
|
||||
- "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100"
|
||||
- "traefik.http.middlewares.testheader.headers.addvaryheader=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.testheader.headers.accesscontrolallowmethods": "GET,OPTIONS,PUT",
|
||||
|
@@ -24,11 +24,6 @@ spec:
|
||||
amount: 10
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Limiting to 10 simultaneous connections
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10"
|
||||
@@ -79,11 +74,6 @@ spec:
|
||||
amount: 10
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Limiting to 10 simultaneous connections
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10"
|
||||
@@ -156,8 +146,9 @@ spec:
|
||||
depth: 2
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2"
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -166,11 +157,6 @@ spec:
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-inflightreq.inflightreq]
|
||||
@@ -223,10 +209,6 @@ spec:
|
||||
- 192.168.1.7
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7"
|
||||
@@ -277,8 +259,9 @@ spec:
|
||||
requestHeaderName: username
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username"
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -287,11 +270,6 @@ spec:
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-inflightreq.inflightreq]
|
||||
@@ -328,8 +306,9 @@ spec:
|
||||
requestHost: true
|
||||
```
|
||||
|
||||
```yaml tab="Cosul Catalog"
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true"
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -338,11 +317,6 @@ spec:
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-inflightreq.inflightreq]
|
||||
|
@@ -27,11 +27,6 @@ spec:
|
||||
- 192.168.1.7
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Accepts request from defined IP
|
||||
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-ipwhitelist.ipwhitelist.sourcerange": "127.0.0.1/32,192.168.1.7"
|
||||
@@ -66,7 +61,7 @@ http:
|
||||
|
||||
### `sourceRange`
|
||||
|
||||
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using CIDR notation).
|
||||
The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs).
|
||||
|
||||
### `ipStrategy`
|
||||
|
||||
@@ -100,10 +95,11 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th
|
||||
depth: 2
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
```yaml tab="Rancher"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||
labels:
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -113,13 +109,6 @@ The `depth` option tells Traefik to use the `X-Forwarded-For` header and take th
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
labels:
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.sourcerange=127.0.0.1/32, 192.168.1.7"
|
||||
- "traefik.http.middlewares.testIPwhitelist.ipwhitelist.ipstrategy.depth=2"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Whitelisting Based on `X-Forwarded-For` with `depth=2`
|
||||
[http.middlewares]
|
||||
@@ -179,9 +168,10 @@ spec:
|
||||
- 192.168.1.7
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
```yaml tab="Rancher"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -190,12 +180,6 @@ spec:
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ipwhitelist.ipwhitelist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Exclude from `X-Forwarded-For`
|
||||
[http.middlewares]
|
||||
|
@@ -63,13 +63,6 @@ spec:
|
||||
- name: stripprefix
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Create a middleware named `foo-add-prefix`
|
||||
- "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo"
|
||||
# Apply the middleware named `foo-add-prefix` to the router named `router1`
|
||||
- "traefik.http.routers.router1.middlewares=foo-add-prefix@consulcatalog"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.foo-add-prefix.addprefix.prefix": "/foo",
|
||||
|
@@ -29,11 +29,6 @@ spec:
|
||||
pem: true
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Pass the escaped pem in the `X-Forwarded-Tls-Client-Cert` header
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem": "true"
|
||||
@@ -116,25 +111,26 @@ http:
|
||||
domainComponent: true
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
```yaml tab="Rancher"
|
||||
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -158,28 +154,6 @@ http:
|
||||
"traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber": "true"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true"
|
||||
- "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
# Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header
|
||||
|
@@ -28,13 +28,6 @@ spec:
|
||||
burst: 50
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Here, an average of 100 requests per second is allowed.
|
||||
# In addition, a burst of 50 requests is allowed.
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.average=100"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=50"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-ratelimit.ratelimit.average": "100",
|
||||
@@ -92,10 +85,6 @@ spec:
|
||||
average: 100
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.average=100"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-ratelimit.ratelimit.average": "100",
|
||||
@@ -141,10 +130,6 @@ spec:
|
||||
burst: 100
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-ratelimit.ratelimit.burst": "100",
|
||||
@@ -153,7 +138,8 @@ spec:
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100"
|
||||
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
@@ -218,8 +204,9 @@ spec:
|
||||
- 192.168.1.7
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -228,11 +215,6 @@ spec:
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ratelimit.rateLimit]
|
||||
@@ -286,8 +268,9 @@ spec:
|
||||
requestHeaderName: username
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername=username"
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername=username"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -296,11 +279,6 @@ spec:
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername=username"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ratelimit.rateLimit]
|
||||
@@ -337,8 +315,9 @@ spec:
|
||||
requestHost: true
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost=true"
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost=true"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
@@ -347,11 +326,6 @@ spec:
|
||||
}
|
||||
```
|
||||
|
||||
```yaml tab="Rancher"
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost=true"
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-ratelimit.rateLimit]
|
||||
|
@@ -31,13 +31,6 @@ spec:
|
||||
replacement: http://mydomain/${1}
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Redirect with domain replacement
|
||||
# Note: all dollar signs need to be doubled for escaping.
|
||||
- "traefik.http.middlewares.test-redirectregex.redirectregex.regex=^http://localhost/(.*)"
|
||||
- "traefik.http.middlewares.test-redirectregex.redirectregex.replacement=http://mydomain/$${1}"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-redirectregex.redirectregex.regex": "^http://localhost/(.*)",
|
||||
|
@@ -28,12 +28,6 @@ spec:
|
||||
scheme: https
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Redirect to https
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme": "https"
|
||||
|
@@ -28,11 +28,6 @@ spec:
|
||||
path: /foo
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Replace the path by /foo
|
||||
- "traefik.http.middlewares.test-replacepath.replacepath.path=/foo"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-replacepath.replacepath.path": "/foo"
|
||||
|
@@ -30,12 +30,6 @@ spec:
|
||||
replacement: /bar/$1
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Replace path with regex
|
||||
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex=^/foo/(.*)"
|
||||
- "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$1"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-replacepathregex.replacepathregex.regex": "^/foo/(.*)",
|
||||
|
@@ -29,11 +29,6 @@ spec:
|
||||
attempts: 4
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Retry to send request 4 times
|
||||
- "traefik.http.middlewares.test-retry.retry.attempts=4"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-retry.retry.attempts": "4"
|
||||
|
@@ -30,11 +30,6 @@ spec:
|
||||
- /fiibar
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Strip prefix /foobar and /fiibar
|
||||
- "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar,/fiibar"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-stripprefix.stripprefix.prefixes": "/foobar,/fiibar"
|
||||
|
@@ -23,10 +23,6 @@ spec:
|
||||
- "/foo/[a-z0-9]+/[0-9]+/"
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
- "traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex=/foo/[a-z0-9]+/[0-9]+/"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex": "/foo/[a-z0-9]+/[0-9]+/"
|
||||
|
@@ -104,7 +104,7 @@ Then any router can refer to an instance of the wanted middleware.
|
||||
|
||||
```yaml tab="K8s IngressRoute"
|
||||
# The definitions below require the definitions for the Middleware and IngressRoute kinds.
|
||||
# https://docs.traefik.io/v2.1/reference/dynamic-configuration/kubernetes-crd/#definitions
|
||||
# https://docs.traefik.io/v2.0/providers/kubernetes-crd/#traefik-ingressroute-definition
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
@@ -278,7 +278,7 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o
|
||||
|
||||
```yaml tab="K8s IngressRoute"
|
||||
# The definitions below require the definitions for the TLSOption and IngressRoute kinds.
|
||||
# https://docs.traefik.io/v2.1/reference/dynamic-configuration/kubernetes-crd/#definitions
|
||||
# https://docs.traefik.io/v2.0/providers/kubernetes-crd/#traefik-ingressroute-definition
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TLSOption
|
||||
metadata:
|
||||
@@ -1093,7 +1093,7 @@ Supported [providers](../providers/overview.md), for now:
|
||||
* [ ] Azure Service Fabric
|
||||
* [ ] BoltDB
|
||||
* [ ] Consul
|
||||
* [x] Consul Catalog
|
||||
* [ ] Consul Catalog
|
||||
* [x] Docker
|
||||
* [ ] DynamoDB
|
||||
* [ ] ECS
|
||||
|
@@ -1,99 +0,0 @@
|
||||
# Migration: Steps needed between the versions
|
||||
|
||||
## v2.0 to v2.1
|
||||
|
||||
In v2.1, a new CRD called `TraefikService` was added. While updating an installation to v2.1,
|
||||
it is required to apply that CRD before as well as enhance the existing `ClusterRole` definition to allow Traefik to use that CRD.
|
||||
|
||||
To add that CRD and enhance the permissions, following definitions need to be applied to the cluster.
|
||||
|
||||
```yaml tab="TraefikService"
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: traefikservices.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: TraefikService
|
||||
plural: traefikservices
|
||||
singular: traefikservice
|
||||
scope: Namespaced
|
||||
```
|
||||
|
||||
```yaml tab="ClusterRole"
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: traefik-ingress-controller
|
||||
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
- endpoints
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- ingresses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- ingresses/status
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- traefik.containo.us
|
||||
resources:
|
||||
- middlewares
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- traefik.containo.us
|
||||
resources:
|
||||
- ingressroutes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- traefik.containo.us
|
||||
resources:
|
||||
- ingressroutetcps
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- traefik.containo.us
|
||||
resources:
|
||||
- tlsoptions
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- traefik.containo.us
|
||||
resources:
|
||||
- traefikservices
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
```
|
||||
|
||||
After having both resources applied, Traefik will work properly.
|
@@ -116,25 +116,3 @@ metrics:
|
||||
--entryPoints.metrics.address=:8082
|
||||
--metrics.prometheus.entryPoint=metrics
|
||||
```
|
||||
|
||||
#### `manualRouting`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
If `manualRouting` is `true`, it disables the default internal router in order to allow one to create a custom router for the `prometheus@internal` service.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[metrics]
|
||||
[metrics.prometheus]
|
||||
manualRouting = true
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
metrics:
|
||||
prometheus:
|
||||
manualRouting: true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--metrics.prometheus.manualrouting=true
|
||||
```
|
||||
|
@@ -103,25 +103,3 @@ metrics:
|
||||
```bash tab="CLI"
|
||||
--metrics.statsd.pushInterval=10s
|
||||
```
|
||||
|
||||
#### `prefix`
|
||||
|
||||
_Optional, Default="traefik"_
|
||||
|
||||
The prefix to use for metrics collection.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[metrics]
|
||||
[metrics.statsD]
|
||||
prefix = "traefik"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
metrics:
|
||||
statsD:
|
||||
prefix: traefik
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--metrics.statsd.prefix="traefik"
|
||||
```
|
@@ -19,36 +19,6 @@ deploy:
|
||||
- "traefik.http.services.dummy-svc.loadbalancer.server.port=9999"
|
||||
```
|
||||
|
||||
```yaml tab="Kubernetes CRD"
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: traefik-dashboard
|
||||
spec:
|
||||
routes:
|
||||
- match: Host(`traefik.domain.com`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: api@internal
|
||||
kind: TraefikService
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: Middleware
|
||||
metadata:
|
||||
name: auth
|
||||
spec:
|
||||
basicAuth:
|
||||
secret: secretName # Kubernetes secret named "secretName"
|
||||
```
|
||||
|
||||
```yaml tab="Consul Catalog"
|
||||
# Dynamic Configuration
|
||||
- "traefik.http.routers.api.rule=Host(`traefik.domain.com`)"
|
||||
- "traefik.http.routers.api.service=api@internal"
|
||||
- "traefik.http.routers.api.middlewares=auth"
|
||||
- "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
||||
```
|
||||
|
||||
```json tab="Marathon"
|
||||
"labels": {
|
||||
"traefik.http.routers.api.rule": "Host(`traefik.domain.com`)",
|
||||
|
@@ -58,23 +58,3 @@ ping:
|
||||
--entryPoints.ping.address=:8082
|
||||
--ping.entryPoint=ping
|
||||
```
|
||||
|
||||
### `manualRouting`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
If `manualRouting` is `true`, it disables the default internal router in order to allow one to create a custom router for the `ping@internal` service.
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[ping]
|
||||
manualRouting = true
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
ping:
|
||||
manualRouting: true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--ping.manualrouting=true
|
||||
```
|
||||
|
@@ -1,603 +0,0 @@
|
||||
# Traefik & Consul Catalog
|
||||
|
||||
A Story of Tags, Services & Instances
|
||||
{: .subtitle }
|
||||
|
||||

|
||||
|
||||
Attach tags to your services and let Traefik do the rest!
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
??? example "Configuring Consul Catalog & Deploying / Exposing Services"
|
||||
|
||||
Enabling the consul catalog provider
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog: {}
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog=true
|
||||
```
|
||||
|
||||
Attaching tags to services
|
||||
|
||||
```yaml
|
||||
- traefik.http.services.my-service.rule=Host(`mydomain.com`)
|
||||
```
|
||||
|
||||
## Routing Configuration
|
||||
|
||||
See the dedicated section in [routing](../routing/providers/consul-catalog.md).
|
||||
|
||||
## Provider Configuration
|
||||
|
||||
### `refreshInterval`
|
||||
|
||||
_Optional, Default=15s_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
refreshInterval = "30s"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
refreshInterval: 30s
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.refreshInterval=30s
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines the polling interval.
|
||||
|
||||
### `prefix`
|
||||
|
||||
_required, Default="traefik"_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
prefix = "test"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
prefix: test
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.prefix=test
|
||||
# ...
|
||||
```
|
||||
|
||||
The prefix for Consul Catalog tags defining traefik labels.
|
||||
|
||||
### `requireConsistent`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
requireConsistent = true
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
requireConsistent: true
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.requireConsistent=true
|
||||
# ...
|
||||
```
|
||||
|
||||
Forces the read to be fully consistent.
|
||||
|
||||
### `stale`
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
stale = true
|
||||
# ...
|
||||
```
|
||||
|
||||
```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`
|
||||
|
||||
Defines the Consul server endpoint.
|
||||
|
||||
#### `address`
|
||||
|
||||
_Optional, Default="http://127.0.0.1:8500"_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
[providers.consulCatalog.endpoint]
|
||||
address = "http://127.0.0.1:8500"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
address: http://127.0.0.1:8500
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.address=http://127.0.0.1:8500
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines the address of the Consul server.
|
||||
|
||||
#### `scheme`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
[providers.consulCatalog.endpoint]
|
||||
scheme = "https"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
scheme: https
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.scheme=https
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines the URI scheme for the Consul server.
|
||||
|
||||
#### `datacenter`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
[providers.consulCatalog.endpoint]
|
||||
datacenter = "test"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
datacenter: test
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.datacenter=test
|
||||
# ...
|
||||
```
|
||||
|
||||
Defines the Data center to use.
|
||||
If not provided, the default agent data center is used.
|
||||
|
||||
#### `token`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
[providers.consulCatalog.endpoint]
|
||||
token = "test"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
token: test
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.token=test
|
||||
# ...
|
||||
```
|
||||
|
||||
Token is used to provide a per-request ACL token which overrides the agent's default token.
|
||||
|
||||
#### `endpointWaitTime`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
[providers.consulCatalog.endpoint]
|
||||
endpointWaitTime = "15s"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
endpointWaitTime: 15s
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.endpointwaittime=15s
|
||||
# ...
|
||||
```
|
||||
|
||||
WaitTime limits how long a Watch will block.
|
||||
If not provided, the agent default values will be used
|
||||
|
||||
#### `httpAuth`
|
||||
|
||||
_Optional_
|
||||
|
||||
Used to authenticate http client with HTTP Basic Authentication.
|
||||
|
||||
##### `username`
|
||||
|
||||
_Optional_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.httpAuth]
|
||||
username = "test"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
httpAuth:
|
||||
username: test
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.httpauth.username=test
|
||||
```
|
||||
|
||||
Username to use for HTTP Basic Authentication
|
||||
|
||||
##### `password`
|
||||
|
||||
_Optional_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.httpAuth]
|
||||
password = "test"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
httpAuth:
|
||||
password: test
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.httpauth.password=test
|
||||
```
|
||||
|
||||
Password to use for HTTP Basic Authentication
|
||||
|
||||
#### `tls`
|
||||
|
||||
_Optional_
|
||||
|
||||
Defines TLS options for Consul server endpoint.
|
||||
|
||||
##### `ca`
|
||||
|
||||
_Optional_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
ca = "path/to/ca.crt"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
tls:
|
||||
ca: path/to/ca.crt
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.tls.ca=path/to/ca.crt
|
||||
```
|
||||
|
||||
`ca` is the path to the CA certificate used for Consul communication, defaults to the system bundle if not specified.
|
||||
|
||||
##### `caOptional`
|
||||
|
||||
_Optional_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
caOptional = true
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
tls:
|
||||
caOptional: true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.tls.caoptional=true
|
||||
```
|
||||
|
||||
Policy followed for the secured connection with TLS Client Authentication to Consul.
|
||||
Requires `tls.ca` to be defined.
|
||||
|
||||
- `true`: VerifyClientCertIfGiven
|
||||
- `false`: RequireAndVerifyClientCert
|
||||
- if `tls.ca` is undefined NoClientCert
|
||||
|
||||
##### `cert`
|
||||
|
||||
_Optional_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
cert = "path/to/foo.cert"
|
||||
key = "path/to/foo.key"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
tls:
|
||||
cert: path/to/foo.cert
|
||||
key: path/to/foo.key
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.tls.cert=path/to/foo.cert
|
||||
--providers.consulcatalog.endpoint.tls.key=path/to/foo.key
|
||||
```
|
||||
|
||||
`cert` is the path to the public certificate for Consul communication.
|
||||
If this is set then you need to also set `key.
|
||||
|
||||
##### `key`
|
||||
|
||||
_Optional_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
cert = "path/to/foo.cert"
|
||||
key = "path/to/foo.key"
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
tls:
|
||||
cert: path/to/foo.cert
|
||||
key: path/to/foo.key
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.tls.cert=path/to/foo.cert
|
||||
--providers.consulcatalog.endpoint.tls.key=path/to/foo.key
|
||||
```
|
||||
|
||||
`key` is the path to the private key for Consul communication.
|
||||
If this is set then you need to also set `cert`.
|
||||
|
||||
##### `insecureSkipVerify`
|
||||
|
||||
_Optional_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
insecureSkipVerify = true
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
endpoint:
|
||||
tls:
|
||||
insecureSkipVerify: true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.endpoint.tls.insecureskipverify=true
|
||||
```
|
||||
|
||||
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` tag 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 service if no routing rule was defined by a tag, 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 (i.e. tags beginning with the `prefix`) defined on this service.
|
||||
|
||||
The option can be overridden on an instance basis with the `traefik.http.routers.{name-of-your-choice}.rule` tag.
|
||||
|
||||
### `constraints`
|
||||
|
||||
_Optional, Default=""_
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[providers.consulCatalog]
|
||||
constraints = "Tag(`a.tag.name`)"
|
||||
# ...
|
||||
```
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
providers:
|
||||
consulCatalog:
|
||||
constraints: "Tag(`a.tag.name`)"
|
||||
# ...
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--providers.consulcatalog.constraints="Tag(`a.tag.name`)"
|
||||
# ...
|
||||
```
|
||||
|
||||
Constraints is an expression that Traefik matches against the service's tags to determine whether to create any route for that service.
|
||||
That is to say, if none of the service's tags match the expression, no route for that service is created.
|
||||
If the expression is empty, all detected services are included.
|
||||
|
||||
The expression syntax is based on the `Tag("tag")`, and `TagRegex("tag")` functions,
|
||||
as well as the usual boolean logic, as shown in examples below.
|
||||
|
||||
??? example "Constraints Expression Examples"
|
||||
|
||||
```toml
|
||||
# Includes only services having the tag `a.tag.name=foo`
|
||||
constraints = "Tag(`a.tag.name=foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Excludes services having any tag `a.tag.name=foo`
|
||||
constraints = "!Tag(`a.tag.name=foo`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND.
|
||||
constraints = "Tag(`a.tag.name`) && Tag(`another.tag.name`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical OR.
|
||||
constraints = "Tag(`a.tag.name`) || Tag(`another.tag.name`)"
|
||||
```
|
||||
|
||||
```toml
|
||||
# With logical AND and OR, with precedence set by parentheses.
|
||||
constraints = "Tag(`a.tag.name`) && (Tag(`another.tag.name`) || Tag(`yet.another.tag.name`))"
|
||||
```
|
||||
|
||||
```toml
|
||||
# Includes only services having a tag matching the `a\.tag\.t.+` regular expression.
|
||||
constraints = "TagRegex(`a\.tag\.t.+`)"
|
||||
```
|
||||
|
||||
See also [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery).
|
@@ -86,7 +86,7 @@ and [Docker Swarm Mode](https://docs.docker.com/engine/swarm/).
|
||||
## Routing Configuration
|
||||
|
||||
When using Docker as a [provider](https://docs.traefik.io/providers/overview/),
|
||||
Traefik uses [container labels](https://docs.docker.com/engine/reference/commandline/run/#set-metadata-on-container--l---label---label-file) to retrieve its routing configuration.
|
||||
Trafik uses [container labels](https://docs.docker.com/engine/reference/commandline/run/#set-metadata-on-container--l---label---label-file) to retrieve its routing configuration.
|
||||
|
||||
See the list of labels in the dedicated [routing](../routing/providers/docker.md) section.
|
||||
|
||||
|
@@ -8,43 +8,9 @@ Traefik used to support Kubernetes only through the [Kubernetes Ingress provider
|
||||
However, as the community expressed the need to benefit from Traefik features without resorting to (lots of) annotations,
|
||||
we ended up writing a [Custom Resource Definition](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) (alias CRD in the following) for an IngressRoute type, defined below, in order to provide a better way to configure access to a Kubernetes cluster.
|
||||
|
||||
## Configuration Requirements
|
||||
|
||||
!!! tip "All Steps for a Successful Deployment"
|
||||
|
||||
* Add/update **all** the Traefik resources [definitions](../reference/dynamic-configuration/kubernetes-crd.md#definitions)
|
||||
* Add/update the [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) for the Traefik custom resources
|
||||
* Use [Helm Chart](../getting-started/install-traefik.md#use-the-helm-chart) or use a custom Traefik Deployment
|
||||
* Enable the kubernetesCRD provider
|
||||
* Apply the needed kubernetesCRD provider [configuration](#provider-configuration)
|
||||
* Add all needed traefik custom [resources](../reference/dynamic-configuration/kubernetes-crd.md#resources)
|
||||
|
||||
??? example "Initializing Resource Definition and RBAC"
|
||||
|
||||
```yaml tab="Traefik Resource Definition"
|
||||
# All resources definition must be declared
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition.yml"
|
||||
```
|
||||
|
||||
```yaml tab="RBAC for Traefik CRD"
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-crd-rbac.yml"
|
||||
```
|
||||
|
||||
## Resource Configuration
|
||||
|
||||
When using KubernetesCRD as a provider,
|
||||
Traefik uses [Custom Resource Definition](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) to retrieve its routing configuration.
|
||||
Traefik Custom Resource Definitions are a Kubernetes implementation of the Traefik concepts. The main particularities are:
|
||||
|
||||
* The usage of `name` **and** `namespace` to refer to another Kubernetes resource.
|
||||
* The usage of [secret](https://kubernetes.io/docs/concepts/configuration/secret/) for sensible data like:
|
||||
* TLS certificate.
|
||||
* Authentication data.
|
||||
* The structure of the configuration.
|
||||
* The obligation to declare all the [definitions](../reference/dynamic-configuration/kubernetes-crd.md#definitions).
|
||||
|
||||
The Traefik CRD are building blocks which you can assemble according to your needs.
|
||||
See the list of CRDs in the dedicated [routing section](../routing/providers/kubernetes-crd.md).
|
||||
See the dedicated section in [routing](../routing/providers/kubernetes-crd.md).
|
||||
|
||||
## LetsEncrypt Support with the Custom Resource Definition Provider
|
||||
|
||||
|
@@ -26,14 +26,13 @@ Even if each provider is different, we can categorize them in four groups:
|
||||
|
||||
Below is the list of the currently supported providers in Traefik.
|
||||
|
||||
| Provider | Type | Configuration Type |
|
||||
|---------------------------------------|--------------|--------------------|
|
||||
| [Docker](./docker.md) | Orchestrator | Label |
|
||||
| [Kubernetes](./kubernetes-crd.md) | Orchestrator | Custom Resource |
|
||||
| [Consul Catalog](./consul-catalog.md) | Orchestrator | Label |
|
||||
| [Marathon](./marathon.md) | Orchestrator | Label |
|
||||
| [Rancher](./rancher.md) | Orchestrator | Label |
|
||||
| [File](./file.md) | Manual | TOML/YAML format |
|
||||
| Provider | Type | Configuration Type |
|
||||
|-----------------------------------|--------------|--------------------|
|
||||
| [Docker](./docker.md) | Orchestrator | Label |
|
||||
| [Kubernetes](./kubernetes-crd.md) | Orchestrator | Custom Resource |
|
||||
| [Marathon](./marathon.md) | Orchestrator | Label |
|
||||
| [Rancher](./rancher.md) | Orchestrator | Label |
|
||||
| [File](./file.md) | Manual | TOML/YAML format |
|
||||
|
||||
!!! info "More Providers"
|
||||
|
||||
@@ -91,7 +90,6 @@ or with a finer granularity mechanism based on constraints.
|
||||
List of providers that support that feature:
|
||||
|
||||
- [Docker](./docker.md#exposedbydefault)
|
||||
- [Consul Catalog](./consul-catalog.md#exposedbydefault)
|
||||
- [Rancher](./rancher.md#exposedbydefault)
|
||||
- [Marathon](./marathon.md#exposedbydefault)
|
||||
|
||||
@@ -100,7 +98,6 @@ List of providers that support that feature:
|
||||
List of providers that support constraints:
|
||||
|
||||
- [Docker](./docker.md#constraints)
|
||||
- [Consul Catalog](./consul-catalog.md#constraints)
|
||||
- [Rancher](./rancher.md#constraints)
|
||||
- [Marathon](./marathon.md#constraints)
|
||||
- [Kubernetes CRD](./kubernetes-crd.md#labelselector)
|
||||
|
@@ -1,11 +0,0 @@
|
||||
# Consul Catalog Configuration Reference
|
||||
|
||||
Dynamic configuration with Consul Catalog
|
||||
{: .subtitle }
|
||||
|
||||
The labels are case insensitive.
|
||||
|
||||
```yaml
|
||||
--8<-- "content/reference/dynamic-configuration/consul-catalog.yml"
|
||||
--8<-- "content/reference/dynamic-configuration/docker-labels.yml"
|
||||
```
|
@@ -1 +0,0 @@
|
||||
- "traefik.enable=true"
|
@@ -319,19 +319,15 @@
|
||||
[tls.options]
|
||||
[tls.options.Options0]
|
||||
minVersion = "foobar"
|
||||
maxVersion = "foobar"
|
||||
cipherSuites = ["foobar", "foobar"]
|
||||
sniStrict = true
|
||||
curvePreferences = ["foobar", "foobar"]
|
||||
[tls.options.Options0.clientAuth]
|
||||
caFiles = ["foobar", "foobar"]
|
||||
clientAuthType = "foobar"
|
||||
[tls.options.Options1]
|
||||
minVersion = "foobar"
|
||||
maxVersion = "foobar"
|
||||
cipherSuites = ["foobar", "foobar"]
|
||||
sniStrict = true
|
||||
curvePreferences = ["foobar", "foobar"]
|
||||
[tls.options.Options1.clientAuth]
|
||||
caFiles = ["foobar", "foobar"]
|
||||
clientAuthType = "foobar"
|
||||
|
@@ -351,11 +351,7 @@ tls:
|
||||
options:
|
||||
Options0:
|
||||
minVersion: foobar
|
||||
maxVersion: foobar
|
||||
cipherSuites:
|
||||
- foobar
|
||||
- foobar
|
||||
curvePreferences:
|
||||
- foobar
|
||||
- foobar
|
||||
clientAuth:
|
||||
@@ -366,11 +362,7 @@ tls:
|
||||
sniStrict: true
|
||||
Options1:
|
||||
minVersion: foobar
|
||||
maxVersion: foobar
|
||||
cipherSuites:
|
||||
- foobar
|
||||
- foobar
|
||||
curvePreferences:
|
||||
- foobar
|
||||
- foobar
|
||||
clientAuth:
|
||||
|
@@ -1,73 +0,0 @@
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: ingressroutes.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: IngressRoute
|
||||
plural: ingressroutes
|
||||
singular: ingressroute
|
||||
scope: Namespaced
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: middlewares.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: Middleware
|
||||
plural: middlewares
|
||||
singular: middleware
|
||||
scope: Namespaced
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: ingressroutetcps.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: IngressRouteTCP
|
||||
plural: ingressroutetcps
|
||||
singular: ingressroutetcp
|
||||
scope: Namespaced
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: tlsoptions.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: TLSOption
|
||||
plural: tlsoptions
|
||||
singular: tlsoption
|
||||
scope: Namespaced
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: traefikservices.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: TraefikService
|
||||
plural: traefikservices
|
||||
singular: traefikservice
|
||||
scope: Namespaced
|
@@ -1,13 +0,0 @@
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: ingressroutetcps.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: IngressRouteTCP
|
||||
plural: ingressroutetcps
|
||||
singular: ingressroutetcp
|
||||
scope: Namespaced
|
@@ -1,57 +0,0 @@
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: traefik-ingress-controller
|
||||
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- services
|
||||
- endpoints
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- ingresses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- ingresses/status
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- traefik.containo.us
|
||||
resources:
|
||||
- middlewares
|
||||
- ingressroutes
|
||||
- traefikservices
|
||||
- ingressroutetcps
|
||||
- tlsoptions
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: traefik-ingress-controller
|
||||
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: traefik-ingress-controller
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: traefik-ingress-controller
|
||||
namespace: default
|
@@ -1,157 +0,0 @@
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: wrr2
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
weighted:
|
||||
services:
|
||||
- name: s1
|
||||
weight: 1
|
||||
port: 80
|
||||
# Optional, as it is the default value
|
||||
kind: Service
|
||||
- name: s3
|
||||
weight: 1
|
||||
port: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: wrr1
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
weighted:
|
||||
services:
|
||||
- name: wrr2
|
||||
kind: TraefikService
|
||||
weight: 1
|
||||
- name: s3
|
||||
weight: 1
|
||||
port: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: mirror1
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
mirroring:
|
||||
name: s1
|
||||
port: 80
|
||||
mirrors:
|
||||
- name: s3
|
||||
percent: 20
|
||||
port: 80
|
||||
- name: mirror2
|
||||
kind: TraefikService
|
||||
percent: 20
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: mirror2
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
mirroring:
|
||||
name: wrr2
|
||||
kind: TraefikService
|
||||
mirrors:
|
||||
- name: s2
|
||||
# Optional, as it is the default value
|
||||
kind: Service
|
||||
percent: 20
|
||||
port: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: ingressroute
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
- web-secure
|
||||
routes:
|
||||
- match: Host(`foo.com`) && PathPrefix(`/bar`)
|
||||
kind: Rule
|
||||
priority: 12
|
||||
# defining several services is possible and allowed, but for now the servers of
|
||||
# all the services (for a given route) get merged altogether under the same
|
||||
# load-balancing strategy.
|
||||
services:
|
||||
- name: s1
|
||||
port: 80
|
||||
healthCheck:
|
||||
path: /health
|
||||
host: baz.com
|
||||
intervalSeconds: 7
|
||||
timeoutSeconds: 60
|
||||
# strategy defines the load balancing strategy between the servers. It defaults
|
||||
# to Round Robin, and for now only Round Robin is supported anyway.
|
||||
strategy: RoundRobin
|
||||
- name: s2
|
||||
port: 433
|
||||
healthCheck:
|
||||
path: /health
|
||||
host: baz.com
|
||||
intervalSeconds: 7
|
||||
timeoutSeconds: 60
|
||||
- match: PathPrefix(`/misc`)
|
||||
services:
|
||||
- name: s3
|
||||
port: 80
|
||||
middlewares:
|
||||
- name: stripprefix
|
||||
- name: addprefix
|
||||
- match: PathPrefix(`/misc`)
|
||||
services:
|
||||
- name: s3
|
||||
# Optional, as it is the default value
|
||||
kind: Service
|
||||
port: 8443
|
||||
# scheme allow to override the scheme for the service. (ex: https or h2c)
|
||||
scheme: https
|
||||
- match: PathPrefix(`/lb`)
|
||||
services:
|
||||
- name: wrr1
|
||||
kind: TraefikService
|
||||
- match: PathPrefix(`/mirrored`)
|
||||
services:
|
||||
- name: mirror1
|
||||
kind: TraefikService
|
||||
# use an empty tls object for TLS with Let's Encrypt
|
||||
tls:
|
||||
secretName: supersecret
|
||||
options:
|
||||
name: myTLSOption
|
||||
namespace: default
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRouteTCP
|
||||
metadata:
|
||||
name: ingressroutetcp.crd
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
entryPoints:
|
||||
- footcp
|
||||
routes:
|
||||
- match: HostSNI(`bar.com`)
|
||||
services:
|
||||
- name: whoamitcp
|
||||
port: 8080
|
||||
tls:
|
||||
secretName: foosecret
|
||||
passthrough: false
|
||||
options:
|
||||
name: myTLSOption
|
||||
namespace: default
|
@@ -3,20 +3,6 @@
|
||||
Dynamic configuration with Kubernetes Custom Resource
|
||||
{: .subtitle }
|
||||
|
||||
## Definitions
|
||||
|
||||
```yaml
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-crd-definition.yml"
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
```yaml
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-crd-resource.yml"
|
||||
```
|
||||
|
||||
## RBAC
|
||||
|
||||
```yaml
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-crd-rbac.yml"
|
||||
--8<-- "content/reference/dynamic-configuration/kubernetes-crd.yml"
|
||||
```
|
||||
|
@@ -56,94 +56,6 @@ spec:
|
||||
singular: ingressroutetcp
|
||||
scope: Namespaced
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: traefikservices.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: TraefikService
|
||||
plural: traefikservices
|
||||
singular: traefikservice
|
||||
scope: Namespaced
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: wrr2
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
weighted:
|
||||
services:
|
||||
- name: s1
|
||||
weight: 1
|
||||
port: 80
|
||||
# Optional, as it is the default value
|
||||
kind: Service
|
||||
- name: s3
|
||||
weight: 1
|
||||
port: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: wrr1
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
weighted:
|
||||
services:
|
||||
- name: wrr2
|
||||
kind: TraefikService
|
||||
weight: 1
|
||||
- name: s3
|
||||
weight: 1
|
||||
port: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: mirror1
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
mirroring:
|
||||
name: s1
|
||||
port: 80
|
||||
mirrors:
|
||||
- name: s3
|
||||
percent: 20
|
||||
port: 80
|
||||
- name: mirror2
|
||||
kind: TraefikService
|
||||
percent: 20
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: mirror2
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
mirroring:
|
||||
name: wrr2
|
||||
kind: TraefikService
|
||||
mirrors:
|
||||
- name: s2
|
||||
# Optional, as it is the default value
|
||||
kind: Service
|
||||
percent: 20
|
||||
port: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRoute
|
||||
@@ -188,19 +100,9 @@ spec:
|
||||
- match: PathPrefix(`/misc`)
|
||||
services:
|
||||
- name: s3
|
||||
# Optional, as it is the default value
|
||||
kind: Service
|
||||
port: 8443
|
||||
# scheme allow to override the scheme for the service. (ex: https or h2c)
|
||||
scheme: https
|
||||
- match: PathPrefix(`/lb`)
|
||||
services:
|
||||
- name: wrr1
|
||||
kind: TraefikService
|
||||
- match: PathPrefix(`/mirrored`)
|
||||
services:
|
||||
- name: mirror1
|
||||
kind: TraefikService
|
||||
# use an empty tls object for TLS with Let's Encrypt
|
||||
tls:
|
||||
secretName: supersecret
|
||||
|
@@ -213,9 +213,6 @@ Buckets for latency metrics. (Default: ```0.100000, 0.300000, 1.200000, 5.000000
|
||||
`--metrics.prometheus.entrypoint`:
|
||||
EntryPoint (Default: ```traefik```)
|
||||
|
||||
`--metrics.prometheus.manualrouting`:
|
||||
Manual routing (Default: ```false```)
|
||||
|
||||
`--metrics.statsd`:
|
||||
StatsD metrics exporter type. (Default: ```false```)
|
||||
|
||||
@@ -228,9 +225,6 @@ StatsD address. (Default: ```localhost:8125```)
|
||||
`--metrics.statsd.addserviceslabels`:
|
||||
Enable metrics on services. (Default: ```true```)
|
||||
|
||||
`--metrics.statsd.prefix`:
|
||||
Prefix to use for metrics collection. (Default: ```traefik```)
|
||||
|
||||
`--metrics.statsd.pushinterval`:
|
||||
StatsD push interval. (Default: ```10```)
|
||||
|
||||
@@ -240,69 +234,6 @@ Enable ping. (Default: ```false```)
|
||||
`--ping.entrypoint`:
|
||||
EntryPoint (Default: ```traefik```)
|
||||
|
||||
`--ping.manualrouting`:
|
||||
Manual routing (Default: ```false```)
|
||||
|
||||
`--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.
|
||||
|
||||
`--providers.consulcatalog.defaultrule`:
|
||||
Default rule. (Default: ```Host(`{{ normalize .Name }}`)```)
|
||||
|
||||
`--providers.consulcatalog.endpoint.address`:
|
||||
The address of the Consul server (Default: ```http://127.0.0.1:8500```)
|
||||
|
||||
`--providers.consulcatalog.endpoint.datacenter`:
|
||||
Data center to use. If not provided, the default agent data center is used
|
||||
|
||||
`--providers.consulcatalog.endpoint.endpointwaittime`:
|
||||
WaitTime limits how long a Watch will block. If not provided, the agent default values will be used (Default: ```0```)
|
||||
|
||||
`--providers.consulcatalog.endpoint.httpauth.password`:
|
||||
Basic Auth password
|
||||
|
||||
`--providers.consulcatalog.endpoint.httpauth.username`:
|
||||
Basic Auth username
|
||||
|
||||
`--providers.consulcatalog.endpoint.scheme`:
|
||||
The URI scheme for the Consul server
|
||||
|
||||
`--providers.consulcatalog.endpoint.tls.ca`:
|
||||
TLS CA
|
||||
|
||||
`--providers.consulcatalog.endpoint.tls.caoptional`:
|
||||
TLS CA.Optional (Default: ```false```)
|
||||
|
||||
`--providers.consulcatalog.endpoint.tls.cert`:
|
||||
TLS cert
|
||||
|
||||
`--providers.consulcatalog.endpoint.tls.insecureskipverify`:
|
||||
TLS insecure skip verify (Default: ```false```)
|
||||
|
||||
`--providers.consulcatalog.endpoint.tls.key`:
|
||||
TLS key
|
||||
|
||||
`--providers.consulcatalog.endpoint.token`:
|
||||
Token is used to provide a per-request ACL token which overrides the agent's default token
|
||||
|
||||
`--providers.consulcatalog.exposedbydefault`:
|
||||
Expose containers by default. (Default: ```true```)
|
||||
|
||||
`--providers.consulcatalog.prefix`:
|
||||
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```)
|
||||
|
||||
|
@@ -213,9 +213,6 @@ Buckets for latency metrics. (Default: ```0.100000, 0.300000, 1.200000, 5.000000
|
||||
`TRAEFIK_METRICS_PROMETHEUS_ENTRYPOINT`:
|
||||
EntryPoint (Default: ```traefik```)
|
||||
|
||||
`TRAEFIK_METRICS_PROMETHEUS_MANUALROUTING`:
|
||||
Manual routing (Default: ```false```)
|
||||
|
||||
`TRAEFIK_METRICS_STATSD`:
|
||||
StatsD metrics exporter type. (Default: ```false```)
|
||||
|
||||
@@ -228,9 +225,6 @@ StatsD address. (Default: ```localhost:8125```)
|
||||
`TRAEFIK_METRICS_STATSD_ADDSERVICESLABELS`:
|
||||
Enable metrics on services. (Default: ```true```)
|
||||
|
||||
`TRAEFIK_METRICS_STATSD_PREFIX`:
|
||||
Prefix to use for metrics collection. (Default: ```traefik```)
|
||||
|
||||
`TRAEFIK_METRICS_STATSD_PUSHINTERVAL`:
|
||||
StatsD push interval. (Default: ```10```)
|
||||
|
||||
@@ -240,69 +234,6 @@ Enable ping. (Default: ```false```)
|
||||
`TRAEFIK_PING_ENTRYPOINT`:
|
||||
EntryPoint (Default: ```traefik```)
|
||||
|
||||
`TRAEFIK_PING_MANUALROUTING`:
|
||||
Manual routing (Default: ```false```)
|
||||
|
||||
`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.
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_DEFAULTRULE`:
|
||||
Default rule. (Default: ```Host(`{{ normalize .Name }}`)```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_ADDRESS`:
|
||||
The address of the Consul server (Default: ```http://127.0.0.1:8500```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_DATACENTER`:
|
||||
Data center to use. If not provided, the default agent data center is used
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_ENDPOINTWAITTIME`:
|
||||
WaitTime limits how long a Watch will block. If not provided, the agent default values will be used (Default: ```0```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_HTTPAUTH_PASSWORD`:
|
||||
Basic Auth password
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_HTTPAUTH_USERNAME`:
|
||||
Basic Auth username
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_SCHEME`:
|
||||
The URI scheme for the Consul server
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_TLS_CA`:
|
||||
TLS CA
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_TLS_CAOPTIONAL`:
|
||||
TLS CA.Optional (Default: ```false```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_TLS_CERT`:
|
||||
TLS cert
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_TLS_INSECURESKIPVERIFY`:
|
||||
TLS insecure skip verify (Default: ```false```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_TLS_KEY`:
|
||||
TLS key
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_ENDPOINT_TOKEN`:
|
||||
Token is used to provide a per-request ACL token which overrides the agent's default token
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_EXPOSEDBYDEFAULT`:
|
||||
Expose containers by default. (Default: ```true```)
|
||||
|
||||
`TRAEFIK_PROVIDERS_CONSULCATALOG_PREFIX`:
|
||||
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```)
|
||||
|
||||
|
@@ -108,27 +108,6 @@
|
||||
refreshSeconds = 42
|
||||
intervalPoll = true
|
||||
prefix = "foobar"
|
||||
[providers.consulCatalog]
|
||||
constraints = "foobar"
|
||||
prefix = "traefik"
|
||||
defaultRule = "foobar"
|
||||
exposedByDefault = true
|
||||
refreshInterval = 15
|
||||
requireConsistent = true
|
||||
stale = true
|
||||
cache = true
|
||||
[providers.consulCatalog.endpoint]
|
||||
address = "foobar"
|
||||
scheme = "foobar"
|
||||
datacenter = "foobar"
|
||||
token = "foobar"
|
||||
endpointWaitTime = "15s"
|
||||
[providers.consulCatalog.endpoint.tls]
|
||||
ca = "foobar"
|
||||
caOptional = true
|
||||
cert = "foobar"
|
||||
key = "foobar"
|
||||
insecureSkipVerify = true
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
@@ -141,7 +120,6 @@
|
||||
addEntryPointsLabels = true
|
||||
addServicesLabels = true
|
||||
entryPoint = "foobar"
|
||||
manualRouting = true
|
||||
[metrics.datadog]
|
||||
address = "foobar"
|
||||
pushInterval = "10s"
|
||||
@@ -152,7 +130,6 @@
|
||||
pushInterval = "10s"
|
||||
addEntryPointsLabels = true
|
||||
addServicesLabels = true
|
||||
prefix = "traefik"
|
||||
[metrics.influxDB]
|
||||
address = "foobar"
|
||||
protocol = "foobar"
|
||||
@@ -166,7 +143,6 @@
|
||||
|
||||
[ping]
|
||||
entryPoint = "foobar"
|
||||
manualRouting = true
|
||||
|
||||
[log]
|
||||
level = "foobar"
|
||||
|
@@ -115,27 +115,6 @@ providers:
|
||||
refreshSeconds: 42
|
||||
intervalPoll: true
|
||||
prefix: foobar
|
||||
consulCatalog:
|
||||
constraints: foobar
|
||||
prefix: traefik
|
||||
defaultRule: foobar
|
||||
exposedByDefault: true
|
||||
refreshInterval: 15
|
||||
requireConsistent: true
|
||||
stale: true
|
||||
cache: true
|
||||
endpoint:
|
||||
address: foobar
|
||||
scheme: foobar
|
||||
datacenter: foobar
|
||||
token: foobar
|
||||
endpointWaitTime: 15s
|
||||
tls:
|
||||
ca: foobar
|
||||
caOptional: true
|
||||
cert: foobar
|
||||
key: foobar
|
||||
insecureSkipVerify: true
|
||||
api:
|
||||
insecure: true
|
||||
dashboard: true
|
||||
@@ -148,7 +127,6 @@ metrics:
|
||||
addEntryPointsLabels: true
|
||||
addServicesLabels: true
|
||||
entryPoint: foobar
|
||||
manualRouting: true
|
||||
datadog:
|
||||
address: foobar
|
||||
pushInterval: 42
|
||||
@@ -159,7 +137,6 @@ metrics:
|
||||
pushInterval: 42
|
||||
addEntryPointsLabels: true
|
||||
addServicesLabels: true
|
||||
prefix: traefik
|
||||
influxDB:
|
||||
address: foobar
|
||||
protocol: foobar
|
||||
@@ -172,7 +149,6 @@ metrics:
|
||||
addServicesLabels: true
|
||||
ping:
|
||||
entryPoint: foobar
|
||||
manualRouting: true
|
||||
log:
|
||||
level: foobar
|
||||
filePath: foobar
|
||||
|
@@ -41,7 +41,7 @@ They define the port which will receive the requests (whether HTTP or TCP).
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.websecure]
|
||||
[entryPoints.web-secure]
|
||||
address = ":443"
|
||||
```
|
||||
|
||||
@@ -51,18 +51,18 @@ They define the port which will receive the requests (whether HTTP or TCP).
|
||||
web:
|
||||
address: ":80"
|
||||
|
||||
websecure:
|
||||
web-secure:
|
||||
address: ":443"
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.web-secure.address=:443
|
||||
```
|
||||
|
||||
- Two entrypoints are defined: one called `web`, and the other called `websecure`.
|
||||
- `web` listens on port `80`, and `websecure` on port `443`.
|
||||
- Two entrypoints are defined: one called `web`, and the other called `web-secure`.
|
||||
- `web` listens on port `80`, and `web-secure` on port `443`.
|
||||
|
||||
## Configuration
|
||||
|
||||
|
@@ -1,383 +0,0 @@
|
||||
# Traefik & Consul Catalog
|
||||
|
||||
A Story of Tags, Services & Instances
|
||||
{: .subtitle }
|
||||
|
||||

|
||||
|
||||
Attach tags to your services and let Traefik do the rest!
|
||||
|
||||
## Routing Configuration
|
||||
|
||||
!!! info "tags"
|
||||
|
||||
- tags are case insensitive.
|
||||
- The complete list of tags can be found [the reference page](../../reference/dynamic-configuration/consul-catalog.md)
|
||||
|
||||
### General
|
||||
|
||||
Traefik creates, for each consul Catalog service, a corresponding [service](../services/index.md) and [router](../routers/index.md).
|
||||
|
||||
The Service automatically gets a server per instance in this consul Catalog service, and the router gets a default rule attached to it, based on the service name.
|
||||
|
||||
### Routers
|
||||
|
||||
To update the configuration of the Router automatically attached to the service, add tags starting with `traefik.routers.{name-of-your-choice}.` and followed by the option you want to change.
|
||||
|
||||
For example, to change the rule, you could add the tag ```traefik.http.routers.my-service.rule=Host(`mydomain.com`)```.
|
||||
|
||||
??? info "`traefik.http.routers.<router_name>.rule`"
|
||||
|
||||
See [rule](../routers/index.md#rule) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.myrouter.rule=Host(`mydomain.com`)
|
||||
```
|
||||
|
||||
??? info "`traefik.http.routers.<router_name>.entrypoints`"
|
||||
|
||||
See [entry points](../routers/index.md#entrypoints) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.myrouter.entrypoints=web,websecure
|
||||
```
|
||||
|
||||
??? info "`traefik.http.routers.<router_name>.middlewares`"
|
||||
|
||||
See [middlewares](../routers/index.md#middlewares) and [middlewares overview](../../middlewares/overview.md) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.myrouter.middlewares=auth,prefix,cb
|
||||
```
|
||||
|
||||
??? info "`traefik.http.routers.<router_name>.service`"
|
||||
|
||||
See [rule](../routers/index.md#service) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.myrouter.service=myservice
|
||||
```
|
||||
|
||||
??? info "`traefik.http.routers.<router_name>.tls`"
|
||||
|
||||
See [tls](../routers/index.md#tls) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.myrouter>.tls=true
|
||||
```
|
||||
|
||||
??? info "`traefik.http.routers.<router_name>.tls.certresolver`"
|
||||
|
||||
See [certResolver](../routers/index.md#certresolver) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.myrouter.tls.certresolver=myresolver
|
||||
```
|
||||
|
||||
??? info "`traefik.http.routers.<router_name>.tls.domains[n].main`"
|
||||
|
||||
See [domains](../routers/index.md#domains) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.myrouter.tls.domains[0].main=foobar.com
|
||||
```
|
||||
|
||||
??? info "`traefik.http.routers.<router_name>.tls.domains[n].sans`"
|
||||
|
||||
See [domains](../routers/index.md#domains) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.myrouter.tls.domains[0].sans=test.foobar.com,dev.foobar.com
|
||||
```
|
||||
|
||||
??? info "`traefik.http.routers.<router_name>.tls.options`"
|
||||
|
||||
See [options](../routers/index.md#options) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.myrouter.tls.options=foobar
|
||||
```
|
||||
|
||||
??? info "`traefik.http.routers.<router_name>.priority`"
|
||||
<!-- TODO doc priority in routers page -->
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.myrouter.priority=42
|
||||
```
|
||||
|
||||
### Services
|
||||
|
||||
To update the configuration of the Service automatically attached to the service,
|
||||
add tags starting with `traefik.http.services.{name-of-your-choice}.`, followed by the option you want to change.
|
||||
|
||||
For example, to change the `passHostHeader` behavior,
|
||||
you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.passhostheader=false`.
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.server.port`"
|
||||
|
||||
Registers a port.
|
||||
Useful when the service exposes multiples ports.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.server.port=8080
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.server.scheme`"
|
||||
|
||||
Overrides the default scheme.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.server.scheme=http
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||
<!-- TODO doc passHostHeader in services page -->
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.passhostheader=true
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`"
|
||||
|
||||
See [health check](../services/index.md#health-check) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.healthcheck.headers.X-Foo=foobar
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`"
|
||||
|
||||
See [health check](../services/index.md#health-check) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.healthcheck.hostname=foobar.com
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`"
|
||||
|
||||
See [health check](../services/index.md#health-check) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.healthcheck.interval=10
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`"
|
||||
|
||||
See [health check](../services/index.md#health-check) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.healthcheck.path=/foo
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`"
|
||||
|
||||
See [health check](../services/index.md#health-check) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.healthcheck.port=42
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`"
|
||||
|
||||
See [health check](../services/index.md#health-check) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.healthcheck.scheme=http
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`"
|
||||
|
||||
See [health check](../services/index.md#health-check) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.healthcheck.timeout=10
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.sticky=true
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.sticky.cookie.httponly=true
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`"
|
||||
|
||||
See [sticky sessions](../services/index.md#sticky-sessions) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true
|
||||
```
|
||||
|
||||
??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`"
|
||||
<!-- TODO doc responseforwarding in services page -->
|
||||
|
||||
FlushInterval specifies the flush interval to flush to the client while copying the response body.
|
||||
|
||||
```yaml
|
||||
traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10
|
||||
```
|
||||
|
||||
### Middleware
|
||||
|
||||
You can declare pieces of middleware using tags starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options.
|
||||
|
||||
For example, to declare a middleware [`redirectscheme`](../../middlewares/redirectscheme.md) named `my-redirect`, you'd write `traefik.http.middlewares.my-redirect.redirectscheme.scheme: https`.
|
||||
|
||||
More information about available middlewares in the dedicated [middlewares section](../../middlewares/overview.md).
|
||||
|
||||
??? example "Declaring and Referencing a Middleware"
|
||||
|
||||
```yaml
|
||||
# ...
|
||||
# Declaring a middleware
|
||||
traefik.http.middlewares.my-redirect.redirectscheme.scheme=https
|
||||
# Referencing a middleware
|
||||
traefik.http.routers.my-service.middlewares=my-redirect
|
||||
```
|
||||
|
||||
!!! warning "Conflicts in Declaration"
|
||||
|
||||
If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared.
|
||||
|
||||
### TCP
|
||||
|
||||
You can declare TCP Routers and/or Services using tags.
|
||||
|
||||
??? example "Declaring TCP Routers and Services"
|
||||
|
||||
```yaml
|
||||
traefik.tcp.routers.my-router.rule=HostSNI(`my-host.com`)
|
||||
traefik.tcp.routers.my-router.tls=true
|
||||
traefik.tcp.services.my-service.loadbalancer.server.port=4123
|
||||
```
|
||||
|
||||
!!! warning "TCP and HTTP"
|
||||
|
||||
If you declare a TCP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no TCP Router/Service is defined).
|
||||
You can declare both a TCP Router/Service and an HTTP Router/Service for the same consul service (but you have to do so manually).
|
||||
|
||||
#### TCP Routers
|
||||
|
||||
??? info "`traefik.tcp.routers.<router_name>.entrypoints`"
|
||||
|
||||
See [entry points](../routers/index.md#entrypoints_1) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.routers.mytcprouter.entrypoints=ep1,ep2
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.routers.<router_name>.rule`"
|
||||
|
||||
See [rule](../routers/index.md#rule_1) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.routers.mytcprouter.rule=HostSNI(`myhost.com`)
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.routers.<router_name>.service`"
|
||||
|
||||
See [service](../routers/index.md#services) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.routers.mytcprouter.service=myservice
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.routers.<router_name>.tls`"
|
||||
|
||||
See [TLS](../routers/index.md#tls_1) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.routers.mytcprouter.tls=true
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.routers.<router_name>.tls.certresolver`"
|
||||
|
||||
See [certResolver](../routers/index.md#certresolver_1) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.routers.mytcprouter.tls.certresolver=myresolver
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].main`"
|
||||
|
||||
See [domains](../routers/index.md#domains_1) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.routers.mytcprouter.tls.domains[0].main=foobar.com
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].sans`"
|
||||
|
||||
See [domains](../routers/index.md#domains_1) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.routers.mytcprouter.tls.domains[0].sans=test.foobar.com,dev.foobar.com
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.routers.<router_name>.tls.options`"
|
||||
|
||||
See [options](../routers/index.md#options_1) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.routers.mytcprouter.tls.options=mysoptions
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.routers.<router_name>.tls.passthrough`"
|
||||
|
||||
See [TLS](../routers/index.md#tls_1) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.routers.mytcprouter.tls.passthrough=true
|
||||
```
|
||||
|
||||
#### TCP Services
|
||||
|
||||
??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.port`"
|
||||
|
||||
Registers a port of the application.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.services.mytcpservice.loadbalancer.server.port=423
|
||||
```
|
||||
|
||||
??? info "`traefik.tcp.services.<service_name>.loadbalancer.terminationdelay`"
|
||||
|
||||
See [termination delay](../services/index.md#termination-delay) for more information.
|
||||
|
||||
```yaml
|
||||
traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100
|
||||
```
|
||||
|
||||
### Specific Provider Options
|
||||
|
||||
#### `traefik.enable`
|
||||
|
||||
```yaml
|
||||
traefik.enable=true
|
||||
```
|
||||
|
||||
You can tell Traefik to consider (or not) the service by setting `traefik.enable` to true or false.
|
||||
|
||||
This option overrides the value of `exposedByDefault`.
|
||||
|
||||
#### Port Lookup
|
||||
|
||||
Traefik is capable of detecting the port to use, by following the default consul Catalog flow.
|
||||
That means, if you just expose lets say port `:1337` on the consul Catalog ui, traefik will pick up this port and use it.
|
@@ -1,13 +0,0 @@
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: traefikservices.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: TraefikService
|
||||
plural: traefikservices
|
||||
singular: traefikservice
|
||||
scope: Namespaced
|
File diff suppressed because it is too large
Load Diff
@@ -387,9 +387,7 @@ The WRR is able to load balance the requests between multiple services based on
|
||||
|
||||
This strategy is only available to load balance between [services](./index.md) and not between [servers](./index.md#servers).
|
||||
|
||||
!!! info "Supported Providers"
|
||||
|
||||
This strategy can be defined currently with the [File](../../providers/file.md) or [IngressRoute](../../providers/kubernetes-crd.md) providers.
|
||||
!!! info "This strategy can be defined only with [File](../../providers/file.md)."
|
||||
|
||||
```toml tab="TOML"
|
||||
## Dynamic configuration
|
||||
@@ -440,9 +438,7 @@ http:
|
||||
|
||||
The mirroring is able to mirror requests sent to a service to other services.
|
||||
|
||||
!!! info "Supported Providers"
|
||||
|
||||
This strategy can be defined currently with the [File](../../providers/file.md) or [IngressRoute](../../providers/kubernetes-crd.md) providers.
|
||||
!!! info "This strategy can be defined only with [File](../../providers/file.md)."
|
||||
|
||||
```toml tab="TOML"
|
||||
## Dynamic configuration
|
||||
@@ -587,9 +583,7 @@ The Weighted Round Robin (alias `WRR`) load-balancer of services is in charge of
|
||||
|
||||
This strategy is only available to load balance between [services](./index.md) and not between [servers](./index.md#servers).
|
||||
|
||||
!!! info "Supported Providers"
|
||||
|
||||
This strategy can be defined currently with the [File](../../providers/file.md) or [IngressRoute](../../providers/kubernetes-crd.md) providers.
|
||||
This strategy can only be defined with [File](../../providers/file.md).
|
||||
|
||||
```toml tab="TOML"
|
||||
## Dynamic configuration
|
||||
|
@@ -57,21 +57,6 @@ spec:
|
||||
singular: tlsoption
|
||||
scope: Namespaced
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: traefikservices.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: TraefikService
|
||||
plural: traefikservices
|
||||
singular: traefikservice
|
||||
scope: Namespaced
|
||||
|
||||
---
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
@@ -135,14 +120,6 @@ rules:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- traefik.containo.us
|
||||
resources:
|
||||
- traefikservices
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
|
||||
---
|
||||
kind: ClusterRoleBinding
|
||||
|
@@ -26,11 +26,7 @@ theme:
|
||||
prev: 'Previous'
|
||||
next: 'Next'
|
||||
|
||||
copyright: "Copyright © 2016-2019 Containous"
|
||||
|
||||
google_analytics:
|
||||
- 'UA-51880359-3'
|
||||
- 'docs.traefik.io'
|
||||
copyright: "Copyright © 2016-2020 Containous"
|
||||
|
||||
extra_css:
|
||||
- assets/styles/extra.css # Our custom styles
|
||||
@@ -80,10 +76,9 @@ nav:
|
||||
- 'Docker': 'providers/docker.md'
|
||||
- 'Kubernetes IngressRoute': 'providers/kubernetes-crd.md'
|
||||
- 'Kubernetes Ingress': 'providers/kubernetes-ingress.md'
|
||||
- 'Consul Catalog': 'providers/consul-catalog.md'
|
||||
- 'Marathon': 'providers/marathon.md'
|
||||
- 'Rancher': 'providers/rancher.md'
|
||||
- 'File': 'providers/file.md'
|
||||
- 'Marathon': 'providers/marathon.md'
|
||||
- 'Routing & Load Balancing':
|
||||
- 'Overview': 'routing/overview.md'
|
||||
- 'EntryPoints': 'routing/entrypoints.md'
|
||||
@@ -92,9 +87,8 @@ nav:
|
||||
- 'Providers':
|
||||
- 'Docker': 'routing/providers/docker.md'
|
||||
- 'Kubernetes IngressRoute': 'routing/providers/kubernetes-crd.md'
|
||||
- 'Consul Catalog': 'routing/providers/consul-catalog.md'
|
||||
- 'Marathon': 'routing/providers/marathon.md'
|
||||
- 'Rancher': 'routing/providers/rancher.md'
|
||||
- 'Marathon': 'routing/providers/marathon.md'
|
||||
- 'HTTPS & TLS':
|
||||
- 'Overview': 'https/overview.md'
|
||||
- 'TLS': 'https/tls.md'
|
||||
@@ -154,7 +148,6 @@ nav:
|
||||
- 'HTTP Challenge': 'user-guides/docker-compose/acme-http/index.md'
|
||||
- 'DNS Challenge': 'user-guides/docker-compose/acme-dns/index.md'
|
||||
- 'Migration':
|
||||
- 'Traefik v2 minor migrations': 'migration/v2.md'
|
||||
- 'Traefik v1 to v2': 'migration/v1-to-v2.md'
|
||||
- 'Contributing':
|
||||
- 'Thank You!': 'contributing/thank-you.md'
|
||||
@@ -177,6 +170,5 @@ nav:
|
||||
- 'File': 'reference/dynamic-configuration/file.md'
|
||||
- 'Docker': 'reference/dynamic-configuration/docker.md'
|
||||
- 'Kubernetes CRD': 'reference/dynamic-configuration/kubernetes-crd.md'
|
||||
- 'Consul Catalog': 'reference/dynamic-configuration/consul-catalog.md'
|
||||
- 'Marathon': 'reference/dynamic-configuration/marathon.md'
|
||||
- 'Rancher': 'reference/dynamic-configuration/rancher.md'
|
||||
|
@@ -4,3 +4,23 @@ mkdocs-bootswatch==1.0
|
||||
mkdocs-material==4.4.3
|
||||
markdown-include==0.5.1
|
||||
mkdocs-exclude==1.0.2
|
||||
Jinja2==3.0.0
|
||||
|
||||
click==8.1.3
|
||||
csscompressor==0.9.5
|
||||
htmlmin==0.1.12
|
||||
importlib-metadata==4.12.0
|
||||
jsmin==3.0.1
|
||||
livereload==2.6.3
|
||||
Markdown==3.3.7
|
||||
MarkupSafe==2.1.1
|
||||
mkdocs-exclude==1.0.2
|
||||
mkdocs-minify-plugin==0.5.0
|
||||
pep562==1.1
|
||||
Pygments==2.12.0
|
||||
pymdown-extensions==6.1
|
||||
PyYAML==6.0.1
|
||||
six==1.16.0
|
||||
tornado==6.2
|
||||
typing-extensions==4.3.0
|
||||
zipp==3.8.1
|
||||
|
12
docs/theme/main.html
vendored
12
docs/theme/main.html
vendored
@@ -1,5 +1,15 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block analytics %}
|
||||
<!-- Google Tag Manager -->
|
||||
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||
})(window,document,'script','dataLayer','GTM-NMWC63S');</script>
|
||||
<!-- End Google Tag Manager -->
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
|
||||
{% import "partials/language.html" as lang with context %}
|
||||
@@ -34,4 +44,4 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
9
go.mod
9
go.mod
@@ -15,7 +15,7 @@ require (
|
||||
github.com/Shopify/sarama v1.23.1 // indirect
|
||||
github.com/VividCortex/gohistogram v1.0.0 // indirect
|
||||
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
|
||||
github.com/abronan/valkeyrie v0.0.0-20190822142731-f2e1850dc905
|
||||
github.com/abronan/valkeyrie v0.0.0-20190802193736-ed4c4a229894
|
||||
github.com/c0va23/go-proxyprotocol v0.9.1
|
||||
github.com/cenkalti/backoff/v3 v3.0.0
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
|
||||
@@ -47,7 +47,6 @@ require (
|
||||
github.com/googleapis/gnostic v0.1.0 // indirect
|
||||
github.com/gorilla/mux v1.7.3
|
||||
github.com/gorilla/websocket v1.4.0
|
||||
github.com/hashicorp/consul/api v1.2.0
|
||||
github.com/hashicorp/go-version v1.2.0
|
||||
github.com/huandu/xstrings v1.2.0 // indirect
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20190402204710-8ff2fc3824fc
|
||||
@@ -73,15 +72,15 @@ require (
|
||||
github.com/philhofer/fwd v1.0.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0
|
||||
github.com/prometheus/client_golang v1.1.0
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90
|
||||
github.com/rancher/go-rancher-metadata v0.0.0-00010101000000-000000000000
|
||||
github.com/sirupsen/logrus v1.4.2
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/stvp/go-udp-testing v0.0.0-20171104055251-c4434f09ec13
|
||||
github.com/tinylib/msgp v1.0.2 // indirect
|
||||
github.com/transip/gotransip v5.8.2+incompatible // indirect
|
||||
github.com/uber/jaeger-client-go v2.21.1+incompatible
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible
|
||||
github.com/uber/jaeger-client-go v2.16.0+incompatible
|
||||
github.com/uber/jaeger-lib v2.0.0+incompatible
|
||||
github.com/unrolled/render v1.0.1
|
||||
github.com/unrolled/secure v1.0.5
|
||||
github.com/vdemeester/shakers v0.1.0
|
||||
|
101
go.sum
101
go.sum
@@ -35,7 +35,6 @@ github.com/Azure/go-autorest/tracing v0.1.0/go.mod h1:ROEEAFwXycQw7Sn3DXNtEedEvd
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798 h1:2T/jmrHeTezcCM58lvEQXs0UpQJCo5SoGAcg+mbSTIg=
|
||||
github.com/DataDog/zstd v1.3.6-0.20190409195224-796139022798/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
|
||||
github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61 h1:1NIUJ+MAMpqDr4LWIfNsoJR+G7zg/8GZVwuRkmJxtTc=
|
||||
@@ -61,8 +60,8 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWso
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
|
||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||
github.com/abronan/valkeyrie v0.0.0-20190822142731-f2e1850dc905 h1:JG0OqQLCILn6ywoXJncu+/MFTTapP3aIIDDqB593HMc=
|
||||
github.com/abronan/valkeyrie v0.0.0-20190822142731-f2e1850dc905/go.mod h1:hTreU6x9m2IP2h8e0TGrSzAXSCI3lxic8/JT5CMknjY=
|
||||
github.com/abronan/valkeyrie v0.0.0-20190802193736-ed4c4a229894 h1:6oe+/ZnkM+gEJL+28sgHiCvO6qt15NE2lm52BuzBees=
|
||||
github.com/abronan/valkeyrie v0.0.0-20190802193736-ed4c4a229894/go.mod h1:sQZ/48uDt1GRBDNsLboJGPD2w/HxEOhqf3JiikfHj1I=
|
||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.0 h1:rXPPPxDA4GCPN0YWwyVHMzcxVpVg8gai2uGhJ3VqOSs=
|
||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.0/go.mod h1:zpDJeKyp9ScW4NNrbdr+Eyxvry3ilGPewKoXw3XGN1k=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
@@ -72,11 +71,6 @@ github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190808125512-07798873deee/go.mod
|
||||
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
|
||||
github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs=
|
||||
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM=
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aws/aws-sdk-go v1.16.23/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.23.0 h1:ilfJN/vJtFo1XDFxB2YMBYGeOvGZl6Qow17oyD4+Z9A=
|
||||
github.com/aws/aws-sdk-go v1.23.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
@@ -86,15 +80,12 @@ github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/c0va23/go-proxyprotocol v0.9.1 h1:5BCkp0fDJOhzzH1lhjUgHhmZz9VvRMMif1U2D31hb34=
|
||||
github.com/c0va23/go-proxyprotocol v0.9.1/go.mod h1:TNjUV+llvk8TvWJxlPYAeAYZgSzT/iicNr3nWBWX320=
|
||||
github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c=
|
||||
github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/cloudflare-go v0.10.2 h1:VBodKICVPnwmDxstcW3biKcDSpFIfS/RELUXsZSBYK4=
|
||||
github.com/cloudflare/cloudflare-go v0.10.2/go.mod h1:qhVI5MKwBGhdNU89ZRz2plgYutcJ5PCekLxXn56w6SY=
|
||||
@@ -118,12 +109,10 @@ github.com/containous/multibuf v0.0.0-20190809014333-8b6c9a7e6bba h1:PhR03pep+5e
|
||||
github.com/containous/multibuf v0.0.0-20190809014333-8b6c9a7e6bba/go.mod h1:zkWcASFUJEst6QwCrxLdkuw1gvaKqmflEipm+iecV5M=
|
||||
github.com/containous/mux v0.0.0-20181024131434-c33f32e26898 h1:1srn9voikJGofblBhWy3WuZWqo14Ou7NaswNG/I2yWc=
|
||||
github.com/containous/mux v0.0.0-20181024131434-c33f32e26898/go.mod h1:z8WW7n06n8/1xF9Jl9WmuDeZuHAhfL+bwarNjsciwwg=
|
||||
github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpu/goacmedns v0.0.1 h1:GeIU5chKys9zmHgOAgP+bstRaLqcGQ6HJh/hLw9hrus=
|
||||
github.com/cpu/goacmedns v0.0.1/go.mod h1:sesf/pNnCYwUevQEQfEwY0Y3DydlQWSGZbaMElOWxok=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
@@ -181,7 +170,6 @@ github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5I
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/exoscale/egoscale v0.18.1 h1:1FNZVk8jHUx0AvWhOZxLEDNlacTU0chMXUUNkm9EZaI=
|
||||
github.com/exoscale/egoscale v0.18.1/go.mod h1:Z7OOdzzTOz1Q1PjQXumlz9Wn/CddH0zSYdCF3rnBKXE=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/felixge/httpsnoop v1.0.0 h1:gh8fMGz0rlOv/1WmRZm7OgncIOTsAj21iNJot48omJQ=
|
||||
@@ -220,8 +208,6 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekf
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903 h1:LbsanbbD6LieFkXbj9YNNBupiGHJgFeLpO0j0Fza1h8=
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
@@ -235,8 +221,6 @@ github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
@@ -271,56 +255,22 @@ github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoA
|
||||
github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f h1:68WxnfBzJRYktZ30fmIjGQ74RsXYLoeH2/NITPktTMY=
|
||||
github.com/gravitational/trace v0.0.0-20190726142706-a535a178675f/go.mod h1:RvdOUHE4SHqR3oXlFFKnGzms8a5dugHygGw1bqDstYI=
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5 h1:2+KSC78XiO6Qy0hIjfc1OD9H+hsaJdJlb8Kqsd41CTE=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5 h1:UImYN5qQ8tuGpGE16ZmjvcTtTw24zw1QAp/SlnNrZhI=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.2.0 h1:oPsuzLp2uk7I7rojPKuncWbZ+m5TMoD4Ivs+2Rkeh4Y=
|
||||
github.com/hashicorp/consul/api v1.2.0/go.mod h1:1SIkFYi2ZTXUE5Kgt179+4hH33djo11+0Eo2XgTAtkw=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/consul/sdk v0.2.0 h1:GWFYFmry/k4b1hEoy7kSkmU8e30GAyI4VZHk0fRxeL4=
|
||||
github.com/hashicorp/consul/sdk v0.2.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
|
||||
github.com/hashicorp/consul v1.4.0/go.mod h1:mFrjN1mfidgJfYP1xrJCF+AfRhr6Eaqhb2+sfyn/OOI=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI=
|
||||
github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0 h1:Rqb66Oo1X/eSV1x66xbDccZjhJigjg0+e82kpwzSwCI=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0 h1:GeH6tui99pF4NJgfnhp+L6+FfobzVW3Ah46sLo0ICXs=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
|
||||
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/memberlist v0.1.4 h1:gkyML/r71w3FL8gUi74Vk76avkj/9lYAY9lvg0OcoGs=
|
||||
github.com/hashicorp/memberlist v0.1.4/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/serf v0.8.1/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE=
|
||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0=
|
||||
@@ -385,30 +335,22 @@ github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 h1:Kg/NPZLLC3aAF
|
||||
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51/go.mod h1:RYmqHbhWwIz3z9eVmQ2rx82rulEMG0t+Q1bzfc9DYN4=
|
||||
github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f h1:ZZYhg16XocqSKPGNQAe0aeweNtFxuedbwwb4fSlg7h4=
|
||||
github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f/go.mod h1:8heskWJ5c0v5J9WH89ADhyal1DOZcayll8fSbhB+/9A=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.15 h1:CSSIDtllwGLMoA6zjdKnaE6Tx6eVUxQ29LUgGetiDCI=
|
||||
github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed/go.mod h1:3rdaFaCv4AyBgu5ALFM0+tSuHrBh6v692nyQe3ikrq0=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y=
|
||||
github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
|
||||
@@ -463,9 +405,6 @@ github.com/oracle/oci-go-sdk v7.0.0+incompatible h1:oj5ESjXwwkFRdhZSnPlShvLWYdt/
|
||||
github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
|
||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014 h1:37VE5TYj2m/FLA9SNr4z0+A0JefvTmR60Zwf8XSEV7c=
|
||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014/go.mod h1:joRatxRJaZBsY3JAOEMcoOp05CnZzsx4scTxi95DHyQ=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
@@ -481,9 +420,7 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
@@ -493,15 +430,11 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
|
||||
@@ -512,13 +445,10 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/sacloud/libsacloud v1.26.1 h1:td3Kd7lvpSAxxHEVpnaZ9goHmmhi0D/RfP0Rqqf/kek=
|
||||
github.com/sacloud/libsacloud v1.26.1/go.mod h1:79ZwATmHLIFZIMd7sxA3LwzVy/B77uj3LDoToVTxDoQ=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
@@ -529,7 +459,6 @@ github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykE
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
github.com/spf13/pflag v1.0.1 h1:aCvUg6QPl3ibpQUxyLkrEkCHtPqYJL4x9AuhqVqFis4=
|
||||
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||
@@ -547,17 +476,16 @@ github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7 h1:CpHxIaZzVy26G
|
||||
github.com/timewasted/linode v0.0.0-20160829202747-37e84520dcf7/go.mod h1:imsgLplxEC/etjIhdr3dNzV3JeT27LbVu5pYWm0JCBY=
|
||||
github.com/tinylib/msgp v1.0.2 h1:DfdQrzQa7Yh2es9SuLkixqxuXS2SxsdYn0KbdrOGWD8=
|
||||
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/transip/gotransip v0.0.0-20190812104329-6d8d9179b66f/go.mod h1:i0f4R4o2HM0m3DZYQWsj6/MEowD57VzoH0v3d7igeFY=
|
||||
github.com/transip/gotransip v5.8.2+incompatible h1:aNJhw/w/3QBqFcHAIPz1ytoK5FexeMzbUCGrrhWr3H0=
|
||||
github.com/transip/gotransip v5.8.2+incompatible/go.mod h1:uacMoJVmrfOcscM4Bi5NVg708b7c6rz2oDTWqa7i2Ic=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo=
|
||||
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
|
||||
github.com/uber/jaeger-client-go v2.21.1+incompatible h1:oozboeZmWz+tyh3VZttJWlF3K73mHgbokieceqKccLo=
|
||||
github.com/uber/jaeger-client-go v2.21.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
|
||||
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/uber/jaeger-client-go v2.16.0+incompatible h1:Q2Pp6v3QYiocMxomCaJuwQGFt7E53bPYqEgug/AoBtY=
|
||||
github.com/uber/jaeger-client-go v2.16.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.0.0+incompatible h1:iMSCV0rmXEogjNWPh2D0xk9YVKvrtGoHJNe9ebLu/pw=
|
||||
github.com/uber/jaeger-lib v2.0.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v0.0.0-20171019201919-bdcc60b419d1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
|
||||
github.com/unrolled/render v1.0.1 h1:VDDnQQVfBMsOsp3VaCJszSO0nkBIVEYoPWeRThk9spY=
|
||||
github.com/unrolled/render v1.0.1/go.mod h1:gN9T0NhL4Bfbwu8ann7Ry/TGHYfosul+J0obPf6NBdM=
|
||||
github.com/unrolled/secure v1.0.5 h1:KRGJ8DQC3jKpERjBKF3H6b3HcAsM/SRTVwfNJnWs25E=
|
||||
@@ -579,7 +507,6 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg=
|
||||
github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
go.etcd.io/bbolt v1.3.1-etcd.8/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||
go.etcd.io/etcd v3.3.13+incompatible/go.mod h1:yaeTdrJi5lOmYerz05bd8+V7KubZs8YSFZfzsF9A6aI=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
@@ -588,16 +515,11 @@ go.opencensus.io v0.21.0 h1:mU6zScU4U1YAFPHEHYk+3JC4SY7JxgkqS10ZOSyksNg=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277 h1:d9qaMM+ODpCq+9We41//fu/sHsTnXcrqd1en3x+GKy4=
|
||||
go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181025213731-e84da0312774/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
@@ -619,9 +541,7 @@ golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -647,11 +567,9 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -711,6 +629,7 @@ google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRn
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||
|
@@ -8,7 +8,6 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -547,16 +546,8 @@ func checkAccessLogExactValuesOutput(c *check.C, values []accessLogValue) int {
|
||||
func extractLines(c *check.C) []string {
|
||||
accessLog, err := ioutil.ReadFile(traefikTestAccessLogFile)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
lines := strings.Split(string(accessLog), "\n")
|
||||
|
||||
var clean []string
|
||||
for _, line := range lines {
|
||||
if !strings.Contains(line, "/api/rawdata") {
|
||||
clean = append(clean, line)
|
||||
}
|
||||
}
|
||||
return clean
|
||||
return lines
|
||||
}
|
||||
|
||||
func checkStatsForLogFile(c *check.C) {
|
||||
@@ -589,31 +580,28 @@ func CheckAccessLogFormat(c *check.C, line string, i int) {
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(results, checker.HasLen, 14)
|
||||
c.Assert(results[accesslog.OriginStatus], checker.Matches, `^(-|\d{3})$`)
|
||||
count, _ := strconv.Atoi(results[accesslog.RequestCount])
|
||||
c.Assert(count, checker.GreaterOrEqualThan, i+1)
|
||||
c.Assert(results[accesslog.RouterName], checker.Matches, `"(rt-.+@docker|api@internal)"`)
|
||||
c.Assert(results[accesslog.ServiceURL], checker.HasPrefix, `"http://`)
|
||||
c.Assert(results[accesslog.RequestCount], checker.Equals, fmt.Sprintf("%d", i+1))
|
||||
c.Assert(results[accesslog.RouterName], checker.Matches, `"rt-.+@docker"`)
|
||||
c.Assert(results[accesslog.ServiceURL], checker.HasPrefix, "\"http://")
|
||||
c.Assert(results[accesslog.Duration], checker.Matches, `^\d+ms$`)
|
||||
}
|
||||
|
||||
func checkAccessLogExactValues(c *check.C, line string, i int, v accessLogValue) {
|
||||
results, err := accesslog.ParseAccessLog(line)
|
||||
// c.Assert(nil, checker.Equals, line)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(results, checker.HasLen, 14)
|
||||
if len(v.user) > 0 {
|
||||
c.Assert(results[accesslog.ClientUsername], checker.Equals, v.user)
|
||||
}
|
||||
c.Assert(results[accesslog.OriginStatus], checker.Equals, v.code)
|
||||
count, _ := strconv.Atoi(results[accesslog.RequestCount])
|
||||
c.Assert(count, checker.GreaterOrEqualThan, i+1)
|
||||
c.Assert(results[accesslog.RequestCount], checker.Equals, fmt.Sprintf("%d", i+1))
|
||||
c.Assert(results[accesslog.RouterName], checker.Matches, `^"?`+v.routerName+`.*(@docker)?$`)
|
||||
c.Assert(results[accesslog.ServiceURL], checker.Matches, `^"?`+v.serviceURL+`.*$`)
|
||||
c.Assert(results[accesslog.Duration], checker.Matches, `^\d+ms$`)
|
||||
}
|
||||
|
||||
func waitForTraefik(c *check.C, containerName string) {
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
// Wait for Traefik to turn ready.
|
||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080/api/rawdata", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
@@ -1,602 +0,0 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/containous/traefik/v2/integration/try"
|
||||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/go-check/check"
|
||||
"github.com/hashicorp/consul/api"
|
||||
)
|
||||
|
||||
type ConsulCatalogSuite struct {
|
||||
BaseSuite
|
||||
consulClient *api.Client
|
||||
consulAgentClient *api.Client
|
||||
consulAddress string
|
||||
consulAgentAddress string
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) SetUpSuite(c *check.C) {
|
||||
s.createComposeProject(c, "consul_catalog")
|
||||
s.composeProject.Start(c)
|
||||
s.consulAddress = "http://" + s.composeProject.Container(c, "consul").NetworkSettings.IPAddress + ":8500"
|
||||
client, err := api.NewClient(&api.Config{
|
||||
Address: s.consulAddress,
|
||||
})
|
||||
c.Check(err, check.IsNil)
|
||||
s.consulClient = client
|
||||
|
||||
// Wait for consul to elect itself leader
|
||||
err = s.waitToElectConsulLeader()
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
s.consulAgentAddress = "http://" + s.composeProject.Container(c, "consul-agent").NetworkSettings.IPAddress + ":8500"
|
||||
clientAgent, err := api.NewClient(&api.Config{
|
||||
Address: s.consulAgentAddress,
|
||||
})
|
||||
c.Check(err, check.IsNil)
|
||||
s.consulAgentClient = clientAgent
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) waitToElectConsulLeader() error {
|
||||
return try.Do(15*time.Second, func() error {
|
||||
leader, err := s.consulClient.Status().Leader()
|
||||
|
||||
if err != nil || len(leader) == 0 {
|
||||
return fmt.Errorf("leader not found. %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TearDownSuite(c *check.C) {
|
||||
// shutdown and delete compose project
|
||||
if s.composeProject != nil {
|
||||
s.composeProject.Stop(c)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) registerService(reg *api.AgentServiceRegistration, onAgent bool) error {
|
||||
client := s.consulClient
|
||||
if onAgent {
|
||||
client = s.consulAgentClient
|
||||
}
|
||||
|
||||
return client.Agent().ServiceRegister(reg)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) deregisterService(id string, onAgent bool) error {
|
||||
client := s.consulClient
|
||||
if onAgent {
|
||||
client = s.consulAgentClient
|
||||
}
|
||||
return client.Agent().ServiceDeregister(id)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestWithNotExposedByDefaultAndDefaultsSettings(c *check.C) {
|
||||
reg1 := &api.AgentServiceRegistration{
|
||||
ID: "whoami1",
|
||||
Name: "whoami",
|
||||
Tags: []string{"traefik.enable=true"},
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
|
||||
}
|
||||
err := s.registerService(reg1, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
reg2 := &api.AgentServiceRegistration{
|
||||
ID: "whoami2",
|
||||
Name: "whoami",
|
||||
Tags: []string{"traefik.enable=true"},
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress,
|
||||
}
|
||||
err = s.registerService(reg2, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
reg3 := &api.AgentServiceRegistration{
|
||||
ID: "whoami3",
|
||||
Name: "whoami",
|
||||
Tags: []string{"traefik.enable=true"},
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami3").NetworkSettings.IPAddress,
|
||||
}
|
||||
err = s.registerService(reg3, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
tempObjects := struct {
|
||||
ConsulAddress string
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, "fixtures/consul_catalog/default_not_exposed.toml", tempObjects)
|
||||
defer os.Remove(file)
|
||||
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
req.Host = "whoami"
|
||||
|
||||
err = try.Request(req, 2*time.Second, try.StatusCodeIs(200), try.BodyContainsOr("Hostname: whoami1", "Hostname: whoami2", "Hostname: whoami3"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami1", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
err = s.deregisterService("whoami2", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
err = s.deregisterService("whoami3", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestByLabels(c *check.C) {
|
||||
containerIP := s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress
|
||||
|
||||
reg := &api.AgentServiceRegistration{
|
||||
ID: "whoami1",
|
||||
Name: "whoami",
|
||||
Tags: []string{
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.router1.rule=Path(`/whoami`)",
|
||||
"traefik.http.routers.router1.service=service1",
|
||||
"traefik.http.services.service1.loadBalancer.server.url=http://" + containerIP,
|
||||
},
|
||||
Port: 80,
|
||||
Address: containerIP,
|
||||
}
|
||||
err := s.registerService(reg, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
tempObjects := struct {
|
||||
ConsulAddress string
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, "fixtures/consul_catalog/default_not_exposed.toml", tempObjects)
|
||||
defer os.Remove(file)
|
||||
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8000/whoami", 2*time.Second, try.StatusCodeIs(http.StatusOK), try.BodyContainsOr("Hostname: whoami1", "Hostname: whoami2", "Hostname: whoami3"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami1", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestSimpleConfiguration(c *check.C) {
|
||||
tempObjects := struct {
|
||||
ConsulAddress string
|
||||
DefaultRule string
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, "fixtures/consul_catalog/simple.toml", tempObjects)
|
||||
defer os.Remove(file)
|
||||
|
||||
reg := &api.AgentServiceRegistration{
|
||||
ID: "whoami1",
|
||||
Name: "whoami",
|
||||
Tags: []string{"traefik.enable=true"},
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
|
||||
}
|
||||
err := s.registerService(reg, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
req.Host = "whoami.consul.localhost"
|
||||
|
||||
err = try.Request(req, 2*time.Second, try.StatusCodeIs(200), try.BodyContainsOr("Hostname: whoami1"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami1", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestRegisterServiceWithoutIP(c *check.C) {
|
||||
tempObjects := struct {
|
||||
ConsulAddress string
|
||||
DefaultRule string
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, "fixtures/consul_catalog/simple.toml", tempObjects)
|
||||
defer os.Remove(file)
|
||||
|
||||
reg := &api.AgentServiceRegistration{
|
||||
ID: "whoami1",
|
||||
Name: "whoami",
|
||||
Tags: []string{"traefik.enable=true"},
|
||||
Port: 80,
|
||||
Address: "",
|
||||
}
|
||||
err := s.registerService(reg, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080/api/http/services", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.Request(req, 2*time.Second, try.StatusCodeIs(200), try.BodyContainsOr("whoami@consulcatalog", "\"http://127.0.0.1:80\": \"UP\""))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami1", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestDefaultConsulService(c *check.C) {
|
||||
tempObjects := struct {
|
||||
ConsulAddress string
|
||||
DefaultRule string
|
||||
}{
|
||||
|
||||
ConsulAddress: s.consulAddress,
|
||||
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, "fixtures/consul_catalog/simple.toml", tempObjects)
|
||||
defer os.Remove(file)
|
||||
|
||||
reg := &api.AgentServiceRegistration{
|
||||
ID: "whoami1",
|
||||
Name: "whoami",
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
|
||||
}
|
||||
err := s.registerService(reg, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Start traefik
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
req.Host = "whoami.consul.localhost"
|
||||
|
||||
err = try.Request(req, 2*time.Second, try.StatusCodeIs(200), try.BodyContainsOr("Hostname: whoami1"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami1", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestConsulServiceWithTCPLabels(c *check.C) {
|
||||
tempObjects := struct {
|
||||
ConsulAddress string
|
||||
DefaultRule string
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, "fixtures/consul_catalog/simple.toml", tempObjects)
|
||||
defer os.Remove(file)
|
||||
|
||||
// Start a container with some tags
|
||||
reg := &api.AgentServiceRegistration{
|
||||
ID: "whoamitcp",
|
||||
Name: "whoamitcp",
|
||||
Tags: []string{
|
||||
"traefik.tcp.Routers.Super.Rule=HostSNI(`my.super.host`)",
|
||||
"traefik.tcp.Routers.Super.tls=true",
|
||||
"traefik.tcp.Services.Super.Loadbalancer.server.port=8080",
|
||||
},
|
||||
Port: 8080,
|
||||
Address: s.composeProject.Container(c, "whoamitcp").NetworkSettings.IPAddress,
|
||||
}
|
||||
|
||||
err := s.registerService(reg, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Start traefik
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1500*time.Millisecond, try.StatusCodeIs(http.StatusOK), try.BodyContains("HostSNI(`my.super.host`)"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
who, err := guessWho("127.0.0.1:8000", "my.super.host", true)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
c.Assert(who, checker.Contains, "whoamitcp")
|
||||
|
||||
err = s.deregisterService("whoamitcp", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestConsulServiceWithLabels(c *check.C) {
|
||||
tempObjects := struct {
|
||||
ConsulAddress string
|
||||
DefaultRule string
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, "fixtures/consul_catalog/simple.toml", tempObjects)
|
||||
defer os.Remove(file)
|
||||
|
||||
// Start a container with some tags
|
||||
reg1 := &api.AgentServiceRegistration{
|
||||
ID: "whoami1",
|
||||
Name: "whoami",
|
||||
Tags: []string{
|
||||
"traefik.http.Routers.Super.Rule=Host(`my.super.host`)",
|
||||
},
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
|
||||
}
|
||||
|
||||
err := s.registerService(reg1, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Start another container by replacing a '.' by a '-'
|
||||
reg2 := &api.AgentServiceRegistration{
|
||||
ID: "whoami2",
|
||||
Name: "whoami",
|
||||
Tags: []string{
|
||||
"traefik.http.Routers.SuperHost.Rule=Host(`my-super.host`)",
|
||||
},
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress,
|
||||
}
|
||||
err = s.registerService(reg2, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Start traefik
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
req.Host = "my-super.host"
|
||||
|
||||
err = try.Request(req, 2*time.Second, try.StatusCodeIs(200), try.BodyContainsOr("Hostname: whoami1"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
req, err = http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
req.Host = "my.super.host"
|
||||
|
||||
err = try.Request(req, 2*time.Second, try.StatusCodeIs(200), try.BodyContainsOr("Hostname: whoami2"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami1", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami2", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestSameServiceIDOnDifferentConsulAgent(c *check.C) {
|
||||
tempObjects := struct {
|
||||
ConsulAddress string
|
||||
DefaultRule string
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, "fixtures/consul_catalog/default_not_exposed.toml", tempObjects)
|
||||
defer os.Remove(file)
|
||||
|
||||
// Start a container with some tags
|
||||
tags := []string{
|
||||
"traefik.enable=true",
|
||||
"traefik.http.Routers.Super.service=whoami",
|
||||
"traefik.http.Routers.Super.Rule=Host(`my.super.host`)",
|
||||
}
|
||||
|
||||
reg1 := &api.AgentServiceRegistration{
|
||||
ID: "whoami",
|
||||
Name: "whoami",
|
||||
Tags: tags,
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
|
||||
}
|
||||
err := s.registerService(reg1, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
reg2 := &api.AgentServiceRegistration{
|
||||
ID: "whoami",
|
||||
Name: "whoami",
|
||||
Tags: tags,
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress,
|
||||
}
|
||||
err = s.registerService(reg2, true)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Start traefik
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
req.Host = "my.super.host"
|
||||
|
||||
err = try.Request(req, 2*time.Second, try.StatusCodeIs(200), try.BodyContainsOr("Hostname: whoami1", "Hostname: whoami2"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
req, err = http.NewRequest(http.MethodGet, "http://127.0.0.1:8080/api/rawdata", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.Request(req, 2*time.Second, try.StatusCodeIs(200),
|
||||
try.BodyContainsOr(s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
|
||||
s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami1", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami2", true)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestConsulServiceWithOneMissingLabels(c *check.C) {
|
||||
tempObjects := struct {
|
||||
ConsulAddress string
|
||||
DefaultRule string
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
DefaultRule: "Host(`{{ normalize .Name }}.consul.localhost`)",
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, "fixtures/consul_catalog/simple.toml", tempObjects)
|
||||
defer os.Remove(file)
|
||||
|
||||
// Start a container with some tags
|
||||
reg := &api.AgentServiceRegistration{
|
||||
ID: "whoami1",
|
||||
Name: "whoami",
|
||||
Tags: []string{
|
||||
"traefik.random.value=my.super.host",
|
||||
},
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
|
||||
}
|
||||
|
||||
err := s.registerService(reg, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Start traefik
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/version", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
req.Host = "my.super.host"
|
||||
|
||||
// FIXME Need to wait than 500 milliseconds more (for swarm or traefik to boot up ?)
|
||||
// TODO validate : run on 80
|
||||
// Expected a 404 as we did not configure anything
|
||||
err = try.Request(req, 1500*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *ConsulCatalogSuite) TestConsulServiceWithHealthCheck(c *check.C) {
|
||||
tags := []string{
|
||||
"traefik.enable=true",
|
||||
"traefik.http.routers.router1.rule=Path(`/whoami`)",
|
||||
"traefik.http.routers.router1.service=service1",
|
||||
"traefik.http.services.service1.loadBalancer.server.url=http://" + s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
|
||||
}
|
||||
|
||||
reg1 := &api.AgentServiceRegistration{
|
||||
ID: "whoami1",
|
||||
Name: "whoami",
|
||||
Tags: tags,
|
||||
Port: 80,
|
||||
Address: s.composeProject.Container(c, "whoami1").NetworkSettings.IPAddress,
|
||||
Check: &api.AgentServiceCheck{
|
||||
CheckID: "some-failed-check",
|
||||
TCP: "127.0.0.1:1234",
|
||||
Name: "some-failed-check",
|
||||
Interval: "1s",
|
||||
Timeout: "1s",
|
||||
},
|
||||
}
|
||||
|
||||
err := s.registerService(reg1, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
tempObjects := struct {
|
||||
ConsulAddress string
|
||||
}{
|
||||
ConsulAddress: s.consulAddress,
|
||||
}
|
||||
|
||||
file := s.adaptFile(c, "fixtures/consul_catalog/simple.toml", tempObjects)
|
||||
defer os.Remove(file)
|
||||
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err = cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8000/whoami", 2*time.Second, try.StatusCodeIs(http.StatusNotFound))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami1", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
containerIP := s.composeProject.Container(c, "whoami2").NetworkSettings.IPAddress
|
||||
|
||||
reg2 := &api.AgentServiceRegistration{
|
||||
ID: "whoami2",
|
||||
Name: "whoami",
|
||||
Tags: tags,
|
||||
Port: 80,
|
||||
Address: containerIP,
|
||||
Check: &api.AgentServiceCheck{
|
||||
CheckID: "some-ok-check",
|
||||
TCP: containerIP + ":80",
|
||||
Name: "some-ok-check",
|
||||
Interval: "1s",
|
||||
Timeout: "1s",
|
||||
},
|
||||
}
|
||||
|
||||
err = s.registerService(reg2, false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/whoami", nil)
|
||||
c.Assert(err, checker.IsNil)
|
||||
req.Host = "whoami"
|
||||
|
||||
// FIXME Need to wait for up to 10 seconds (for consul discovery or traefik to boot up ?)
|
||||
err = try.Request(req, 10*time.Second, try.StatusCodeIs(200), try.BodyContainsOr("Hostname: whoami2"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = s.deregisterService("whoami2", false)
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
@@ -4,7 +4,6 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/containous/traefik/v2/integration/try"
|
||||
@@ -71,18 +70,15 @@ func (s *DockerComposeSuite) TestComposeScale(c *check.C) {
|
||||
err = json.NewDecoder(resp.Body).Decode(&rtconf)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// check that we have only three routers (the one from this test + 2 unrelated internal ones)
|
||||
c.Assert(rtconf.Routers, checker.HasLen, 3)
|
||||
// check that we have only one router
|
||||
c.Assert(rtconf.Routers, checker.HasLen, 1)
|
||||
|
||||
// check that we have only one service (not counting the internal ones) with n servers
|
||||
// check that we have only one service with n servers
|
||||
services := rtconf.Services
|
||||
c.Assert(services, checker.HasLen, 3)
|
||||
for name, service := range services {
|
||||
if strings.HasSuffix(name, "@internal") {
|
||||
continue
|
||||
}
|
||||
c.Assert(name, checker.Equals, composeService+"-integrationtest"+composeProject+"@docker")
|
||||
c.Assert(service.LoadBalancer.Servers, checker.HasLen, serviceCount)
|
||||
c.Assert(services, checker.HasLen, 1)
|
||||
for k, v := range services {
|
||||
c.Assert(k, checker.Equals, composeService+"-integrationtest"+composeProject+"@docker")
|
||||
c.Assert(v.LoadBalancer.Servers, checker.HasLen, serviceCount)
|
||||
// We could break here, but we don't just to keep us honest.
|
||||
}
|
||||
}
|
||||
|
@@ -1,20 +0,0 @@
|
||||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers]
|
||||
[providers.consulCatalog]
|
||||
exposedByDefault = false
|
||||
refreshInterval = "500ms"
|
||||
[providers.consulCatalog.endpoint]
|
||||
address = "{{ .ConsulAddress }}"
|
@@ -1,21 +0,0 @@
|
||||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers]
|
||||
[providers.consulCatalog]
|
||||
exposedByDefault = true
|
||||
refreshInterval = "500ms"
|
||||
defaultRule = "{{ .DefaultRule }}"
|
||||
[providers.consulCatalog.endpoint]
|
||||
address = "{{ .ConsulAddress }}"
|
@@ -56,18 +56,3 @@ spec:
|
||||
plural: tlsoptions
|
||||
singular: tlsoption
|
||||
scope: Namespaced
|
||||
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: traefikservices.traefik.containo.us
|
||||
|
||||
spec:
|
||||
group: traefik.containo.us
|
||||
version: v1alpha1
|
||||
names:
|
||||
kind: TraefikService
|
||||
plural: traefikservices
|
||||
singular: traefikservice
|
||||
scope: Namespaced
|
||||
|
@@ -1,62 +0,0 @@
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: mirror1
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
mirroring:
|
||||
name: whoami
|
||||
port: 80
|
||||
mirrors:
|
||||
- name: whoami
|
||||
port: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: TraefikService
|
||||
metadata:
|
||||
name: wrr1
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
weighted:
|
||||
services:
|
||||
- name: mirror1
|
||||
kind: TraefikService
|
||||
- name: whoami
|
||||
port: 80
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: test3.route
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
routes:
|
||||
- match: Host(`foo.com`) && PathPrefix(`/wrr1`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: wrr1
|
||||
kind: TraefikService
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: api.route
|
||||
namespace: default
|
||||
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
routes:
|
||||
- match: PathPrefix(`/api`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: api@internal
|
||||
kind: TraefikService
|
@@ -6,6 +6,7 @@
|
||||
level = "DEBUG"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.footcp]
|
||||
|
@@ -2,12 +2,12 @@
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
|
@@ -19,7 +19,6 @@
|
||||
samplingParam = 1.0
|
||||
samplingServerURL = "http://{{.IP}}:5778/sampling"
|
||||
localAgentHostPort = "{{.IP}}:6831"
|
||||
traceContextHeaderName = "{{.TraceContextHeaderName}}"
|
||||
|
||||
[providers.file]
|
||||
filename = "{{ .SelfFilename }}"
|
||||
|
@@ -36,7 +36,6 @@ func Test(t *testing.T) {
|
||||
// tests launched from a container
|
||||
check.Suite(&AccessLogSuite{})
|
||||
check.Suite(&AcmeSuite{})
|
||||
check.Suite(&ConsulCatalogSuite{})
|
||||
check.Suite(&DockerComposeSuite{})
|
||||
check.Suite(&DockerSuite{})
|
||||
check.Suite(&ErrorPagesSuite{})
|
||||
|
@@ -71,7 +71,7 @@ func (s *K8sSuite) TestIngressConfiguration(c *check.C) {
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
testConfiguration(c, "testdata/rawdata-ingress.json", "8080")
|
||||
testConfiguration(c, "testdata/rawdata-ingress.json")
|
||||
}
|
||||
|
||||
func (s *K8sSuite) TestCRDConfiguration(c *check.C) {
|
||||
@@ -82,11 +82,11 @@ func (s *K8sSuite) TestCRDConfiguration(c *check.C) {
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
testConfiguration(c, "testdata/rawdata-crd.json", "8000")
|
||||
testConfiguration(c, "testdata/rawdata-crd.json")
|
||||
}
|
||||
|
||||
func testConfiguration(c *check.C, path, apiPort string) {
|
||||
err := try.GetRequest("http://127.0.0.1:"+apiPort+"/api/entrypoints", 20*time.Second, try.BodyContains(`"name":"web"`))
|
||||
func testConfiguration(c *check.C, path string) {
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/entrypoints", 20*time.Second, try.BodyContains(`"name":"web"`))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
expectedJSON := filepath.FromSlash(path)
|
||||
@@ -99,7 +99,7 @@ func testConfiguration(c *check.C, path, apiPort string) {
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
err = try.GetRequest("http://127.0.0.1:"+apiPort+"/api/rawdata", 40*time.Second, try.StatusCodeIs(http.StatusOK), matchesConfig(expectedJSON, &buf))
|
||||
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 40*time.Second, try.StatusCodeIs(http.StatusOK), matchesConfig(expectedJSON, &buf))
|
||||
|
||||
if !*updateExpected {
|
||||
if err != nil {
|
||||
|
@@ -7,7 +7,6 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -156,14 +155,10 @@ func verifyLogLines(c *check.C, fileName string, countInit int, accessLog bool)
|
||||
line := rotatedLog.Text()
|
||||
if accessLog {
|
||||
if len(line) > 0 {
|
||||
if !strings.Contains(line, "/api/rawdata") {
|
||||
CheckAccessLogFormat(c, line, count)
|
||||
count++
|
||||
}
|
||||
CheckAccessLogFormat(c, line, count)
|
||||
}
|
||||
} else {
|
||||
count++
|
||||
}
|
||||
count++
|
||||
}
|
||||
|
||||
return count
|
||||
|
@@ -1,24 +0,0 @@
|
||||
consul:
|
||||
image: consul:1.6.2
|
||||
ports:
|
||||
- 8500:8500
|
||||
command: "agent -server -bootstrap -ui -client 0.0.0.0"
|
||||
consul-agent:
|
||||
image: consul:1.6.2
|
||||
ports:
|
||||
- 8501:8500
|
||||
command: "agent -retry-join consul -client 0.0.0.0"
|
||||
links:
|
||||
- consul
|
||||
whoami1:
|
||||
image: containous/whoami:v1.3.0
|
||||
hostname: whoami1
|
||||
whoami2:
|
||||
image: containous/whoami:v1.3.0
|
||||
hostname: whoami2
|
||||
whoami3:
|
||||
image: containous/whoami:v1.3.0
|
||||
hostname: whoami3
|
||||
whoamitcp:
|
||||
image: containous/whoamitcp
|
||||
hostname: whoamitcp
|
@@ -6,7 +6,7 @@ zipkin:
|
||||
ports:
|
||||
- 9411:9411
|
||||
jaeger:
|
||||
image: jaegertracing/all-in-one:1.14
|
||||
image: jaegertracing/all-in-one:1.12
|
||||
environment:
|
||||
COLLECTOR_ZIPKIN_HTTP_PORT: 9411
|
||||
ports:
|
||||
@@ -18,4 +18,4 @@ jaeger:
|
||||
- "14268:14268"
|
||||
- "9411:9411"
|
||||
whoami:
|
||||
image: containous/whoami
|
||||
image: containous/whoami
|
@@ -30,10 +30,6 @@ func (s *RestSuite) TestSimpleConfigurationInsecure(c *check.C) {
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
// wait for Traefik
|
||||
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1000*time.Millisecond, try.BodyContains("rest@internal"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
// Expected a 404 as we did not configure anything.
|
||||
err = try.GetRequest("http://127.0.0.1:8000/", 1000*time.Millisecond, try.StatusCodeIs(http.StatusNotFound))
|
||||
c.Assert(err, checker.IsNil)
|
||||
@@ -48,15 +44,15 @@ func (s *RestSuite) TestSimpleConfigurationInsecure(c *check.C) {
|
||||
config: &dynamic.Configuration{
|
||||
HTTP: &dynamic.HTTPConfiguration{
|
||||
Routers: map[string]*dynamic.Router{
|
||||
"routerHTTP": {
|
||||
"router1": {
|
||||
EntryPoints: []string{"web"},
|
||||
Middlewares: []string{},
|
||||
Service: "serviceHTTP",
|
||||
Service: "service1",
|
||||
Rule: "PathPrefix(`/`)",
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.Service{
|
||||
"serviceHTTP": {
|
||||
"service1": {
|
||||
LoadBalancer: &dynamic.ServersLoadBalancer{
|
||||
Servers: []dynamic.Server{
|
||||
{
|
||||
@@ -75,14 +71,14 @@ func (s *RestSuite) TestSimpleConfigurationInsecure(c *check.C) {
|
||||
config: &dynamic.Configuration{
|
||||
TCP: &dynamic.TCPConfiguration{
|
||||
Routers: map[string]*dynamic.TCPRouter{
|
||||
"routerTCP": {
|
||||
"router1": {
|
||||
EntryPoints: []string{"web"},
|
||||
Service: "serviceTCP",
|
||||
Service: "service1",
|
||||
Rule: "HostSNI(`*`)",
|
||||
},
|
||||
},
|
||||
Services: map[string]*dynamic.TCPService{
|
||||
"serviceTCP": {
|
||||
"service1": {
|
||||
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
||||
Servers: []dynamic.TCPServer{
|
||||
{
|
||||
@@ -99,17 +95,17 @@ func (s *RestSuite) TestSimpleConfigurationInsecure(c *check.C) {
|
||||
}
|
||||
|
||||
for _, test := range testCase {
|
||||
data, err := json.Marshal(test.config)
|
||||
json, err := json.Marshal(test.config)
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
request, err := http.NewRequest(http.MethodPut, "http://127.0.0.1:8080/api/providers/rest", bytes.NewReader(data))
|
||||
request, err := http.NewRequest(http.MethodPut, "http://127.0.0.1:8080/api/providers/rest", bytes.NewReader(json))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
response, err := http.DefaultClient.Do(request)
|
||||
c.Assert(err, checker.IsNil)
|
||||
c.Assert(response.StatusCode, checker.Equals, http.StatusOK)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 3*time.Second, try.BodyContains(test.ruleMatch))
|
||||
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1000*time.Millisecond, try.BodyContains(test.ruleMatch))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8000/", 1000*time.Millisecond, try.StatusCodeIs(http.StatusOK))
|
||||
|
114
integration/testdata/rawdata-crd.json
vendored
114
integration/testdata/rawdata-crd.json
vendored
@@ -1,21 +1,10 @@
|
||||
{
|
||||
"routers": {
|
||||
"default-api-route-29f28a463fb5d5ba16d2@kubernetescrd": {
|
||||
"default-test.route-6b204d94623b3df4370c@kubernetescrd": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"service": "api@internal",
|
||||
"rule": "PathPrefix(`/api`)",
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
"web"
|
||||
]
|
||||
},
|
||||
"default-test-route-6b204d94623b3df4370c@kubernetescrd": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"service": "default-test-route-6b204d94623b3df4370c",
|
||||
"service": "default-test.route-6b204d94623b3df4370c",
|
||||
"rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/bar`)",
|
||||
"priority": 12,
|
||||
"tls": {
|
||||
@@ -26,30 +15,19 @@
|
||||
"web"
|
||||
]
|
||||
},
|
||||
"default-test2-route-23c7f4c450289ee29016@kubernetescrd": {
|
||||
"default-test2.route-23c7f4c450289ee29016@kubernetescrd": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"middlewares": [
|
||||
"default-mychain@kubernetescrd"
|
||||
],
|
||||
"service": "default-test2-route-23c7f4c450289ee29016",
|
||||
"service": "default-test2.route-23c7f4c450289ee29016",
|
||||
"rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/tobestripped`)",
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
"web"
|
||||
]
|
||||
},
|
||||
"default-test3-route-7d0ac22d3d8db4b82618@kubernetescrd": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"service": "default-wrr1",
|
||||
"rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/wrr1`)",
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
"web"
|
||||
]
|
||||
}
|
||||
},
|
||||
"middlewares": {
|
||||
@@ -61,7 +39,7 @@
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"default-test2-route-23c7f4c450289ee29016@kubernetescrd"
|
||||
"default-test2.route-23c7f4c450289ee29016@kubernetescrd"
|
||||
]
|
||||
},
|
||||
"default-stripprefix@kubernetescrd": {
|
||||
@@ -74,103 +52,47 @@
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"api@internal": {
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"default-api-route-29f28a463fb5d5ba16d2@kubernetescrd"
|
||||
]
|
||||
},
|
||||
"dashboard@internal": {
|
||||
"status": "enabled"
|
||||
},
|
||||
"default-mirror1@kubernetescrd": {
|
||||
"mirroring": {
|
||||
"service": "default-whoami-80",
|
||||
"mirrors": [
|
||||
{
|
||||
"name": "default-whoami-80"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": "enabled"
|
||||
},
|
||||
"default-test-route-6b204d94623b3df4370c@kubernetescrd": {
|
||||
"default-test.route-6b204d94623b3df4370c@kubernetescrd": {
|
||||
"loadBalancer": {
|
||||
"servers": [
|
||||
{
|
||||
"url": "http://10.42.0.3:80"
|
||||
"url": "http://10.42.0.2:80"
|
||||
},
|
||||
{
|
||||
"url": "http://10.42.0.5:80"
|
||||
"url": "http://10.42.0.6:80"
|
||||
}
|
||||
],
|
||||
"passHostHeader": true
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"default-test-route-6b204d94623b3df4370c@kubernetescrd"
|
||||
"default-test.route-6b204d94623b3df4370c@kubernetescrd"
|
||||
],
|
||||
"serverStatus": {
|
||||
"http://10.42.0.3:80": "UP",
|
||||
"http://10.42.0.5:80": "UP"
|
||||
"http://10.42.0.2:80": "UP",
|
||||
"http://10.42.0.6:80": "UP"
|
||||
}
|
||||
},
|
||||
"default-test2-route-23c7f4c450289ee29016@kubernetescrd": {
|
||||
"default-test2.route-23c7f4c450289ee29016@kubernetescrd": {
|
||||
"loadBalancer": {
|
||||
"servers": [
|
||||
{
|
||||
"url": "http://10.42.0.3:80"
|
||||
"url": "http://10.42.0.2:80"
|
||||
},
|
||||
{
|
||||
"url": "http://10.42.0.5:80"
|
||||
"url": "http://10.42.0.6:80"
|
||||
}
|
||||
],
|
||||
"passHostHeader": true
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"default-test2-route-23c7f4c450289ee29016@kubernetescrd"
|
||||
"default-test2.route-23c7f4c450289ee29016@kubernetescrd"
|
||||
],
|
||||
"serverStatus": {
|
||||
"http://10.42.0.3:80": "UP",
|
||||
"http://10.42.0.5:80": "UP"
|
||||
"http://10.42.0.2:80": "UP",
|
||||
"http://10.42.0.6:80": "UP"
|
||||
}
|
||||
},
|
||||
"default-whoami-80@kubernetescrd": {
|
||||
"loadBalancer": {
|
||||
"servers": [
|
||||
{
|
||||
"url": "http://10.42.0.3:80"
|
||||
},
|
||||
{
|
||||
"url": "http://10.42.0.5:80"
|
||||
}
|
||||
],
|
||||
"passHostHeader": true
|
||||
},
|
||||
"status": "enabled",
|
||||
"serverStatus": {
|
||||
"http://10.42.0.3:80": "UP",
|
||||
"http://10.42.0.5:80": "UP"
|
||||
}
|
||||
},
|
||||
"default-wrr1@kubernetescrd": {
|
||||
"weighted": {
|
||||
"services": [
|
||||
{
|
||||
"name": "default-mirror1",
|
||||
"weight": 1
|
||||
},
|
||||
{
|
||||
"name": "default-whoami-80",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"default-test3-route-7d0ac22d3d8db4b82618@kubernetescrd"
|
||||
]
|
||||
}
|
||||
},
|
||||
"tcpRouters": {
|
||||
@@ -199,7 +121,7 @@
|
||||
"address": "10.42.0.4:8080"
|
||||
},
|
||||
{
|
||||
"address": "10.42.0.6:8080"
|
||||
"address": "10.42.0.5:8080"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
73
integration/testdata/rawdata-ingress.json
vendored
73
integration/testdata/rawdata-ingress.json
vendored
@@ -1,33 +1,5 @@
|
||||
{
|
||||
"routers": {
|
||||
"api@internal": {
|
||||
"entryPoints": [
|
||||
"traefik"
|
||||
],
|
||||
"service": "api@internal",
|
||||
"rule": "PathPrefix(`/api`)",
|
||||
"priority": 2147483646,
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
"traefik"
|
||||
]
|
||||
},
|
||||
"dashboard@internal": {
|
||||
"entryPoints": [
|
||||
"traefik"
|
||||
],
|
||||
"middlewares": [
|
||||
"dashboard_redirect@internal",
|
||||
"dashboard_stripprefix@internal"
|
||||
],
|
||||
"service": "dashboard@internal",
|
||||
"rule": "PathPrefix(`/`)",
|
||||
"priority": 2147483645,
|
||||
"status": "enabled",
|
||||
"using": [
|
||||
"traefik"
|
||||
]
|
||||
},
|
||||
"whoami-test-https-whoami-tls@kubernetes": {
|
||||
"service": "default-whoami-http",
|
||||
"rule": "Host(`whoami.test.https`) \u0026\u0026 PathPrefix(`/whoami`)",
|
||||
@@ -57,52 +29,15 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"middlewares": {
|
||||
"dashboard_redirect@internal": {
|
||||
"redirectRegex": {
|
||||
"regex": "^(http:\\/\\/[^:\\/]+(:\\d+)?)\\/$",
|
||||
"replacement": "${1}/dashboard/",
|
||||
"permanent": true
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"dashboard@internal"
|
||||
]
|
||||
},
|
||||
"dashboard_stripprefix@internal": {
|
||||
"stripPrefix": {
|
||||
"prefixes": [
|
||||
"/dashboard/",
|
||||
"/dashboard"
|
||||
]
|
||||
},
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"dashboard@internal"
|
||||
]
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"api@internal": {
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"api@internal"
|
||||
]
|
||||
},
|
||||
"dashboard@internal": {
|
||||
"status": "enabled",
|
||||
"usedBy": [
|
||||
"dashboard@internal"
|
||||
]
|
||||
},
|
||||
"default-whoami-http@kubernetes": {
|
||||
"loadBalancer": {
|
||||
"servers": [
|
||||
{
|
||||
"url": "http://10.42.0.4:80"
|
||||
"url": "http://10.42.0.2:80"
|
||||
},
|
||||
{
|
||||
"url": "http://10.42.0.6:80"
|
||||
"url": "http://10.42.0.4:80"
|
||||
}
|
||||
],
|
||||
"passHostHeader": true
|
||||
@@ -114,8 +49,8 @@
|
||||
"whoami-test-whoami@kubernetes"
|
||||
],
|
||||
"serverStatus": {
|
||||
"http://10.42.0.4:80": "UP",
|
||||
"http://10.42.0.6:80": "UP"
|
||||
"http://10.42.0.2:80": "UP",
|
||||
"http://10.42.0.4:80": "UP"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,10 +18,9 @@ type TracingSuite struct {
|
||||
}
|
||||
|
||||
type TracingTemplate struct {
|
||||
WhoAmiIP string
|
||||
WhoAmiPort int
|
||||
IP string
|
||||
TraceContextHeaderName string
|
||||
WhoAmiIP string
|
||||
WhoAmiPort int
|
||||
IP string
|
||||
}
|
||||
|
||||
func (s *TracingSuite) SetUpSuite(c *check.C) {
|
||||
@@ -158,10 +157,9 @@ func (s *TracingSuite) TestJaegerRateLimit(c *check.C) {
|
||||
s.startJaeger(c)
|
||||
defer s.composeProject.Stop(c, "jaeger")
|
||||
file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
|
||||
WhoAmiIP: s.WhoAmiIP,
|
||||
WhoAmiPort: s.WhoAmiPort,
|
||||
IP: s.IP,
|
||||
TraceContextHeaderName: "uber-trace-id",
|
||||
WhoAmiIP: s.WhoAmiIP,
|
||||
WhoAmiPort: s.WhoAmiPort,
|
||||
IP: s.IP,
|
||||
})
|
||||
defer os.Remove(file)
|
||||
|
||||
@@ -208,10 +206,9 @@ func (s *TracingSuite) TestJaegerRetry(c *check.C) {
|
||||
s.startJaeger(c)
|
||||
defer s.composeProject.Stop(c, "jaeger")
|
||||
file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
|
||||
WhoAmiIP: s.WhoAmiIP,
|
||||
WhoAmiPort: 81,
|
||||
IP: s.IP,
|
||||
TraceContextHeaderName: "uber-trace-id",
|
||||
WhoAmiIP: s.WhoAmiIP,
|
||||
WhoAmiPort: 81,
|
||||
IP: s.IP,
|
||||
})
|
||||
defer os.Remove(file)
|
||||
|
||||
@@ -236,38 +233,9 @@ func (s *TracingSuite) TestJaegerAuth(c *check.C) {
|
||||
s.startJaeger(c)
|
||||
defer s.composeProject.Stop(c, "jaeger")
|
||||
file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
|
||||
WhoAmiIP: s.WhoAmiIP,
|
||||
WhoAmiPort: s.WhoAmiPort,
|
||||
IP: s.IP,
|
||||
TraceContextHeaderName: "uber-trace-id",
|
||||
})
|
||||
defer os.Remove(file)
|
||||
|
||||
cmd, display := s.traefikCmd(withConfigFile(file))
|
||||
defer display(c)
|
||||
err := cmd.Start()
|
||||
c.Assert(err, checker.IsNil)
|
||||
defer cmd.Process.Kill()
|
||||
|
||||
// wait for traefik
|
||||
err = try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("basic-auth"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.GetRequest("http://127.0.0.1:8000/auth", 500*time.Millisecond, try.StatusCodeIs(http.StatusUnauthorized))
|
||||
c.Assert(err, checker.IsNil)
|
||||
|
||||
err = try.GetRequest("http://"+s.IP+":16686/api/traces?service=tracing", 20*time.Second, try.BodyContains("EntryPoint web", "basic-auth@file"))
|
||||
c.Assert(err, checker.IsNil)
|
||||
}
|
||||
|
||||
func (s *TracingSuite) TestJaegerCustomHeader(c *check.C) {
|
||||
s.startJaeger(c)
|
||||
defer s.composeProject.Stop(c, "jaeger")
|
||||
file := s.adaptFile(c, "fixtures/tracing/simple-jaeger.toml", TracingTemplate{
|
||||
WhoAmiIP: s.WhoAmiIP,
|
||||
WhoAmiPort: s.WhoAmiPort,
|
||||
IP: s.IP,
|
||||
TraceContextHeaderName: "powpow",
|
||||
WhoAmiIP: s.WhoAmiIP,
|
||||
WhoAmiPort: s.WhoAmiPort,
|
||||
IP: s.IP,
|
||||
})
|
||||
defer os.Remove(file)
|
||||
|
||||
|
@@ -27,6 +27,12 @@ func (g DashboardHandler) Append(router *mux.Router) {
|
||||
http.Redirect(response, request, request.Header.Get("X-Forwarded-Prefix")+"/dashboard/", http.StatusFound)
|
||||
})
|
||||
|
||||
router.Methods(http.MethodGet).
|
||||
Path("/dashboard/status").
|
||||
HandlerFunc(func(response http.ResponseWriter, request *http.Request) {
|
||||
http.Redirect(response, request, "/dashboard/", http.StatusFound)
|
||||
})
|
||||
|
||||
router.Methods(http.MethodGet).
|
||||
PathPrefix("/dashboard/").
|
||||
Handler(http.StripPrefix("/dashboard/", http.FileServer(g.Assets)))
|
||||
|
@@ -44,19 +44,23 @@ type RunTimeRepresentation struct {
|
||||
|
||||
// Handler serves the configuration and status of Traefik on API endpoints.
|
||||
type Handler struct {
|
||||
dashboard bool
|
||||
debug bool
|
||||
staticConfig static.Configuration
|
||||
dashboardAssets *assetfs.AssetFS
|
||||
|
||||
dashboard bool
|
||||
debug bool
|
||||
// runtimeConfiguration is the data set used to create all the data representations exposed by the API.
|
||||
runtimeConfiguration *runtime.Configuration
|
||||
staticConfig static.Configuration
|
||||
// statistics *types.Statistics
|
||||
// stats *thoasstats.Stats // FIXME stats
|
||||
// StatsRecorder *middlewares.StatsRecorder // FIXME stats
|
||||
dashboardAssets *assetfs.AssetFS
|
||||
}
|
||||
|
||||
// NewBuilder returns a http.Handler builder based on runtime.Configuration
|
||||
func NewBuilder(staticConfig static.Configuration) func(*runtime.Configuration) http.Handler {
|
||||
return func(configuration *runtime.Configuration) http.Handler {
|
||||
return New(staticConfig, configuration).createRouter()
|
||||
router := mux.NewRouter()
|
||||
New(staticConfig, configuration).Append(router)
|
||||
return router
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +73,8 @@ func New(staticConfig static.Configuration, runtimeConfig *runtime.Configuration
|
||||
}
|
||||
|
||||
return &Handler{
|
||||
dashboard: staticConfig.API.Dashboard,
|
||||
dashboard: staticConfig.API.Dashboard,
|
||||
// statistics: staticConfig.API.Statistics,
|
||||
dashboardAssets: staticConfig.API.DashboardAssets,
|
||||
runtimeConfiguration: rConfig,
|
||||
staticConfig: staticConfig,
|
||||
@@ -77,10 +82,8 @@ func New(staticConfig static.Configuration, runtimeConfig *runtime.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
// createRouter creates API routes and router.
|
||||
func (h Handler) createRouter() *mux.Router {
|
||||
router := mux.NewRouter()
|
||||
|
||||
// Append add api routes on a router
|
||||
func (h Handler) Append(router *mux.Router) {
|
||||
if h.debug {
|
||||
DebugHandler{}.Append(router)
|
||||
}
|
||||
@@ -105,13 +108,15 @@ func (h Handler) createRouter() *mux.Router {
|
||||
router.Methods(http.MethodGet).Path("/api/tcp/services").HandlerFunc(h.getTCPServices)
|
||||
router.Methods(http.MethodGet).Path("/api/tcp/services/{serviceID}").HandlerFunc(h.getTCPService)
|
||||
|
||||
// FIXME stats
|
||||
// health route
|
||||
// router.Methods(http.MethodGet).Path("/health").HandlerFunc(p.getHealthHandler)
|
||||
|
||||
version.Handler{}.Append(router)
|
||||
|
||||
if h.dashboard {
|
||||
DashboardHandler{Assets: h.dashboardAssets}.Append(router)
|
||||
}
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
func (h Handler) getRuntimeConfiguration(rw http.ResponseWriter, request *http.Request) {
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/containous/traefik/v2/pkg/config/runtime"
|
||||
"github.com/containous/traefik/v2/pkg/config/static"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -198,7 +199,10 @@ func TestHandler_EntryPoints(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
handler := New(test.conf, &runtime.Configuration{})
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
router := mux.NewRouter()
|
||||
handler.Append(router)
|
||||
|
||||
server := httptest.NewServer(router)
|
||||
|
||||
resp, err := http.DefaultClient.Get(server.URL + test.path)
|
||||
require.NoError(t, err)
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||
"github.com/containous/traefik/v2/pkg/config/runtime"
|
||||
"github.com/containous/traefik/v2/pkg/config/static"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -812,7 +813,10 @@ func TestHandler_HTTP(t *testing.T) {
|
||||
rtConf.GetRoutersByEntryPoints(context.Background(), []string{"web"}, false)
|
||||
|
||||
handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf)
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
router := mux.NewRouter()
|
||||
handler.Append(router)
|
||||
|
||||
server := httptest.NewServer(router)
|
||||
|
||||
resp, err := http.DefaultClient.Get(server.URL + test.path)
|
||||
require.NoError(t, err)
|
||||
|
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/containous/traefik/v2/pkg/provider/rest"
|
||||
"github.com/containous/traefik/v2/pkg/tracing/jaeger"
|
||||
"github.com/containous/traefik/v2/pkg/types"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -251,7 +252,10 @@ func TestHandler_Overview(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
handler := New(test.confStatic, &test.confDyn)
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
router := mux.NewRouter()
|
||||
handler.Append(router)
|
||||
|
||||
server := httptest.NewServer(router)
|
||||
|
||||
resp, err := http.DefaultClient.Get(server.URL + test.path)
|
||||
require.NoError(t, err)
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||
"github.com/containous/traefik/v2/pkg/config/runtime"
|
||||
"github.com/containous/traefik/v2/pkg/config/static"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -519,7 +520,10 @@ func TestHandler_TCP(t *testing.T) {
|
||||
rtConf.GetTCPRoutersByEntryPoints(context.Background(), []string{"web"})
|
||||
|
||||
handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf)
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
router := mux.NewRouter()
|
||||
handler.Append(router)
|
||||
|
||||
server := httptest.NewServer(router)
|
||||
|
||||
resp, err := http.DefaultClient.Get(server.URL + test.path)
|
||||
require.NoError(t, err)
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
||||
"github.com/containous/traefik/v2/pkg/config/runtime"
|
||||
"github.com/containous/traefik/v2/pkg/config/static"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -136,7 +137,10 @@ func TestHandler_RawData(t *testing.T) {
|
||||
|
||||
rtConf.PopulateUsedBy()
|
||||
handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf)
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
router := mux.NewRouter()
|
||||
handler.Append(router)
|
||||
|
||||
server := httptest.NewServer(router)
|
||||
|
||||
resp, err := http.DefaultClient.Get(server.URL + test.path)
|
||||
require.NoError(t, err)
|
||||
|
@@ -4,20 +4,18 @@ package cli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// Command structure contains program/command information (command name and description).
|
||||
type Command struct {
|
||||
Name string
|
||||
Description string
|
||||
Configuration interface{}
|
||||
Resources []ResourceLoader
|
||||
Run func([]string) error
|
||||
CustomHelpFunc func(io.Writer, *Command) error
|
||||
Hidden bool
|
||||
Name string
|
||||
Description string
|
||||
Configuration interface{}
|
||||
Resources []ResourceLoader
|
||||
Run func([]string) error
|
||||
Hidden bool
|
||||
// AllowArg if not set, disallows any argument that is not a known command or a sub-command.
|
||||
AllowArg bool
|
||||
subCommands []*Command
|
||||
@@ -37,15 +35,6 @@ func (c *Command) AddCommand(cmd *Command) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrintHelp calls the custom help function of the command if it's set.
|
||||
// Otherwise, it calls the default help function.
|
||||
func (c *Command) PrintHelp(w io.Writer) error {
|
||||
if c.CustomHelpFunc != nil {
|
||||
return c.CustomHelpFunc(w, c)
|
||||
}
|
||||
return PrintHelp(w, c)
|
||||
}
|
||||
|
||||
// Execute Executes a command.
|
||||
func Execute(cmd *Command) error {
|
||||
return execute(cmd, os.Args, true)
|
||||
@@ -72,12 +61,10 @@ func execute(cmd *Command, args []string, root bool) error {
|
||||
|
||||
// Calls command by its name.
|
||||
if len(args) >= 2 && cmd.Name == args[1] {
|
||||
if len(args) < 3 || !contains(cmd.subCommands, args[2]) {
|
||||
if err := run(cmd, args[2:]); err != nil {
|
||||
return fmt.Errorf("command %s error: %v", cmd.Name, err)
|
||||
}
|
||||
return nil
|
||||
if err := run(cmd, args[2:]); err != nil {
|
||||
return fmt.Errorf("command %s error: %v", cmd.Name, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// No sub-command, calls the current command.
|
||||
@@ -91,9 +78,6 @@ func execute(cmd *Command, args []string, root bool) error {
|
||||
// Trying to find the sub-command.
|
||||
for _, subCmd := range cmd.subCommands {
|
||||
if len(args) >= 2 && subCmd.Name == args[1] {
|
||||
return execute(subCmd, args, false)
|
||||
}
|
||||
if len(args) >= 3 && subCmd.Name == args[2] {
|
||||
return execute(subCmd, args[1:], false)
|
||||
}
|
||||
}
|
||||
@@ -103,16 +87,16 @@ func execute(cmd *Command, args []string, root bool) error {
|
||||
|
||||
func run(cmd *Command, args []string) error {
|
||||
if len(args) > 0 && !isFlag(args[0]) && !cmd.AllowArg {
|
||||
_ = cmd.PrintHelp(os.Stdout)
|
||||
_ = PrintHelp(os.Stdout, cmd)
|
||||
return fmt.Errorf("command not found: %s", args[0])
|
||||
}
|
||||
|
||||
if isHelp(args) {
|
||||
return cmd.PrintHelp(os.Stdout)
|
||||
return PrintHelp(os.Stdout, cmd)
|
||||
}
|
||||
|
||||
if cmd.Run == nil {
|
||||
_ = cmd.PrintHelp(os.Stdout)
|
||||
_ = PrintHelp(os.Stdout, cmd)
|
||||
return fmt.Errorf("command %s is not runnable", cmd.Name)
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,6 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -59,63 +55,6 @@ func TestCommand_AddCommand(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommand_PrintHelp(t *testing.T) {
|
||||
testCases := []struct {
|
||||
desc string
|
||||
command *Command
|
||||
expectedOutput string
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
desc: "print default help",
|
||||
command: &Command{},
|
||||
expectedOutput: " \n\nUsage: [command] [flags] [arguments]\n\nUse \" [command] --help\" for help on any command.\n\n",
|
||||
},
|
||||
{
|
||||
desc: "print custom help",
|
||||
command: &Command{
|
||||
Name: "root",
|
||||
Description: "Description for root",
|
||||
Configuration: &struct {
|
||||
Foo []struct {
|
||||
Field string
|
||||
}
|
||||
}{},
|
||||
Run: func(args []string) error {
|
||||
return nil
|
||||
},
|
||||
CustomHelpFunc: func(w io.Writer, _ *Command) error {
|
||||
_, _ = fmt.Fprintln(w, "test")
|
||||
return nil
|
||||
},
|
||||
},
|
||||
expectedOutput: "test\n",
|
||||
},
|
||||
{
|
||||
desc: "error is returned from called help",
|
||||
command: &Command{
|
||||
CustomHelpFunc: func(_ io.Writer, _ *Command) error {
|
||||
return errors.New("test")
|
||||
},
|
||||
},
|
||||
expectedError: errors.New("test"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
test := test
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
buffer := &bytes.Buffer{}
|
||||
err := test.command.PrintHelp(buffer)
|
||||
|
||||
assert.Equal(t, test.expectedError, err)
|
||||
assert.Equal(t, test.expectedOutput, buffer.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_execute(t *testing.T) {
|
||||
var called string
|
||||
|
||||
@@ -620,88 +559,6 @@ func Test_execute(t *testing.T) {
|
||||
},
|
||||
expected: expected{result: "root---foo=bar--fii=bir"},
|
||||
},
|
||||
{
|
||||
desc: "sub command help",
|
||||
args: []string{"", "test", "subtest", "--help"},
|
||||
command: func() *Command {
|
||||
rootCmd := &Command{
|
||||
Name: "test",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
}
|
||||
|
||||
subCmd := &Command{
|
||||
Name: "subtest",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
}
|
||||
|
||||
err := rootCmd.AddCommand(subCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
subSubCmd := &Command{
|
||||
Name: "subsubtest",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
}
|
||||
|
||||
err = subCmd.AddCommand(subSubCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
subSubSubCmd := &Command{
|
||||
Name: "subsubsubtest",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
Run: func([]string) error {
|
||||
called = "subsubsubtest"
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
err = subSubCmd.AddCommand(subSubSubCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
return rootCmd
|
||||
},
|
||||
expected: expected{},
|
||||
},
|
||||
{
|
||||
desc: "sub sub command help",
|
||||
args: []string{"", "test", "subtest", "subsubtest", "--help"},
|
||||
command: func() *Command {
|
||||
rootCmd := &Command{
|
||||
Name: "test",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
}
|
||||
|
||||
subCmd := &Command{
|
||||
Name: "subtest",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
}
|
||||
|
||||
err := rootCmd.AddCommand(subCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
subSubCmd := &Command{
|
||||
Name: "subsubtest",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
}
|
||||
|
||||
err = subCmd.AddCommand(subSubCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
subSubSubCmd := &Command{
|
||||
Name: "subsubsubtest",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
Run: func([]string) error {
|
||||
called = "subsubsubtest"
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
err = subSubCmd.AddCommand(subSubSubCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
return rootCmd
|
||||
},
|
||||
expected: expected{},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
@@ -899,43 +756,3 @@ Flags:
|
||||
|
||||
`, string(out))
|
||||
}
|
||||
|
||||
func TestName(t *testing.T) {
|
||||
rootCmd := &Command{
|
||||
Name: "test",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
}
|
||||
|
||||
subCmd := &Command{
|
||||
Name: "subtest",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
}
|
||||
|
||||
err := rootCmd.AddCommand(subCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
subSubCmd := &Command{
|
||||
Name: "subsubtest",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
Run: func([]string) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
err = subCmd.AddCommand(subSubCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
subSubSubCmd := &Command{
|
||||
Name: "subsubsubtest",
|
||||
Resources: []ResourceLoader{&FlagLoader{}},
|
||||
Run: func([]string) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
err = subSubCmd.AddCommand(subSubSubCmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = execute(rootCmd, []string{"", "test", "subtest", "subsubtest", "subsubsubtest", "--help"}, true)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user