From e7d3f4316f639ae463fce008b24afae6ffd22ee4 Mon Sep 17 00:00:00 2001 From: Mal Curtis Date: Tue, 23 Feb 2021 08:28:05 +1300 Subject: [PATCH 01/16] Fix typo in routing/services/index.md --- docs/content/routing/services/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md index 96d4dff5d..2d69d42e6 100644 --- a/docs/content/routing/services/index.md +++ b/docs/content/routing/services/index.md @@ -332,7 +332,7 @@ Below are the available options for the health check mechanism: !!! info "Recovering Servers" Traefik keeps monitoring the health of unhealthy servers. - If a server has recovered (returning `2xx` -> `3xx` responses again), it will be added back to the load balacer rotation pool. + If a server has recovered (returning `2xx` -> `3xx` responses again), it will be added back to the load balancer rotation pool. !!! warning "Health check in Kubernetes" From 32500773b8808654628556015c467e0b93bb3688 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Wed, 24 Feb 2021 17:06:03 +0100 Subject: [PATCH 02/16] Update Yaegi to v0.9.13 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 11a9ff6d1..c47262ec4 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( github.com/tinylib/msgp v1.0.2 // indirect github.com/traefik/gziphandler v1.1.2-0.20210212101304-175e0fad6888 github.com/traefik/paerser v0.1.1 - github.com/traefik/yaegi v0.9.8 + github.com/traefik/yaegi v0.9.13 github.com/uber/jaeger-client-go v2.25.0+incompatible github.com/uber/jaeger-lib v2.2.0+incompatible github.com/unrolled/render v1.0.2 diff --git a/go.sum b/go.sum index 4d14d54ff..1d4c4127a 100644 --- a/go.sum +++ b/go.sum @@ -881,8 +881,8 @@ github.com/traefik/gziphandler v1.1.2-0.20210212101304-175e0fad6888 h1:GMY0C+M/w github.com/traefik/gziphandler v1.1.2-0.20210212101304-175e0fad6888/go.mod h1:sLqwoN03tkluITKL+lPEZbfsJQU2suYoKbrR/HeV9aM= github.com/traefik/paerser v0.1.1 h1:Suj0iA4hTAV6E4Dh5/++TXAj5u6iTwydBlFssIUz+9w= github.com/traefik/paerser v0.1.1/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE= -github.com/traefik/yaegi v0.9.8 h1:sYGKV2d911B9olVsSO/nRmjIh+CQTffAUSzoyv4a4/4= -github.com/traefik/yaegi v0.9.8/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk= +github.com/traefik/yaegi v0.9.13 h1:LQzMIjTp3fFyAULaWel88iJz1QL2lBd0bbaOSV8or4o= +github.com/traefik/yaegi v0.9.13/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk= github.com/transip/gotransip/v6 v6.2.0 h1:0Z+qVsyeiQdWfcAUeJyF0IEKAPvhJwwpwPi2WGtBIiE= github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= From dd0701dd1688910ed24c68928cb5d0877c15d189 Mon Sep 17 00:00:00 2001 From: Julien Salleyron Date: Thu, 25 Feb 2021 17:20:04 +0100 Subject: [PATCH 03/16] fix: wait for file and internal before applying configurations Co-authored-by: Ludovic Fernandez --- cmd/traefik/traefik.go | 1 + pkg/provider/aggregator/aggregator.go | 10 ++++++---- pkg/provider/aggregator/aggregator_test.go | 5 ++--- pkg/server/configurationwatcher.go | 10 ++++++++-- pkg/server/configurationwatcher_test.go | 16 ++++++++-------- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index 6126a1a7c..9ad068e4f 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -256,6 +256,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err providerAggregator, time.Duration(staticConfiguration.Providers.ProvidersThrottleDuration), getDefaultsEntrypoints(staticConfiguration), + "internal", ) // TLS diff --git a/pkg/provider/aggregator/aggregator.go b/pkg/provider/aggregator/aggregator.go index d000fa8af..89bcae4d5 100644 --- a/pkg/provider/aggregator/aggregator.go +++ b/pkg/provider/aggregator/aggregator.go @@ -119,10 +119,6 @@ func (p ProviderAggregator) Init() error { // Provide calls the provide method of every providers. func (p ProviderAggregator) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error { - if p.internalProvider != nil { - launchProvider(configurationChan, pool, p.internalProvider) - } - if p.fileProvider != nil { launchProvider(configurationChan, pool, p.fileProvider) } @@ -134,6 +130,12 @@ func (p ProviderAggregator) Provide(configurationChan chan<- dynamic.Message, po }) } + // internal provider must be the last because we use it to know if all the providers are loaded. + // ConfigurationWatcher will wait for this requiredProvider before applying configurations. + if p.internalProvider != nil { + launchProvider(configurationChan, pool, p.internalProvider) + } + return nil } diff --git a/pkg/provider/aggregator/aggregator_test.go b/pkg/provider/aggregator/aggregator_test.go index a88a791ba..a6363e819 100644 --- a/pkg/provider/aggregator/aggregator_test.go +++ b/pkg/provider/aggregator/aggregator_test.go @@ -32,12 +32,11 @@ func TestProviderAggregator_Provide(t *testing.T) { errCh <- aggregator.Provide(cfgCh, pool) }() - // Make sure the internal provider is always called first, followed by the file provider. - requireReceivedMessageFromProviders(t, cfgCh, []string{"internal"}) + // Make sure the file provider is always called first. requireReceivedMessageFromProviders(t, cfgCh, []string{"file"}) // Check if all providers have been called, the order doesn't matter. - requireReceivedMessageFromProviders(t, cfgCh, []string{"salad", "tomato", "onion"}) + requireReceivedMessageFromProviders(t, cfgCh, []string{"salad", "tomato", "onion", "internal"}) require.NoError(t, <-errCh) } diff --git a/pkg/server/configurationwatcher.go b/pkg/server/configurationwatcher.go index 260dcfb07..1d71fe472 100644 --- a/pkg/server/configurationwatcher.go +++ b/pkg/server/configurationwatcher.go @@ -28,6 +28,7 @@ type ConfigurationWatcher struct { configurationValidatedChan chan dynamic.Message providerConfigUpdateMap map[string]chan dynamic.Message + requiredProvider string configurationListeners []func(dynamic.Configuration) routinesPool *safe.Pool @@ -39,6 +40,7 @@ func NewConfigurationWatcher( pvd provider.Provider, providersThrottleDuration time.Duration, defaultEntryPoints []string, + requiredProvider string, ) *ConfigurationWatcher { watcher := &ConfigurationWatcher{ provider: pvd, @@ -48,6 +50,7 @@ func NewConfigurationWatcher( providersThrottleDuration: providersThrottleDuration, routinesPool: routinesPool, defaultEntryPoints: defaultEntryPoints, + requiredProvider: requiredProvider, } currentConfigurations := make(dynamic.Configurations) @@ -146,8 +149,11 @@ func (c *ConfigurationWatcher) loadMessage(configMsg dynamic.Message) { conf := mergeConfiguration(newConfigurations, c.defaultEntryPoints) conf = applyModel(conf) - for _, listener := range c.configurationListeners { - listener(conf) + // We wait for first configuration of the require provider before applying configurations. + if _, ok := newConfigurations[c.requiredProvider]; c.requiredProvider == "" || ok { + for _, listener := range c.configurationListeners { + listener(conf) + } } } diff --git a/pkg/server/configurationwatcher_test.go b/pkg/server/configurationwatcher_test.go index 44c4454b1..5c31f46df 100644 --- a/pkg/server/configurationwatcher_test.go +++ b/pkg/server/configurationwatcher_test.go @@ -55,7 +55,7 @@ func TestNewConfigurationWatcher(t *testing.T) { }}, } - watcher := NewConfigurationWatcher(routinesPool, pvd, time.Second, []string{}) + watcher := NewConfigurationWatcher(routinesPool, pvd, time.Second, []string{}, "") run := make(chan struct{}) @@ -112,7 +112,7 @@ func TestListenProvidersThrottleProviderConfigReload(t *testing.T) { }) } - watcher := NewConfigurationWatcher(routinesPool, pvd, 30*time.Millisecond, []string{}) + watcher := NewConfigurationWatcher(routinesPool, pvd, 30*time.Millisecond, []string{}, "") publishedConfigCount := 0 watcher.AddListener(func(_ dynamic.Configuration) { @@ -136,7 +136,7 @@ func TestListenProvidersSkipsEmptyConfigs(t *testing.T) { messages: []dynamic.Message{{ProviderName: "mock"}}, } - watcher := NewConfigurationWatcher(routinesPool, pvd, time.Second, []string{}) + watcher := NewConfigurationWatcher(routinesPool, pvd, time.Second, []string{}, "") watcher.AddListener(func(_ dynamic.Configuration) { t.Error("An empty configuration was published but it should not") }) @@ -162,7 +162,7 @@ func TestListenProvidersSkipsSameConfigurationForProvider(t *testing.T) { messages: []dynamic.Message{message, message}, } - watcher := NewConfigurationWatcher(routinesPool, pvd, 0, []string{}) + watcher := NewConfigurationWatcher(routinesPool, pvd, 0, []string{}, "") alreadyCalled := false watcher.AddListener(func(_ dynamic.Configuration) { @@ -205,7 +205,7 @@ func TestListenProvidersDoesNotSkipFlappingConfiguration(t *testing.T) { }, } - watcher := NewConfigurationWatcher(routinesPool, pvd, 15*time.Millisecond, []string{"defaultEP"}) + watcher := NewConfigurationWatcher(routinesPool, pvd, 15*time.Millisecond, []string{"defaultEP"}, "") var lastConfig dynamic.Configuration watcher.AddListener(func(conf dynamic.Configuration) { @@ -260,7 +260,7 @@ func TestListenProvidersPublishesConfigForEachProvider(t *testing.T) { }, } - watcher := NewConfigurationWatcher(routinesPool, pvd, 0, []string{"defaultEP"}) + watcher := NewConfigurationWatcher(routinesPool, pvd, 0, []string{"defaultEP"}, "") var publishedProviderConfig dynamic.Configuration @@ -327,7 +327,7 @@ func TestPublishConfigUpdatedByProvider(t *testing.T) { }, } - watcher := NewConfigurationWatcher(routinesPool, pvd, 30*time.Millisecond, []string{}) + watcher := NewConfigurationWatcher(routinesPool, pvd, 30*time.Millisecond, []string{}, "") publishedConfigCount := 0 watcher.AddListener(func(configuration dynamic.Configuration) { @@ -375,7 +375,7 @@ func TestPublishConfigUpdatedByConfigWatcherListener(t *testing.T) { }, } - watcher := NewConfigurationWatcher(routinesPool, pvd, 30*time.Millisecond, []string{}) + watcher := NewConfigurationWatcher(routinesPool, pvd, 30*time.Millisecond, []string{}, "") publishedConfigCount := 0 watcher.AddListener(func(configuration dynamic.Configuration) { From c35a8bdb159ee4f60a8ffeb331e09001a4e5ede6 Mon Sep 17 00:00:00 2001 From: Tom Moulard Date: Fri, 26 Feb 2021 10:20:03 +0100 Subject: [PATCH 04/16] Fixing doc for default value of checknewversion --- docs/content/reference/static-configuration/cli-ref.md | 6 +++--- docs/content/reference/static-configuration/env-ref.md | 6 +++--- internal/gendoc.go | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index 48e81df02..934569ab3 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -184,7 +184,7 @@ plugin's module name. plugin's version. `--global.checknewversion`: -Periodically check if a new version has been released. (Default: ```false```) +Periodically check if a new version has been released. (Default: ```true```) `--global.sendanonymoususage`: Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. (Default: ```false```) @@ -694,7 +694,7 @@ Display additional provider logs. (Default: ```false```) Watch provider. (Default: ```true```) `--providers.providersthrottleduration`: -Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```0```) +Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```2```) `--providers.rancher`: Enable Rancher backend with default settings. (Default: ```false```) @@ -802,7 +802,7 @@ The amount of time to wait for a server's response headers after fully writing t Disable SSL certificate verification. (Default: ```false```) `--serverstransport.maxidleconnsperhost`: -If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used (Default: ```0```) +If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used (Default: ```200```) `--serverstransport.rootcas`: Add cert file for self-signed certificate. diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index f3bc6d607..46e227b08 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -184,7 +184,7 @@ plugin's module name. plugin's version. `TRAEFIK_GLOBAL_CHECKNEWVERSION`: -Periodically check if a new version has been released. (Default: ```false```) +Periodically check if a new version has been released. (Default: ```true```) `TRAEFIK_GLOBAL_SENDANONYMOUSUSAGE`: Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. (Default: ```false```) @@ -694,7 +694,7 @@ Display additional provider logs. (Default: ```false```) Watch provider. (Default: ```true```) `TRAEFIK_PROVIDERS_PROVIDERSTHROTTLEDURATION`: -Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```0```) +Backends throttle duration: minimum duration between 2 events from providers before applying a new configuration. It avoids unnecessary reloads if multiples events are sent in a short amount of time. (Default: ```2```) `TRAEFIK_PROVIDERS_RANCHER`: Enable Rancher backend with default settings. (Default: ```false```) @@ -802,7 +802,7 @@ The amount of time to wait for a server's response headers after fully writing t Disable SSL certificate verification. (Default: ```false```) `TRAEFIK_SERVERSTRANSPORT_MAXIDLECONNSPERHOST`: -If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used (Default: ```0```) +If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used (Default: ```200```) `TRAEFIK_SERVERSTRANSPORT_ROOTCAS`: Add cert file for self-signed certificate. diff --git a/internal/gendoc.go b/internal/gendoc.go index 6e6290ec3..c8d739445 100644 --- a/internal/gendoc.go +++ b/internal/gendoc.go @@ -14,7 +14,7 @@ import ( "github.com/traefik/paerser/flag" "github.com/traefik/paerser/generator" "github.com/traefik/paerser/parser" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v2/cmd" "github.com/traefik/traefik/v2/pkg/log" ) @@ -29,7 +29,7 @@ func main() { func genStaticConfDoc(outputFile, prefix string, encodeFn func(interface{}) ([]parser.Flat, error)) { logger := log.WithoutContext().WithField("file", outputFile) - element := &static.Configuration{} + element := &cmd.NewTraefikConfiguration().Configuration generator.Generate(element) From c843c182e4ac276fe45ea773f72442823c9723cc Mon Sep 17 00:00:00 2001 From: wouter bolsterlee Date: Fri, 26 Feb 2021 14:34:04 +0100 Subject: [PATCH 05/16] Address all shellcheck warnings --- script/deploy.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/script/deploy.sh b/script/deploy.sh index 8e7706564..e1598f57c 100755 --- a/script/deploy.sh +++ b/script/deploy.sh @@ -12,8 +12,10 @@ git config --global user.email "$TRAEFIKER_EMAIL" git config --global user.name "Traefiker" # load ssh key +: "${encrypted_83c521e11abe_key:?}" # ensures variable is defined +: "${encrypted_83c521e11abe_iv:?}" # same echo "Loading key..." -openssl aes-256-cbc -K $encrypted_83c521e11abe_key -iv $encrypted_83c521e11abe_iv -in .travis/traefiker_rsa.enc -out ~/.ssh/traefiker_rsa -d +openssl aes-256-cbc -K "$encrypted_83c521e11abe_key" -iv "$encrypted_83c521e11abe_iv" -in .travis/traefiker_rsa.enc -out ~/.ssh/traefiker_rsa -d eval "$(ssh-agent -s)" chmod 600 ~/.ssh/traefiker_rsa ssh-add ~/.ssh/traefiker_rsa @@ -22,10 +24,10 @@ ssh-add ~/.ssh/traefiker_rsa echo "Updating traefik-library-imag repo..." git clone git@github.com:traefik/traefik-library-image.git cd traefik-library-image -./updatev2.sh $VERSION +./updatev2.sh "$VERSION" git add -A -echo $VERSION | git commit --file - -echo $VERSION | git tag -a $VERSION --file - +echo "$VERSION" | git commit --file - +echo "$VERSION" | git tag -a "$VERSION" --file - git push -q --follow-tags -u origin master > /dev/null 2>&1 cd .. From 40cd6ada4f3d8fc68289222bd9324a17187a92ae Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Doumenjou <925513+jbdoumenjou@users.noreply.github.com> Date: Mon, 1 Mar 2021 19:14:03 +0100 Subject: [PATCH 06/16] Prepare release v2.4.6 --- CHANGELOG.md | 13 +++++++++++++ script/gcg/traefik-bugfix.toml | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 383d5bf6c..c981ca4e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## [v2.4.6](https://github.com/traefik/traefik/tree/v2.4.6) (2021-03-01) +[All Commits](https://github.com/traefik/traefik/compare/v2.4.5...v2.4.6) + +**Bug fixes:** +- **[plugins]** Update Yaegi to v0.9.13 ([#7928](https://github.com/traefik/traefik/pull/7928) by [ldez](https://github.com/ldez)) +- **[provider]** Fix: wait for file and internal before applying configurations ([#7925](https://github.com/traefik/traefik/pull/7925) by [juliens](https://github.com/juliens)) + +**Documentation:** +- **[file]** Fix reflink typo in file provider documentation ([#7913](https://github.com/traefik/traefik/pull/7913) by [vgerak](https://github.com/vgerak)) +- **[k8s/serviceapi]** Fix Kubernetes Gateway API documentation links ([#7914](https://github.com/traefik/traefik/pull/7914) by [kevinpollet](https://github.com/kevinpollet)) +- **[service]** Fix typo in routing/services/index.md ([#7922](https://github.com/traefik/traefik/pull/7922) by [snikch](https://github.com/snikch)) +- Fixing doc for default value of checknewversion ([#7933](https://github.com/traefik/traefik/pull/7933) by [tomMoulard](https://github.com/tomMoulard)) + ## [v2.4.5](https://github.com/traefik/traefik/tree/v2.4.5) (2021-02-18) [All Commits](https://github.com/traefik/traefik/compare/v2.4.3...v2.4.5) diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index c1dd907c5..fe91fd987 100644 --- a/script/gcg/traefik-bugfix.toml +++ b/script/gcg/traefik-bugfix.toml @@ -6,9 +6,9 @@ FileName = "traefik_changelog.md" # example new bugfix v2.4.5 CurrentRef = "v2.4" -PreviousRef = "v2.4.4" +PreviousRef = "v2.4.5" BaseBranch = "v2.4" -FutureCurrentRefName = "v2.4.5" +FutureCurrentRefName = "v2.4.6" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 From d2d7cf14e5e4b50205bef40f949724ec5215ffd0 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Doumenjou <925513+jbdoumenjou@users.noreply.github.com> Date: Wed, 3 Mar 2021 12:46:03 +0100 Subject: [PATCH 07/16] Bump paerser to v0.1.2 --- go.mod | 2 +- go.sum | 14 ++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index c47262ec4..94e41ea43 100644 --- a/go.mod +++ b/go.mod @@ -71,7 +71,7 @@ require ( github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 github.com/tinylib/msgp v1.0.2 // indirect github.com/traefik/gziphandler v1.1.2-0.20210212101304-175e0fad6888 - github.com/traefik/paerser v0.1.1 + github.com/traefik/paerser v0.1.2 github.com/traefik/yaegi v0.9.13 github.com/uber/jaeger-client-go v2.25.0+incompatible github.com/uber/jaeger-lib v2.2.0+incompatible diff --git a/go.sum b/go.sum index 1d4c4127a..2b1ff801f 100644 --- a/go.sum +++ b/go.sum @@ -30,13 +30,11 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7O github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg= github.com/Azure/go-autorest/autorest v0.5.0/go.mod h1:9HLKlQjVBH6U3oDfsXOeVc56THsLPw1L03yban4xThw= -github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.6 h1:5YWtOnckcudzIw8lPPBcWOnmIFWMtHci1ZWAZulMSx0= github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= github.com/Azure/go-autorest/autorest/adal v0.2.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E= -github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0= github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= @@ -44,12 +42,10 @@ github.com/Azure/go-autorest/autorest/azure/auth v0.1.0 h1:YgO/vSnJEc76NLw2ecIXv github.com/Azure/go-autorest/autorest/azure/auth v0.1.0/go.mod h1:Gf7/i2FUpyb/sGBLIFxTBzrNzBo7aPXXE3ZVeDRwdpM= github.com/Azure/go-autorest/autorest/azure/cli v0.1.0 h1:YTtBrcb6mhA+PoSW8WxFDoIIyjp13XqJeX80ssQtri4= github.com/Azure/go-autorest/autorest/azure/cli v0.1.0/go.mod h1:Dk8CUAt/b/PzkfeRsWzVG9Yj3ps8mS8ECztu43rdU8U= -github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc= github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= @@ -153,7 +149,6 @@ github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEe github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.0.2 h1:JIufpQLbh4DkbQoii76ItQIUFzevQSqOLZca4eamEDs= github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= -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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -205,7 +200,6 @@ github.com/coreos/etcd v3.3.13+incompatible h1:8F3hqu9fGYLBifCmRCJsicFqDx/D68Rt3 github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -575,7 +569,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b h1:DzHy0GlWeF0KAglaTMY7Q+khIFoG8toHP+wLFBVBQJc= github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -666,7 +659,6 @@ github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 h1:o6uBwrhM5C8Ll3MAA github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8= github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2 h1:i2Ly0B+1+rzNZHHWtD4ZwKi+OU5l+uQo1iDHZ2PmiIc= github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= @@ -823,7 +815,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm 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= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -864,7 +855,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -879,8 +869,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/traefik/gziphandler v1.1.2-0.20210212101304-175e0fad6888 h1:GMY0C+M/w8xO+/NP3Kq6sroMd+z2KbbdVr1K8o2NLHk= github.com/traefik/gziphandler v1.1.2-0.20210212101304-175e0fad6888/go.mod h1:sLqwoN03tkluITKL+lPEZbfsJQU2suYoKbrR/HeV9aM= -github.com/traefik/paerser v0.1.1 h1:Suj0iA4hTAV6E4Dh5/++TXAj5u6iTwydBlFssIUz+9w= -github.com/traefik/paerser v0.1.1/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE= +github.com/traefik/paerser v0.1.2 h1:0zvJgdwp2dNUodZHfgf+3IcaeJH2B28NcCGM+iZVtds= +github.com/traefik/paerser v0.1.2/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE= github.com/traefik/yaegi v0.9.13 h1:LQzMIjTp3fFyAULaWel88iJz1QL2lBd0bbaOSV8or4o= github.com/traefik/yaegi v0.9.13/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk= github.com/transip/gotransip/v6 v6.2.0 h1:0Z+qVsyeiQdWfcAUeJyF0IEKAPvhJwwpwPi2WGtBIiE= From ec0d03658db4762be8004d209279e14981dcaae5 Mon Sep 17 00:00:00 2001 From: Romain Date: Wed, 3 Mar 2021 16:48:04 +0100 Subject: [PATCH 08/16] Fix ServersTransport documentation Co-authored-by: mpl --- .../routing/providers/consul-catalog.md | 3 ++- docs/content/routing/providers/docker.md | 5 +++-- docs/content/routing/providers/ecs.md | 3 ++- .../routing/providers/kubernetes-crd.md | 19 ++++++++++--------- docs/content/routing/providers/kv.md | 7 ++++--- docs/content/routing/providers/marathon.md | 5 +++-- docs/content/routing/providers/rancher.md | 3 ++- 7 files changed, 26 insertions(+), 19 deletions(-) diff --git a/docs/content/routing/providers/consul-catalog.md b/docs/content/routing/providers/consul-catalog.md index 28121980e..ed88664e7 100644 --- a/docs/content/routing/providers/consul-catalog.md +++ b/docs/content/routing/providers/consul-catalog.md @@ -132,10 +132,11 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass ??? info "`traefik.http.services..loadbalancer.serverstransport`" + Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. See [serverstransport](../services/index.md#serverstransport) for more information. ```yaml - traefik.http.services..loadbalancer.serverstransport=foobar + traefik.http.services..loadbalancer.serverstransport=foobar@file ``` ??? info "`traefik.http.services..loadbalancer.passhostheader`" diff --git a/docs/content/routing/providers/docker.md b/docs/content/routing/providers/docker.md index ed39ba823..09738ec77 100644 --- a/docs/content/routing/providers/docker.md +++ b/docs/content/routing/providers/docker.md @@ -287,10 +287,11 @@ you'd add the label `traefik.http.services..loadbalancer.pa ??? info "`traefik.http.services..loadbalancer.serverstransport`" + Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. See [serverstransport](../services/index.md#serverstransport) for more information. - + ```yaml - - "traefik.http.services..loadbalancer.serverstransport=foobar" + - "traefik.http.services..loadbalancer.serverstransport=foobar@file" ``` ??? info "`traefik.http.services..loadbalancer.passhostheader`" diff --git a/docs/content/routing/providers/ecs.md b/docs/content/routing/providers/ecs.md index ff96309dc..78abd573e 100644 --- a/docs/content/routing/providers/ecs.md +++ b/docs/content/routing/providers/ecs.md @@ -135,10 +135,11 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa ??? info "`traefik.http.services..loadbalancer.serverstransport`" + Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. See [serverstransport](../services/index.md#serverstransport) for more information. ```yaml - traefik.http.services..loadbalancer.serverstransport=foobar + traefik.http.services..loadbalancer.serverstransport=foobar@file ``` ??? info "`traefik.http.services..loadbalancer.passhostheader`" diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index dcf795f27..d54175da1 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -292,15 +292,16 @@ The Kubernetes Ingress Controller, The Custom Resource Way. You can find an excerpt of the available custom resources in the table below: -| Kind | Purpose | Concept Behind | -|------------------------------------------|---------------------------------------------------------------|----------------------------------------------------------------| -| [IngressRoute](#kind-ingressroute) | HTTP Routing | [HTTP router](../routers/index.md#configuring-http-routers) | -| [Middleware](#kind-middleware) | Tweaks the HTTP requests before they are sent to your service | [HTTP Middlewares](../../middlewares/overview.md) | -| [TraefikService](#kind-traefikservice) | Abstraction for HTTP loadbalancing/mirroring | [HTTP service](../services/index.md#configuring-http-services) | -| [IngressRouteTCP](#kind-ingressroutetcp) | TCP Routing | [TCP router](../routers/index.md#configuring-tcp-routers) | -| [IngressRouteUDP](#kind-ingressrouteudp) | UDP Routing | [UDP router](../routers/index.md#configuring-udp-routers) | -| [TLSOptions](#kind-tlsoption) | Allows to configure some parameters of the TLS connection | [TLSOptions](../../https/tls.md#tls-options) | -| [TLSStores](#kind-tlsstore) | Allows to configure the default TLS store | [TLSStores](../../https/tls.md#certificates-stores) | +| Kind | Purpose | Concept Behind | +|--------------------------------------------|--------------------------------------------------------------------|----------------------------------------------------------------| +| [IngressRoute](#kind-ingressroute) | HTTP Routing | [HTTP router](../routers/index.md#configuring-http-routers) | +| [Middleware](#kind-middleware) | Tweaks the HTTP requests before they are sent to your service | [HTTP Middlewares](../../middlewares/overview.md) | +| [TraefikService](#kind-traefikservice) | Abstraction for HTTP loadbalancing/mirroring | [HTTP service](../services/index.md#configuring-http-services) | +| [IngressRouteTCP](#kind-ingressroutetcp) | TCP Routing | [TCP router](../routers/index.md#configuring-tcp-routers) | +| [IngressRouteUDP](#kind-ingressrouteudp) | UDP Routing | [UDP router](../routers/index.md#configuring-udp-routers) | +| [TLSOptions](#kind-tlsoption) | Allows to configure some parameters of the TLS connection | [TLSOptions](../../https/tls.md#tls-options) | +| [TLSStores](#kind-tlsstore) | Allows to configure the default TLS store | [TLSStores](../../https/tls.md#certificates-stores) | +| [ServersTransport](#kind-serverstransport) | Allows to configure the transport between Traefik and the backends | [ServersTransport](../../services/#serverstransport_1) | ### Kind: `IngressRoute` diff --git a/docs/content/routing/providers/kv.md b/docs/content/routing/providers/kv.md index 1e2b5fc7b..2276f04df 100644 --- a/docs/content/routing/providers/kv.md +++ b/docs/content/routing/providers/kv.md @@ -112,11 +112,12 @@ A Story of key & values ??? info "`traefik/http/services//loadbalancer/serverstransport`" + Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. See [serverstransport](../services/index.md#serverstransport) for more information. - | Key (Path) | Value | - |-----------------------------------------------------------------|----------| - | `traefik/http/services/myservice/loadbalancer/serverstransport` | `foobar` | + | Key (Path) | Value | + |-----------------------------------------------------------------|---------------| + | `traefik/http/services/myservice/loadbalancer/serverstransport` | `foobar@file` | ??? info "`traefik/http/services//loadbalancer/passhostheader`" diff --git a/docs/content/routing/providers/marathon.md b/docs/content/routing/providers/marathon.md index d762bfe72..ae25d5c9e 100644 --- a/docs/content/routing/providers/marathon.md +++ b/docs/content/routing/providers/marathon.md @@ -161,11 +161,12 @@ For example, to change the passHostHeader behavior, you'd add the label `"traefi ``` ??? info "`traefik.http.services..loadbalancer.serverstransport`" - + + Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. See [serverstransport](../services/index.md#serverstransport) for more information. ```json - "traefik.http.services..loadbalancer.serverstransport": "foobar" + "traefik.http.services..loadbalancer.serverstransport": "foobar@file" ``` ??? info "`traefik.http.services..loadbalancer.passhostheader`" diff --git a/docs/content/routing/providers/rancher.md b/docs/content/routing/providers/rancher.md index a045643b6..77506158a 100644 --- a/docs/content/routing/providers/rancher.md +++ b/docs/content/routing/providers/rancher.md @@ -168,10 +168,11 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa ??? info "`traefik.http.services..loadbalancer.serverstransport`" + Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. See [serverstransport](../services/index.md#serverstransport) for more information. ```yaml - - "traefik.http.services..loadbalancer.serverstransport=foobar" + - "traefik.http.services..loadbalancer.serverstransport=foobar@file" ``` ??? info "`traefik.http.services..loadbalancer.passhostheader`" From 2e7833df493790f887423cc306c54f8f24fba901 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Thu, 4 Mar 2021 09:02:03 +0100 Subject: [PATCH 09/16] chore: update linter. --- .golangci.toml | 75 ++++++++++++------- Makefile | 6 +- build.Dockerfile | 2 +- cmd/context.go | 6 +- cmd/traefik/traefik.go | 48 ++++++------ integration/grpc_test.go | 15 +++- integration/rest_test.go | 4 +- integration/try/try.go | 2 +- integration/websocket_test.go | 3 +- pkg/anonymize/anonymize.go | 2 +- pkg/cli/loader_file.go | 2 +- pkg/job/job_test.go | 18 ++++- pkg/metrics/prometheus.go | 2 +- pkg/middlewares/accesslog/logger_test.go | 4 +- pkg/middlewares/customerrors/custom_errors.go | 55 +++++++------- pkg/middlewares/tracing/mock_tracing_test.go | 4 +- pkg/provider/kubernetes/gateway/kubernetes.go | 35 ++++----- pkg/provider/kubernetes/ingress/client.go | 2 +- pkg/server/server_entrypoint_tcp.go | 4 +- .../service/loadbalancer/mirror/mirror.go | 4 +- pkg/server/service/loadbalancer/wrr/wrr.go | 26 +++---- 21 files changed, 179 insertions(+), 140 deletions(-) diff --git a/.golangci.toml b/.golangci.toml index 5486bc1ee..75fbff956 100644 --- a/.golangci.toml +++ b/.golangci.toml @@ -30,38 +30,64 @@ lines = 230 # default 60 statements = 120 # default 40 + [linters-settings.forbidigo] + forbid = [ + '^print(ln)?$', + '^spew\.Print(f|ln)?$', + '^spew\.Dump$', + ] + + [linters-settings.depguard] + list-type = "blacklist" + include-go-root = false + packages = ["github.com/pkg/errors"] + + [linters-settings.godox] + keywords = ["FIXME"] + + [linters-settings.importas] + corev1 = "k8s.io/api/core/v1" + networkingv1beta1 = "k8s.io/api/networking/v1beta1" + extensionsv1beta1 = "k8s.io/api/extensions/v1beta1" + metav1 = "k8s.io/apimachinery/pkg/apis/meta/v1" + kubeerror = "k8s.io/apimachinery/pkg/api/errors" + [linters] enable-all = true disable = [ + "scopelint", # Deprecated + "interfacer", # Deprecated + "maligned", # Deprecated + "sqlclosecheck", # Not relevant (SQL) + "rowserrcheck", # Not relevant (SQL) + "lll", # Not relevant "gocyclo", # FIXME must be fixed - "gosec", - "dupl", - "maligned", - "lll", - "unparam", - "prealloc", - "scopelint", + "cyclop", # Duplicate of gocyclo + "gocognit", # Too strict + "nestif", # Too many false-positive. + "prealloc", # Too many false-positive. + "makezero", # Not relevant + "ifshort", # Not relevant + "dupl", # Too strict + "gosec", # Too strict "gochecknoinits", "gochecknoglobals", - "godox", - "gocognit", - "bodyclose", # Too many false-positive and panics. "wsl", # Too strict + "nlreturn", # Not relevant "gomnd", # Too strict "stylecheck", # skip because report issues related to some generated files. "testpackage", # Too strict - "goerr113", # Too strict - "nestif", # Too many false-positive. - "noctx", # Too strict - "exhaustive", # Too strict - "nlreturn", # Not relevant - "wrapcheck", # Too strict "tparallel", # Not relevant "paralleltest", # Not relevant + "exhaustive", # Not relevant "exhaustivestruct", # Not relevant - "makezero", # not relevant - "forbidigo", # not relevant - "ifshort", # not relevant + "goerr113", # Too strict + "wrapcheck", # Too strict + "noctx", # Too strict + "bodyclose", # Too many false-positive and panics. + "unparam", # Too strict + "godox", # Too strict + "forcetypeassert", # Too strict ] [issues] @@ -69,9 +95,9 @@ max-per-linter = 0 max-same-issues = 0 exclude = [ - "SA1019: http.CloseNotifier is deprecated: the CloseNotifier interface predates Go's context package. New code should use Request.Context instead.", # FIXME must be fixed "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*printf?|os\\.(Un)?Setenv). is not checked", "should have a package comment, unless it's in another file for this package", + "SA1019: http.CloseNotifier has been deprecated", # FIXME must be fixed ] [[issues.exclude-rules]] path = "(.+)_test.go" @@ -88,18 +114,12 @@ [[issues.exclude-rules]] path = "pkg/h2c/h2c.go" text = "Error return value of `rw.Write` is not checked" - [[issues.exclude-rules]] - path = "pkg/middlewares/recovery/recovery.go" - text = "`logger` can be `github.com/stretchr/testify/assert.TestingT`" [[issues.exclude-rules]] path = "pkg/provider/docker/builder_test.go" text = "(U1000: func )?`(.+)` is unused" [[issues.exclude-rules]] path = "pkg/provider/kubernetes/builder_(endpoint|service)_test.go" text = "(U1000: func )?`(.+)` is unused" - [[issues.exclude-rules]] - path = "pkg/config/parser/.+_test.go" - text = "U1000: field `(foo|fuu)` is unused" [[issues.exclude-rules]] path = "pkg/server/service/bufferpool.go" text = "SA6002: argument should be pointer-like to avoid allocations" @@ -109,9 +129,6 @@ [[issues.exclude-rules]] path = "pkg/server/middleware/middlewares.go" text = "Function 'buildConstructor' has too many statements" - [[issues.exclude-rules]] # FIXME must be fixed - path = "cmd/context.go" - text = "S1000: should use a simple channel send/receive instead of `select` with a single case" [[issues.exclude-rules]] path = "pkg/tracing/haystack/logger.go" linters = ["goprintffuncname"] diff --git a/Makefile b/Makefile index 02fc7793d..2c60c2d03 100644 --- a/Makefile +++ b/Makefile @@ -63,18 +63,18 @@ generate-webui: build-webui-image mkdir -p static; \ docker run --rm -v "$$PWD/static":'/src/static' traefik-webui npm run build:nc; \ docker run --rm -v "$$PWD/static":'/src/static' traefik-webui chown -R $(shell id -u):$(shell id -g) ../static; \ - echo 'For more informations show `webui/readme.md`' > $$PWD/static/DONT-EDIT-FILES-IN-THIS-DIRECTORY.md; \ + echo 'For more information show `webui/readme.md`' > $$PWD/static/DONT-EDIT-FILES-IN-THIS-DIRECTORY.md; \ fi ## Build the linux binary binary: generate-webui $(PRE_TARGET) $(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate binary -## Build the binary for the standard plaforms (linux, darwin, windows) +## Build the binary for the standard platforms (linux, darwin, windows) crossbinary-default: generate-webui build-dev-image $(DOCKER_RUN_TRAEFIK_NOTTY) ./script/make.sh generate crossbinary-default -## Build the binary for the standard plaforms (linux, darwin, windows) in parallel +## Build the binary for the standard platforms (linux, darwin, windows) in parallel crossbinary-default-parallel: $(MAKE) generate-webui $(MAKE) build-dev-image crossbinary-default diff --git a/build.Dockerfile b/build.Dockerfile index 2ed4a1217..736447861 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -19,7 +19,7 @@ RUN mkdir -p /usr/local/bin \ && chmod +x /usr/local/bin/go-bindata # Download golangci-lint binary to bin folder in $GOPATH -RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.36.0 +RUN curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s -- -b $GOPATH/bin v1.38.0 # Download misspell binary to bin folder in $GOPATH RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4 diff --git a/cmd/context.go b/cmd/context.go index 35866fec2..867cb3f72 100644 --- a/cmd/context.go +++ b/cmd/context.go @@ -13,10 +13,8 @@ func ContextWithSignal(ctx context.Context) context.Context { signals := make(chan os.Signal) signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) go func() { - select { - case <-signals: - cancel() - } + <-signals + cancel() }() return newCtx } diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index 9ad068e4f..d4674b14d 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -366,30 +366,32 @@ func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.Pr var resolvers []*acme.Provider for name, resolver := range c.CertificatesResolvers { - if resolver.ACME != nil { - if localStores[resolver.ACME.Storage] == nil { - localStores[resolver.ACME.Storage] = acme.NewLocalStore(resolver.ACME.Storage) - } - - p := &acme.Provider{ - Configuration: resolver.ACME, - Store: localStores[resolver.ACME.Storage], - ResolverName: name, - HTTPChallengeProvider: httpChallengeProvider, - TLSChallengeProvider: tlsChallengeProvider, - } - - if err := providerAggregator.AddProvider(p); err != nil { - log.WithoutContext().Errorf("The ACME resolver %q is skipped from the resolvers list because: %v", name, err) - continue - } - - p.SetTLSManager(tlsManager) - - p.SetConfigListenerChan(make(chan dynamic.Configuration)) - - resolvers = append(resolvers, p) + if resolver.ACME == nil { + continue } + + if localStores[resolver.ACME.Storage] == nil { + localStores[resolver.ACME.Storage] = acme.NewLocalStore(resolver.ACME.Storage) + } + + p := &acme.Provider{ + Configuration: resolver.ACME, + Store: localStores[resolver.ACME.Storage], + ResolverName: name, + HTTPChallengeProvider: httpChallengeProvider, + TLSChallengeProvider: tlsChallengeProvider, + } + + if err := providerAggregator.AddProvider(p); err != nil { + log.WithoutContext().Errorf("The ACME resolver %q is skipped from the resolvers list because: %v", name, err) + continue + } + + p.SetTLSManager(tlsManager) + + p.SetConfigListenerChan(make(chan dynamic.Configuration)) + + resolvers = append(resolvers, p) } return resolvers diff --git a/integration/grpc_test.go b/integration/grpc_test.go index 256b977a7..51ede7b60 100644 --- a/integration/grpc_test.go +++ b/integration/grpc_test.go @@ -112,7 +112,7 @@ func callHelloClientGRPC(name string, secure bool) (string, error) { } else { client, closer, err = getHelloClientGRPCh2c() } - defer closer() + defer func() { _ = closer() }() if err != nil { return "", err @@ -139,6 +139,7 @@ func callStreamExampleClientGRPC() (helloworld.Greeter_StreamExampleClient, func func (s *GRPCSuite) TestGRPC(c *check.C) { lis, err := net.Listen("tcp", ":0") + c.Assert(err, check.IsNil) _, port, err := net.SplitHostPort(lis.Addr().String()) c.Assert(err, check.IsNil) @@ -181,6 +182,7 @@ func (s *GRPCSuite) TestGRPC(c *check.C) { func (s *GRPCSuite) TestGRPCh2c(c *check.C) { lis, err := net.Listen("tcp", ":0") + c.Assert(err, check.IsNil) _, port, err := net.SplitHostPort(lis.Addr().String()) c.Assert(err, check.IsNil) @@ -219,6 +221,7 @@ func (s *GRPCSuite) TestGRPCh2c(c *check.C) { func (s *GRPCSuite) TestGRPCh2cTermination(c *check.C) { lis, err := net.Listen("tcp", ":0") + c.Assert(err, check.IsNil) _, port, err := net.SplitHostPort(lis.Addr().String()) c.Assert(err, check.IsNil) @@ -261,6 +264,7 @@ func (s *GRPCSuite) TestGRPCh2cTermination(c *check.C) { func (s *GRPCSuite) TestGRPCInsecure(c *check.C) { lis, err := net.Listen("tcp", ":0") + c.Assert(err, check.IsNil) _, port, err := net.SplitHostPort(lis.Addr().String()) c.Assert(err, check.IsNil) @@ -340,7 +344,7 @@ func (s *GRPCSuite) TestGRPCBuffer(c *check.C) { c.Assert(err, check.IsNil) var client helloworld.Greeter_StreamExampleClient client, closer, err := callStreamExampleClientGRPC() - defer closer() + defer func() { _ = closer() }() c.Assert(err, check.IsNil) received := make(chan bool) @@ -400,8 +404,10 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) { var client helloworld.Greeter_StreamExampleClient client, closer, err := callStreamExampleClientGRPC() - defer closer() - defer func() { stopStreamExample <- true }() + defer func() { + _ = closer() + stopStreamExample <- true + }() c.Assert(err, check.IsNil) received := make(chan bool) @@ -425,6 +431,7 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) { func (s *GRPCSuite) TestGRPCWithRetry(c *check.C) { lis, err := net.Listen("tcp", ":0") + c.Assert(err, check.IsNil) _, port, err := net.SplitHostPort(lis.Addr().String()) c.Assert(err, check.IsNil) diff --git a/integration/rest_test.go b/integration/rest_test.go index 55ce57af9..53f804353 100644 --- a/integration/rest_test.go +++ b/integration/rest_test.go @@ -203,10 +203,10 @@ func (s *RestSuite) TestSimpleConfiguration(c *check.C) { } for _, test := range testCase { - json, err := json.Marshal(test.config) + data, err := json.Marshal(test.config) c.Assert(err, checker.IsNil) - request, err := http.NewRequest(http.MethodPut, "http://127.0.0.1:8000/secure/api/providers/rest", bytes.NewReader(json)) + request, err := http.NewRequest(http.MethodPut, "http://127.0.0.1:8000/secure/api/providers/rest", bytes.NewReader(data)) c.Assert(err, checker.IsNil) response, err := http.DefaultClient.Do(request) diff --git a/integration/try/try.go b/integration/try/try.go index d6ca95505..af54eb8f0 100644 --- a/integration/try/try.go +++ b/integration/try/try.go @@ -120,7 +120,7 @@ func Do(timeout time.Duration, operation DoCondition) error { fmt.Print("*") if err = operation(); err == nil { fmt.Println("+") - return err + return nil } } } diff --git a/integration/websocket_test.go b/integration/websocket_test.go index 9fec4a209..1b312fa72 100644 --- a/integration/websocket_test.go +++ b/integration/websocket_test.go @@ -461,8 +461,7 @@ func (s *WebsocketSuite) TestSSLhttp2(c *check.C) { })) ts.TLS = &tls.Config{} - ts.TLS.NextProtos = append(ts.TLS.NextProtos, `h2`) - ts.TLS.NextProtos = append(ts.TLS.NextProtos, `http/1.1`) + ts.TLS.NextProtos = append(ts.TLS.NextProtos, `h2`, `http/1.1`) ts.StartTLS() file := s.adaptFile(c, "fixtures/websocket/config_https.toml", struct { diff --git a/pkg/anonymize/anonymize.go b/pkg/anonymize/anonymize.go index 68b6289c7..4bbf61717 100644 --- a/pkg/anonymize/anonymize.go +++ b/pkg/anonymize/anonymize.go @@ -40,7 +40,7 @@ func Do(baseConfig interface{}, indent bool) (string, error) { } func doOnJSON(input string) string { - mailExp := regexp.MustCompile(`\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3}"`) + mailExp := regexp.MustCompile(`\w[-.\w]*\w@\w[-.\w]*\w\.\w{2,3}"`) return xurls.Relaxed().ReplaceAllString(mailExp.ReplaceAllString(input, maskLarge+"\""), maskLarge) } diff --git a/pkg/cli/loader_file.go b/pkg/cli/loader_file.go index da13fceb1..dd3624010 100644 --- a/pkg/cli/loader_file.go +++ b/pkg/cli/loader_file.go @@ -79,7 +79,7 @@ func loadConfigFiles(configFile string, element interface{}) (string, error) { return "", nil } - if err = file.Decode(filePath, element); err != nil { + if err := file.Decode(filePath, element); err != nil { return "", err } return filePath, nil diff --git a/pkg/job/job_test.go b/pkg/job/job_test.go index eaa3f8cf5..eb3cb09e0 100644 --- a/pkg/job/job_test.go +++ b/pkg/job/job_test.go @@ -24,9 +24,21 @@ func TestJobBackOff(t *testing.T) { exp.MinJobInterval = testMinJobInterval exp.Reset() - expectedResults := []time.Duration{500, 500, 500, 1000, 2000, 4000, 5000, 5000, 500, 1000, 2000, 4000, 5000, 5000} - for i, d := range expectedResults { - expectedResults[i] = d * time.Millisecond + expectedResults := []time.Duration{ + 500 * time.Millisecond, + 500 * time.Millisecond, + 500 * time.Millisecond, + 1 * time.Second, + 2 * time.Second, + 4 * time.Second, + 5 * time.Second, + 5 * time.Second, + 500 * time.Millisecond, + 1 * time.Second, + 2 * time.Second, + 4 * time.Second, + 5 * time.Second, + 5 * time.Second, } for i, expected := range expectedResults { diff --git a/pkg/metrics/prometheus.go b/pkg/metrics/prometheus.go index f936a0728..735f6ee29 100644 --- a/pkg/metrics/prometheus.go +++ b/pkg/metrics/prometheus.go @@ -390,7 +390,7 @@ func newCollector(metricName string, labels stdprometheus.Labels, c stdprometheu // collector wraps a Collector object from the Prometheus client library. // It adds information on how many generations this metric should be present -// in the /metrics output, relatived to the time it was last tracked. +// in the /metrics output, relative to the time it was last tracked. type collector struct { id string labels stdprometheus.Labels diff --git a/pkg/middlewares/accesslog/logger_test.go b/pkg/middlewares/accesslog/logger_test.go index aaa145e5b..c2449af94 100644 --- a/pkg/middlewares/accesslog/logger_test.go +++ b/pkg/middlewares/accesslog/logger_test.go @@ -711,10 +711,10 @@ func assertValidLogData(t *testing.T, expected string, logData []byte) { assert.Equal(t, resultExpected[OriginContentSize], result[OriginContentSize], formatErrMessage) assert.Equal(t, resultExpected[RequestRefererHeader], result[RequestRefererHeader], formatErrMessage) assert.Equal(t, resultExpected[RequestUserAgentHeader], result[RequestUserAgentHeader], formatErrMessage) - assert.Regexp(t, regexp.MustCompile("[0-9]*"), result[RequestCount], formatErrMessage) + assert.Regexp(t, regexp.MustCompile(`\d*`), result[RequestCount], formatErrMessage) assert.Equal(t, resultExpected[RouterName], result[RouterName], formatErrMessage) assert.Equal(t, resultExpected[ServiceURL], result[ServiceURL], formatErrMessage) - assert.Regexp(t, regexp.MustCompile("[0-9]*ms"), result[Duration], formatErrMessage) + assert.Regexp(t, regexp.MustCompile(`\d*ms`), result[Duration], formatErrMessage) } func captureStdout(t *testing.T) (out *os.File, restoreStdout func()) { diff --git a/pkg/middlewares/customerrors/custom_errors.go b/pkg/middlewares/customerrors/custom_errors.go index a43a4f028..0af6e6681 100644 --- a/pkg/middlewares/customerrors/custom_errors.go +++ b/pkg/middlewares/customerrors/custom_errors.go @@ -92,39 +92,42 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) { // check the recorder code against the configured http status code ranges code := catcher.getCode() for _, block := range c.httpCodeRanges { - if code >= block[0] && code <= block[1] { - logger.Debugf("Caught HTTP Status Code %d, returning error page", code) + if code < block[0] || code > block[1] { + continue + } - var query string - if len(c.backendQuery) > 0 { - query = "/" + strings.TrimPrefix(c.backendQuery, "/") - query = strings.ReplaceAll(query, "{status}", strconv.Itoa(code)) - } + logger.Debugf("Caught HTTP Status Code %d, returning error page", code) - pageReq, err := newRequest(backendURL + query) - if err != nil { - logger.Error(err) - rw.WriteHeader(code) - _, err = fmt.Fprint(rw, http.StatusText(code)) - if err != nil { - http.Error(rw, err.Error(), http.StatusInternalServerError) - } - return - } + var query string + if len(c.backendQuery) > 0 { + query = "/" + strings.TrimPrefix(c.backendQuery, "/") + query = strings.ReplaceAll(query, "{status}", strconv.Itoa(code)) + } - recorderErrorPage := newResponseRecorder(ctx, rw) - utils.CopyHeaders(pageReq.Header, req.Header) - - c.backendHandler.ServeHTTP(recorderErrorPage, pageReq.WithContext(req.Context())) - - utils.CopyHeaders(rw.Header(), recorderErrorPage.Header()) + pageReq, err := newRequest(backendURL + query) + if err != nil { + logger.Error(err) rw.WriteHeader(code) - - if _, err = rw.Write(recorderErrorPage.GetBody().Bytes()); err != nil { - logger.Error(err) + _, err = fmt.Fprint(rw, http.StatusText(code)) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) } return } + + recorderErrorPage := newResponseRecorder(ctx, rw) + utils.CopyHeaders(pageReq.Header, req.Header) + + c.backendHandler.ServeHTTP(recorderErrorPage, pageReq.WithContext(req.Context())) + + utils.CopyHeaders(rw.Header(), recorderErrorPage.Header()) + rw.WriteHeader(code) + + if _, err = rw.Write(recorderErrorPage.GetBody().Bytes()); err != nil { + logger.Error(err) + } + + return } } diff --git a/pkg/middlewares/tracing/mock_tracing_test.go b/pkg/middlewares/tracing/mock_tracing_test.go index af469ee52..ca5fcf4fa 100644 --- a/pkg/middlewares/tracing/mock_tracing_test.go +++ b/pkg/middlewares/tracing/mock_tracing_test.go @@ -27,12 +27,12 @@ func (n MockTracer) Extract(format, carrier interface{}) (opentracing.SpanContex return nil, opentracing.ErrSpanContextNotFound } -// MockSpanContext. +// MockSpanContext a span context mock. type MockSpanContext struct{} func (n MockSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {} -// MockSpan. +// MockSpan a span mock. type MockSpan struct { OpName string Tags map[string]interface{} diff --git a/pkg/provider/kubernetes/gateway/kubernetes.go b/pkg/provider/kubernetes/gateway/kubernetes.go index 50490cde7..b2649ca81 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes.go +++ b/pkg/provider/kubernetes/gateway/kubernetes.go @@ -541,23 +541,24 @@ func (p *Provider) makeGatewayStatus(listenerStatuses []v1alpha1.ListenerStatus) gatewayStatus.Listeners = listenerStatuses - // update "Scheduled" status with "ResourcesAvailable" reason - gatewayStatus.Conditions = append(gatewayStatus.Conditions, metav1.Condition{ - Type: string(v1alpha1.GatewayConditionScheduled), - Status: metav1.ConditionTrue, - Reason: "ResourcesAvailable", - Message: "Resources available", - LastTransitionTime: metav1.Now(), - }) - - // update "Ready" status with "ListenersValid" reason - gatewayStatus.Conditions = append(gatewayStatus.Conditions, metav1.Condition{ - Type: string(v1alpha1.GatewayConditionReady), - Status: metav1.ConditionTrue, - Reason: "ListenersValid", - Message: "Listeners valid", - LastTransitionTime: metav1.Now(), - }) + gatewayStatus.Conditions = append(gatewayStatus.Conditions, + // update "Scheduled" status with "ResourcesAvailable" reason + metav1.Condition{ + Type: string(v1alpha1.GatewayConditionScheduled), + Status: metav1.ConditionTrue, + Reason: "ResourcesAvailable", + Message: "Resources available", + LastTransitionTime: metav1.Now(), + }, + // update "Ready" status with "ListenersValid" reason + metav1.Condition{ + Type: string(v1alpha1.GatewayConditionReady), + Status: metav1.ConditionTrue, + Reason: "ListenersValid", + Message: "Listeners valid", + LastTransitionTime: metav1.Now(), + }, + ) return gatewayStatus, nil } diff --git a/pkg/provider/kubernetes/ingress/client.go b/pkg/provider/kubernetes/ingress/client.go index f05a85372..6c3c5bb77 100644 --- a/pkg/provider/kubernetes/ingress/client.go +++ b/pkg/provider/kubernetes/ingress/client.go @@ -341,7 +341,7 @@ func (c *clientWrapper) updateIngressStatusOld(src *networkingv1beta1.Ingress, i } // isLoadBalancerIngressEquals returns true if the given slices are equal, false otherwise. -func isLoadBalancerIngressEquals(aSlice []corev1.LoadBalancerIngress, bSlice []corev1.LoadBalancerIngress) bool { +func isLoadBalancerIngressEquals(aSlice, bSlice []corev1.LoadBalancerIngress) bool { if len(aSlice) != len(bSlice) { return false } diff --git a/pkg/server/server_entrypoint_tcp.go b/pkg/server/server_entrypoint_tcp.go index 1f001c9c8..38693fcc3 100644 --- a/pkg/server/server_entrypoint_tcp.go +++ b/pkg/server/server_entrypoint_tcp.go @@ -341,11 +341,11 @@ func (ln tcpKeepAliveListener) Accept() (net.Conn, error) { return nil, err } - if err = tc.SetKeepAlive(true); err != nil { + if err := tc.SetKeepAlive(true); err != nil { return nil, err } - if err = tc.SetKeepAlivePeriod(3 * time.Minute); err != nil { + if err := tc.SetKeepAlivePeriod(3 * time.Minute); err != nil { // Some systems, such as OpenBSD, have no user-settable per-socket TCP // keepalive options. if !errors.Is(err, syscall.ENOPROTOOPT) { diff --git a/pkg/server/service/loadbalancer/mirror/mirror.go b/pkg/server/service/loadbalancer/mirror/mirror.go index 00e2f06cb..d23979cf3 100644 --- a/pkg/server/service/loadbalancer/mirror/mirror.go +++ b/pkg/server/service/loadbalancer/mirror/mirror.go @@ -147,8 +147,8 @@ func (b blackHoleResponseWriter) Header() http.Header { return http.Header{} } -func (b blackHoleResponseWriter) Write(bytes []byte) (int, error) { - return len(bytes), nil +func (b blackHoleResponseWriter) Write(data []byte) (int, error) { + return len(data), nil } func (b blackHoleResponseWriter) WriteHeader(statusCode int) {} diff --git a/pkg/server/service/loadbalancer/wrr/wrr.go b/pkg/server/service/loadbalancer/wrr/wrr.go index 7558f6bca..bef0042f9 100644 --- a/pkg/server/service/loadbalancer/wrr/wrr.go +++ b/pkg/server/service/loadbalancer/wrr/wrr.go @@ -24,6 +24,19 @@ type stickyCookie struct { httpOnly bool } +// Balancer is a WeightedRoundRobin load balancer based on Earliest Deadline First (EDF). +// (https://en.wikipedia.org/wiki/Earliest_deadline_first_scheduling) +// Each pick from the schedule has the earliest deadline entry selected. +// Entries have deadlines set at currentDeadline + 1 / weight, +// providing weighted round robin behavior with floating point weights and an O(log n) pick time. +type Balancer struct { + stickyCookie *stickyCookie + + mutex sync.RWMutex + handlers []*namedHandler + curDeadline float64 +} + // New creates a new load balancer. func New(sticky *dynamic.Sticky) *Balancer { balancer := &Balancer{} @@ -68,19 +81,6 @@ func (b *Balancer) Pop() interface{} { return h } -// Balancer is a WeightedRoundRobin load balancer based on Earliest Deadline First (EDF). -// (https://en.wikipedia.org/wiki/Earliest_deadline_first_scheduling) -// Each pick from the schedule has the earliest deadline entry selected. -// Entries have deadlines set at currentDeadline + 1 / weight, -// providing weighted round robin behavior with floating point weights and an O(log n) pick time. -type Balancer struct { - stickyCookie *stickyCookie - - mutex sync.RWMutex - handlers []*namedHandler - curDeadline float64 -} - func (b *Balancer) nextServer() (*namedHandler, error) { b.mutex.Lock() defer b.mutex.Unlock() From bdba7d3adfd404ea5de8fab5ab875470521108da Mon Sep 17 00:00:00 2001 From: Romain Date: Thu, 4 Mar 2021 20:08:03 +0100 Subject: [PATCH 10/16] Update to go1.16 --- build.Dockerfile | 2 +- docs/content/contributing/building-testing.md | 4 +- exp.Dockerfile | 2 +- go.mod | 5 +- go.sum | 9 +- integration/access_log_test.go | 11 +- integration/acme_test.go | 3 +- integration/consul_test.go | 5 +- integration/docker_test.go | 8 +- integration/etcd_test.go | 5 +- integration/grpc_test.go | 5 +- integration/integration_test.go | 5 +- integration/k8s_test.go | 7 +- integration/log_rotation_test.go | 5 +- integration/redis_test.go | 5 +- integration/simple_test.go | 10 +- integration/tls_client_headers_test.go | 7 +- integration/try/condition.go | 10 +- integration/websocket_test.go | 5 +- integration/zk_test.go | 5 +- pkg/anonymize/anonymize_config_test.go | 9 +- pkg/anonymize/anonymize_doOnJSON_test.go | 6 +- pkg/api/handler_entrypoint_test.go | 9 +- pkg/api/handler_http_test.go | 9 +- pkg/api/handler_overview_test.go | 9 +- pkg/api/handler_tcp_test.go | 9 +- pkg/api/handler_test.go | 11 +- pkg/api/handler_udp_test.go | 9 +- pkg/cli/loader_file.go | 3 +- pkg/config/dynamic/middlewares.go | 3 +- pkg/metrics/influxdb_test.go | 4 +- pkg/middlewares/accesslog/logger_test.go | 46 ++------ pkg/middlewares/auth/auth.go | 4 +- pkg/middlewares/auth/basic_auth_test.go | 17 ++- pkg/middlewares/auth/digest_auth_test.go | 9 +- pkg/middlewares/auth/forward.go | 4 +- pkg/middlewares/auth/forward_test.go | 13 +-- pkg/middlewares/compress/compress_test.go | 6 +- pkg/middlewares/retry/retry.go | 6 +- pkg/middlewares/retry/retry_test.go | 107 ++++++------------ pkg/pilot/pilot.go | 6 +- pkg/plugins/client.go | 7 +- pkg/provider/acme/local_store.go | 6 +- pkg/provider/acme/local_store_test.go | 6 +- pkg/provider/file/file.go | 5 +- pkg/provider/file/file_test.go | 23 +--- pkg/provider/http/http.go | 4 +- pkg/provider/kubernetes/crd/client.go | 3 +- .../kubernetes/crd/client_mock_test.go | 4 +- .../kubernetes/crd/kubernetes_test.go | 4 +- pkg/provider/kubernetes/gateway/client.go | 4 +- .../kubernetes/gateway/client_mock_test.go | 4 +- pkg/provider/kubernetes/ingress/client.go | 3 +- .../kubernetes/ingress/client_mock_test.go | 4 +- pkg/provider/traefik/internal_test.go | 6 +- pkg/server/router/router_test.go | 6 +- pkg/server/server_entrypoint_tcp_test.go | 2 +- .../service/loadbalancer/mirror/mirror.go | 7 +- .../loadbalancer/mirror/mirror_test.go | 10 +- pkg/server/service/proxy_test.go | 4 +- pkg/tls/certificate.go | 3 +- pkg/types/tls.go | 3 +- 62 files changed, 217 insertions(+), 318 deletions(-) diff --git a/build.Dockerfile b/build.Dockerfile index 736447861..44880272a 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.15-alpine +FROM golang:1.16-alpine RUN apk --update upgrade \ && apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \ diff --git a/docs/content/contributing/building-testing.md b/docs/content/contributing/building-testing.md index 665852872..f2e7eea57 100644 --- a/docs/content/contributing/building-testing.md +++ b/docs/content/contributing/building-testing.md @@ -30,7 +30,7 @@ Successfully tagged traefik-webui:latest [...] docker build -t "traefik-dev:4475--feature-documentation" -f build.Dockerfile . Sending build context to Docker daemon 279MB -Step 1/10 : FROM golang:1.14-alpine +Step 1/10 : FROM golang:1.16-alpine ---> f4bfb3d22bda [...] Successfully built 5c3c1a911277 @@ -62,7 +62,7 @@ PRE_TARGET= make test-unit Requirements: -- `go` v1.14+ +- `go` v1.16+ - environment variable `GO111MODULE=on` - [go-bindata](https://github.com/containous/go-bindata) `GO111MODULE=off go get -u github.com/containous/go-bindata/...` diff --git a/exp.Dockerfile b/exp.Dockerfile index b63b6f67b..318f8c95f 100644 --- a/exp.Dockerfile +++ b/exp.Dockerfile @@ -12,7 +12,7 @@ RUN npm install RUN npm run build # BUILD -FROM golang:1.15-alpine as gobuild +FROM golang:1.16-alpine as gobuild RUN apk --update upgrade \ && apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \ diff --git a/go.mod b/go.mod index 94e41ea43..a5fd2b11a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/traefik/traefik/v2 -go 1.15 +go 1.16 require ( github.com/BurntSushi/toml v0.3.1 @@ -78,7 +78,7 @@ require ( github.com/unrolled/render v1.0.2 github.com/unrolled/secure v1.0.7 github.com/vdemeester/shakers v0.1.0 - github.com/vulcand/oxy v1.1.0 + github.com/vulcand/oxy v1.2.0 github.com/vulcand/predicate v1.1.0 go.elastic.co/apm v1.7.0 go.elastic.co/apm/module/apmot v1.7.0 @@ -88,7 +88,6 @@ require ( google.golang.org/grpc v1.27.1 gopkg.in/DataDog/dd-trace-go.v1 v1.19.0 gopkg.in/fsnotify.v1 v1.4.7 - gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 k8s.io/api v0.19.2 k8s.io/apimachinery v0.19.2 diff --git a/go.sum b/go.sum index 2b1ff801f..516778472 100644 --- a/go.sum +++ b/go.sum @@ -98,7 +98,6 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/sarama v1.23.1 h1:XxJBCZEoWJtoWjf/xRbmGUpAmTZGnuuF0ON0EvxxBrs= github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs= -github.com/Shopify/toxiproxy v2.1.4+incompatible h1:TKdv8HiTLgE5wdJuEML90aBgNWsokNbMijUGhmcoBJc= 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= @@ -664,7 +663,6 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/nrdcg/auroradns v1.0.1 h1:m/kBq83Xvy3cU261MOknd8BdnOk12q4lAWM+kOdsC2Y= github.com/nrdcg/auroradns v1.0.1/go.mod h1:y4pc0i9QXYlFCWrhWrUSIETnZgrf4KuwjDIWmmXo3JI= @@ -895,8 +893,8 @@ github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/vdemeester/shakers v0.1.0 h1:K+n9sSyUCg2ywmZkv+3c7vsYZfivcfKhMh8kRxCrONM= github.com/vdemeester/shakers v0.1.0/go.mod h1:IZ1HHynUOQt32iQ3rvAeVddXLd19h/6LWiKsh9RZtAQ= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= -github.com/vulcand/oxy v1.1.0 h1:DbBijGo1+6cFqR9jarkMxasdj0lgWwrrFtue6ijek4Q= -github.com/vulcand/oxy v1.1.0/go.mod h1:ADiMYHi8gkGl2987yQIzDRoXZilANF4WtKaQ92OppKY= +github.com/vulcand/oxy v1.2.0 h1:Y2Wt1EgQddA/qMnp1+YXjehPsyw2Gy8CAfavkFF+fQk= +github.com/vulcand/oxy v1.2.0/go.mod h1:nGeNTWfyYQj3ghi3W8ok7vLSkw7Gkvr0x+G/v8Wk7vM= github.com/vulcand/predicate v1.1.0 h1:Gq/uWopa4rx/tnZu2opOSBqHK63Yqlou/SzrbwdJiNg= github.com/vulcand/predicate v1.1.0/go.mod h1:mlccC5IRBoc2cIFmCB8ZM62I3VDb6p2GXESMHa3CnZg= github.com/vultr/govultr/v2 v2.0.0 h1:+lAtqfWy3g9VwL7tT2Fpyad8Vv4MxOhT/NU8O5dk+EQ= @@ -925,7 +923,6 @@ go.elastic.co/fastjson v1.0.0 h1:ooXV/ABvf+tBul26jcVViPT3sBir0PvXgibYB1IQQzg= go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= go.etcd.io/bbolt v1.3.1-etcd.8/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd v3.3.13+incompatible h1:jCejD5EMnlGxFvcGRyEV4VGlENZc7oPQX6o0t7n3xbw= @@ -1271,8 +1268,6 @@ gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hr gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= -gopkg.in/jcmturner/goidentity.v3 v3.0.0 h1:1duIyWiTaYvVx3YX2CYtpJbUFd7/UuPYCfgXtQ3VTbI= -gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= gopkg.in/jcmturner/gokrb5.v7 v7.2.3 h1:hHMV/yKPwMnJhPuPx7pH2Uw/3Qyf+thJYlisUc44010= gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU= diff --git a/integration/access_log_test.go b/integration/access_log_test.go index 74d8200e1..59f23eccb 100644 --- a/integration/access_log_test.go +++ b/integration/access_log_test.go @@ -5,7 +5,6 @@ import ( "crypto/rand" "fmt" "io" - "io/ioutil" "net/http" "os" "strconv" @@ -58,7 +57,7 @@ func (s *AccessLogSuite) TestAccessLog(c *check.C) { defer display(c) defer func() { - traefikLog, err := ioutil.ReadFile(traefikTestLogFile) + traefikLog, err := os.ReadFile(traefikTestLogFile) c.Assert(err, checker.IsNil) log.WithoutContext().Info(string(traefikLog)) }() @@ -545,7 +544,7 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontendSuccess(c *check.C) { } func checkNoOtherTraefikProblems(c *check.C) { - traefikLog, err := ioutil.ReadFile(traefikTestLogFile) + traefikLog, err := os.ReadFile(traefikTestLogFile) c.Assert(err, checker.IsNil) if len(traefikLog) > 0 { fmt.Printf("%s\n", string(traefikLog)) @@ -583,7 +582,7 @@ func checkAccessLogExactValuesOutput(c *check.C, values []accessLogValue) int { } func extractLines(c *check.C) []string { - accessLog, err := ioutil.ReadFile(traefikTestAccessLogFile) + accessLog, err := os.ReadFile(traefikTestAccessLogFile) c.Assert(err, checker.IsNil) lines := strings.Split(string(accessLog), "\n") @@ -613,7 +612,7 @@ func ensureWorkingDirectoryIsClean() { } func checkTraefikStarted(c *check.C) []byte { - traefikLog, err := ioutil.ReadFile(traefikTestLogFile) + traefikLog, err := os.ReadFile(traefikTestLogFile) c.Assert(err, checker.IsNil) if len(traefikLog) > 0 { fmt.Printf("%s\n", string(traefikLog)) @@ -663,7 +662,7 @@ func waitForTraefik(c *check.C, containerName string) { func displayTraefikLogFile(c *check.C, path string) { if c.Failed() { if _, err := os.Stat(path); !os.IsNotExist(err) { - content, errRead := ioutil.ReadFile(path) + content, errRead := os.ReadFile(path) fmt.Printf("%s: Traefik logs: \n", c.TestName()) if errRead == nil { fmt.Println(content) diff --git a/integration/acme_test.go b/integration/acme_test.go index a67eb96e2..503f03c6c 100644 --- a/integration/acme_test.go +++ b/integration/acme_test.go @@ -4,7 +4,6 @@ import ( "crypto/tls" "crypto/x509" "fmt" - "io/ioutil" "net/http" "os" "path/filepath" @@ -67,7 +66,7 @@ func setupPebbleRootCA() (*http.Transport, error) { os.Setenv("LEGO_CA_CERTIFICATES", path) os.Setenv("LEGO_CA_SERVER_NAME", "pebble") - customCAs, err := ioutil.ReadFile(path) + customCAs, err := os.ReadFile(path) if err != nil { return nil, err } diff --git a/integration/consul_test.go b/integration/consul_test.go index 07ade5d17..330069a39 100644 --- a/integration/consul_test.go +++ b/integration/consul_test.go @@ -3,7 +3,6 @@ package integration import ( "bytes" "encoding/json" - "io/ioutil" "net/http" "os" "path/filepath" @@ -138,11 +137,11 @@ func (s *ConsulSuite) TestSimpleConfiguration(c *check.C) { expectedJSON := filepath.FromSlash("testdata/rawdata-consul.json") if *updateExpected { - err = ioutil.WriteFile(expectedJSON, got, 0o666) + err = os.WriteFile(expectedJSON, got, 0o666) c.Assert(err, checker.IsNil) } - expected, err := ioutil.ReadFile(expectedJSON) + expected, err := os.ReadFile(expectedJSON) c.Assert(err, checker.IsNil) if !bytes.Equal(expected, got) { diff --git a/integration/docker_test.go b/integration/docker_test.go index e379d4f6b..bff89ad9e 100644 --- a/integration/docker_test.go +++ b/integration/docker_test.go @@ -3,7 +3,7 @@ package integration import ( "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "os" "strings" @@ -135,7 +135,7 @@ func (s *DockerSuite) TestDefaultDockerContainers(c *check.C) { resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK) c.Assert(err, checker.IsNil) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) c.Assert(err, checker.IsNil) var version map[string]interface{} @@ -228,7 +228,7 @@ func (s *DockerSuite) TestDockerContainersWithLabels(c *check.C) { resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK) c.Assert(err, checker.IsNil) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) c.Assert(err, checker.IsNil) var version map[string]interface{} @@ -307,7 +307,7 @@ func (s *DockerSuite) TestRestartDockerContainers(c *check.C) { resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK) c.Assert(err, checker.IsNil) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) c.Assert(err, checker.IsNil) var version map[string]interface{} diff --git a/integration/etcd_test.go b/integration/etcd_test.go index a4ca83262..ff8f8cc16 100644 --- a/integration/etcd_test.go +++ b/integration/etcd_test.go @@ -3,7 +3,6 @@ package integration import ( "bytes" "encoding/json" - "io/ioutil" "net/http" "os" "path/filepath" @@ -138,11 +137,11 @@ func (s *EtcdSuite) TestSimpleConfiguration(c *check.C) { expectedJSON := filepath.FromSlash("testdata/rawdata-etcd.json") if *updateExpected { - err = ioutil.WriteFile(expectedJSON, got, 0o666) + err = os.WriteFile(expectedJSON, got, 0o666) c.Assert(err, checker.IsNil) } - expected, err := ioutil.ReadFile(expectedJSON) + expected, err := os.ReadFile(expectedJSON) c.Assert(err, checker.IsNil) if !bytes.Equal(expected, got) { diff --git a/integration/grpc_test.go b/integration/grpc_test.go index 51ede7b60..496f4b371 100644 --- a/integration/grpc_test.go +++ b/integration/grpc_test.go @@ -5,7 +5,6 @@ import ( "crypto/tls" "crypto/x509" "errors" - "io/ioutil" "math/rand" "net" "os" @@ -35,9 +34,9 @@ type myserver struct { func (s *GRPCSuite) SetUpSuite(c *check.C) { var err error - LocalhostCert, err = ioutil.ReadFile("./resources/tls/local.cert") + LocalhostCert, err = os.ReadFile("./resources/tls/local.cert") c.Assert(err, check.IsNil) - LocalhostKey, err = ioutil.ReadFile("./resources/tls/local.key") + LocalhostKey, err = os.ReadFile("./resources/tls/local.key") c.Assert(err, check.IsNil) } diff --git a/integration/integration_test.go b/integration/integration_test.go index 020ea3c53..1cd438d9b 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -5,7 +5,6 @@ import ( "bytes" "flag" "fmt" - "io/ioutil" "net" "os" "os/exec" @@ -143,7 +142,7 @@ func (s *BaseSuite) traefikCmd(args ...string) (*exec.Cmd, func(*check.C)) { func (s *BaseSuite) displayLogK3S(c *check.C) { filePath := "./fixtures/k8s/config.skip/k3s.log" if _, err := os.Stat(filePath); err == nil { - content, errR := ioutil.ReadFile(filePath) + content, errR := os.ReadFile(filePath) if errR != nil { log.WithoutContext().Error(errR) } @@ -178,7 +177,7 @@ func (s *BaseSuite) adaptFile(c *check.C, path string, tempObjects interface{}) c.Assert(err, checker.IsNil) folder, prefix := filepath.Split(path) - tmpFile, err := ioutil.TempFile(folder, strings.TrimSuffix(prefix, filepath.Ext(prefix))+"_*"+filepath.Ext(prefix)) + tmpFile, err := os.CreateTemp(folder, strings.TrimSuffix(prefix, filepath.Ext(prefix))+"_*"+filepath.Ext(prefix)) c.Assert(err, checker.IsNil) defer tmpFile.Close() diff --git a/integration/k8s_test.go b/integration/k8s_test.go index b5f2b2093..392c327cf 100644 --- a/integration/k8s_test.go +++ b/integration/k8s_test.go @@ -7,7 +7,6 @@ import ( "flag" "fmt" "io" - "io/ioutil" "net/http" "os" "path/filepath" @@ -153,14 +152,14 @@ func testConfiguration(c *check.C, path, apiPort string) { newJSON, err := json.MarshalIndent(rtRepr, "", "\t") c.Assert(err, checker.IsNil) - err = ioutil.WriteFile(expectedJSON, newJSON, 0o644) + err = os.WriteFile(expectedJSON, newJSON, 0o644) c.Assert(err, checker.IsNil) c.Errorf("We do not want a passing test in file update mode") } func matchesConfig(wantConfig string, buf *bytes.Buffer) try.ResponseCondition { return func(res *http.Response) error { - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return fmt.Errorf("failed to read response body: %w", err) } @@ -187,7 +186,7 @@ func matchesConfig(wantConfig string, buf *bytes.Buffer) try.ResponseCondition { return err } - expected, err := ioutil.ReadFile(wantConfig) + expected, err := os.ReadFile(wantConfig) if err != nil { return err } diff --git a/integration/log_rotation_test.go b/integration/log_rotation_test.go index d91bf04b4..2fe27d78b 100644 --- a/integration/log_rotation_test.go +++ b/integration/log_rotation_test.go @@ -4,7 +4,6 @@ package integration import ( "bufio" - "io/ioutil" "net/http" "os" "strings" @@ -130,14 +129,14 @@ func (s *LogRotationSuite) TestTraefikLogRotation(c *check.C) { } func logAccessLogFile(c *check.C, fileName string) { - output, err := ioutil.ReadFile(fileName) + output, err := os.ReadFile(fileName) c.Assert(err, checker.IsNil) c.Logf("Contents of file %s\n%s", fileName, string(output)) } func verifyEmptyErrorLog(c *check.C, name string) { err := try.Do(5*time.Second, func() error { - traefikLog, e2 := ioutil.ReadFile(name) + traefikLog, e2 := os.ReadFile(name) if e2 != nil { return e2 } diff --git a/integration/redis_test.go b/integration/redis_test.go index f601ca35a..eb31d5533 100644 --- a/integration/redis_test.go +++ b/integration/redis_test.go @@ -3,7 +3,6 @@ package integration import ( "bytes" "encoding/json" - "io/ioutil" "net/http" "os" "path/filepath" @@ -138,11 +137,11 @@ func (s *RedisSuite) TestSimpleConfiguration(c *check.C) { expectedJSON := filepath.FromSlash("testdata/rawdata-redis.json") if *updateExpected { - err = ioutil.WriteFile(expectedJSON, got, 0o666) + err = os.WriteFile(expectedJSON, got, 0o666) c.Assert(err, checker.IsNil) } - expected, err := ioutil.ReadFile(expectedJSON) + expected, err := os.ReadFile(expectedJSON) c.Assert(err, checker.IsNil) if !bytes.Equal(expected, got) { diff --git a/integration/simple_test.go b/integration/simple_test.go index d5cbc09a9..17519d0d5 100644 --- a/integration/simple_test.go +++ b/integration/simple_test.go @@ -5,7 +5,7 @@ import ( "crypto/rand" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "os" @@ -688,7 +688,7 @@ func (s *SimpleSuite) TestWRR(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(response.StatusCode, checker.Equals, http.StatusOK) - body, err := ioutil.ReadAll(response.Body) + body, err := io.ReadAll(response.Body) c.Assert(err, checker.IsNil) if strings.Contains(string(body), server1) { @@ -739,7 +739,7 @@ func (s *SimpleSuite) TestWRRSticky(c *check.C) { req.AddCookie(cookie) } - body, err := ioutil.ReadAll(response.Body) + body, err := io.ReadAll(response.Body) c.Assert(err, checker.IsNil) if strings.Contains(string(body), server1) { @@ -819,7 +819,7 @@ func (s *SimpleSuite) TestMirrorWithBody(c *check.C) { c.Assert(err, checker.IsNil) verifyBody := func(req *http.Request) { - b, _ := ioutil.ReadAll(req.Body) + b, _ := io.ReadAll(req.Body) switch req.Header.Get("Size") { case "20": if !bytes.Equal(b, body20) { @@ -1030,7 +1030,7 @@ func (s *SimpleSuite) TestContentTypeDisableAutoDetect(c *check.C) { rw.WriteHeader(http.StatusOK) - data, err := ioutil.ReadFile("fixtures/test.pdf") + data, err := os.ReadFile("fixtures/test.pdf") c.Assert(err, checker.IsNil) _, err = rw.Write(data) diff --git a/integration/tls_client_headers_test.go b/integration/tls_client_headers_test.go index f55d2ff99..9d2de014c 100644 --- a/integration/tls_client_headers_test.go +++ b/integration/tls_client_headers_test.go @@ -2,7 +2,6 @@ package integration import ( "crypto/tls" - "io/ioutil" "net/http" "os" "time" @@ -26,11 +25,11 @@ func (s *TLSClientHeadersSuite) SetUpSuite(c *check.C) { } func (s *TLSClientHeadersSuite) TestTLSClientHeaders(c *check.C) { - rootCertContent, err := ioutil.ReadFile(rootCertPath) + rootCertContent, err := os.ReadFile(rootCertPath) c.Assert(err, check.IsNil) - serverCertContent, err := ioutil.ReadFile(certPemPath) + serverCertContent, err := os.ReadFile(certPemPath) c.Assert(err, check.IsNil) - ServerKeyContent, err := ioutil.ReadFile(certKeyPath) + ServerKeyContent, err := os.ReadFile(certKeyPath) c.Assert(err, check.IsNil) file := s.adaptFile(c, "fixtures/tlsclientheaders/simple.toml", struct { diff --git a/integration/try/condition.go b/integration/try/condition.go index a2619a28b..c10d20a9a 100644 --- a/integration/try/condition.go +++ b/integration/try/condition.go @@ -3,7 +3,7 @@ package try import ( "errors" "fmt" - "io/ioutil" + "io" "net/http" "reflect" "strings" @@ -19,7 +19,7 @@ type ResponseCondition func(*http.Response) error // The condition returns an error if the request body does not contain all the given strings. func BodyContains(values ...string) ResponseCondition { return func(res *http.Response) error { - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return fmt.Errorf("failed to read response body: %w", err) } @@ -37,7 +37,7 @@ func BodyContains(values ...string) ResponseCondition { // The condition returns an error if the request body contain one of the given strings. func BodyNotContains(values ...string) ResponseCondition { return func(res *http.Response) error { - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return fmt.Errorf("failed to read response body: %w", err) } @@ -55,7 +55,7 @@ func BodyNotContains(values ...string) ResponseCondition { // The condition returns an error if the request body does not contain one of the given strings. func BodyContainsOr(values ...string) ResponseCondition { return func(res *http.Response) error { - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return fmt.Errorf("failed to read response body: %w", err) } @@ -73,7 +73,7 @@ func BodyContainsOr(values ...string) ResponseCondition { // The condition returns an error if the request body does not have body content. func HasBody() ResponseCondition { return func(res *http.Response) error { - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) if err != nil { return fmt.Errorf("failed to read response body: %w", err) } diff --git a/integration/websocket_test.go b/integration/websocket_test.go index 1b312fa72..819da7cc1 100644 --- a/integration/websocket_test.go +++ b/integration/websocket_test.go @@ -4,7 +4,6 @@ import ( "crypto/tls" "crypto/x509" "encoding/base64" - "io/ioutil" "net" "net/http" "net/http/httptest" @@ -279,7 +278,7 @@ func (s *WebsocketSuite) TestSSLTermination(c *check.C) { // Add client self-signed cert roots := x509.NewCertPool() - certContent, err := ioutil.ReadFile("./resources/tls/local.cert") + certContent, err := os.ReadFile("./resources/tls/local.cert") c.Assert(err, checker.IsNil) roots.AppendCertsFromPEM(certContent) gorillawebsocket.DefaultDialer.TLSClientConfig = &tls.Config{ @@ -484,7 +483,7 @@ func (s *WebsocketSuite) TestSSLhttp2(c *check.C) { // Add client self-signed cert roots := x509.NewCertPool() - certContent, err := ioutil.ReadFile("./resources/tls/local.cert") + certContent, err := os.ReadFile("./resources/tls/local.cert") c.Assert(err, checker.IsNil) roots.AppendCertsFromPEM(certContent) gorillawebsocket.DefaultDialer.TLSClientConfig = &tls.Config{ diff --git a/integration/zk_test.go b/integration/zk_test.go index 5ab71151f..61154779d 100644 --- a/integration/zk_test.go +++ b/integration/zk_test.go @@ -3,7 +3,6 @@ package integration import ( "bytes" "encoding/json" - "io/ioutil" "net/http" "os" "path/filepath" @@ -138,11 +137,11 @@ func (s *ZookeeperSuite) TestSimpleConfiguration(c *check.C) { expectedJSON := filepath.FromSlash("testdata/rawdata-zk.json") if *updateExpected { - err = ioutil.WriteFile(expectedJSON, got, 0o666) + err = os.WriteFile(expectedJSON, got, 0o666) c.Assert(err, checker.IsNil) } - expected, err := ioutil.ReadFile(expectedJSON) + expected, err := os.ReadFile(expectedJSON) c.Assert(err, checker.IsNil) if !bytes.Equal(expected, got) { diff --git a/pkg/anonymize/anonymize_config_test.go b/pkg/anonymize/anonymize_config_test.go index 4c3b67d4c..b769b78c2 100644 --- a/pkg/anonymize/anonymize_config_test.go +++ b/pkg/anonymize/anonymize_config_test.go @@ -2,7 +2,6 @@ package anonymize import ( "flag" - "io/ioutil" "os" "strings" "testing" @@ -462,14 +461,14 @@ func TestDo_dynamicConfiguration(t *testing.T) { }, } - expectedConfiguration, err := ioutil.ReadFile("./testdata/anonymized-dynamic-config.json") + expectedConfiguration, err := os.ReadFile("./testdata/anonymized-dynamic-config.json") require.NoError(t, err) cleanJSON, err := Do(config, true) require.NoError(t, err) if *updateExpected { - require.NoError(t, ioutil.WriteFile("testdata/anonymized-dynamic-config.json", []byte(cleanJSON), 0666)) + require.NoError(t, os.WriteFile("testdata/anonymized-dynamic-config.json", []byte(cleanJSON), 0666)) } expected := strings.TrimSuffix(string(expectedConfiguration), "\n") @@ -965,14 +964,14 @@ func TestDo_staticConfiguration(t *testing.T) { }, } - expectedConfiguration, err := ioutil.ReadFile("./testdata/anonymized-static-config.json") + expectedConfiguration, err := os.ReadFile("./testdata/anonymized-static-config.json") require.NoError(t, err) cleanJSON, err := Do(config, true) require.NoError(t, err) if *updateExpected { - require.NoError(t, ioutil.WriteFile("testdata/anonymized-static-config.json", []byte(cleanJSON), 0666)) + require.NoError(t, os.WriteFile("testdata/anonymized-static-config.json", []byte(cleanJSON), 0666)) } expected := strings.TrimSuffix(string(expectedConfiguration), "\n") diff --git a/pkg/anonymize/anonymize_doOnJSON_test.go b/pkg/anonymize/anonymize_doOnJSON_test.go index 1ff7b9d4b..85248954b 100644 --- a/pkg/anonymize/anonymize_doOnJSON_test.go +++ b/pkg/anonymize/anonymize_doOnJSON_test.go @@ -1,7 +1,7 @@ package anonymize import ( - "io/ioutil" + "os" "testing" "github.com/stretchr/testify/assert" @@ -9,12 +9,12 @@ import ( ) func Test_doOnJSON(t *testing.T) { - baseConfiguration, err := ioutil.ReadFile("./testdata/example.json") + baseConfiguration, err := os.ReadFile("./testdata/example.json") require.NoError(t, err) anomConfiguration := doOnJSON(string(baseConfiguration)) - expectedConfiguration, err := ioutil.ReadFile("./testdata/expected.json") + expectedConfiguration, err := os.ReadFile("./testdata/expected.json") require.NoError(t, err) assert.JSONEq(t, string(expectedConfiguration), anomConfiguration) diff --git a/pkg/api/handler_entrypoint_test.go b/pkg/api/handler_entrypoint_test.go index 5a2a134aa..a3c31e583 100644 --- a/pkg/api/handler_entrypoint_test.go +++ b/pkg/api/handler_entrypoint_test.go @@ -3,9 +3,10 @@ package api import ( "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" + "os" "strconv" "testing" @@ -212,7 +213,7 @@ func TestHandler_EntryPoints(t *testing.T) { } assert.Equal(t, resp.Header.Get("Content-Type"), "application/json") - contents, err := ioutil.ReadAll(resp.Body) + contents, err := io.ReadAll(resp.Body) require.NoError(t, err) err = resp.Body.Close() @@ -226,11 +227,11 @@ func TestHandler_EntryPoints(t *testing.T) { newJSON, err := json.MarshalIndent(results, "", "\t") require.NoError(t, err) - err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0o644) + err = os.WriteFile(test.expected.jsonFile, newJSON, 0o644) require.NoError(t, err) } - data, err := ioutil.ReadFile(test.expected.jsonFile) + data, err := os.ReadFile(test.expected.jsonFile) require.NoError(t, err) assert.JSONEq(t, string(data), string(contents)) }) diff --git a/pkg/api/handler_http_test.go b/pkg/api/handler_http_test.go index 93adb0b23..e3698fa4c 100644 --- a/pkg/api/handler_http_test.go +++ b/pkg/api/handler_http_test.go @@ -4,9 +4,10 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" + "os" "strconv" "testing" @@ -826,7 +827,7 @@ func TestHandler_HTTP(t *testing.T) { } assert.Equal(t, resp.Header.Get("Content-Type"), "application/json") - contents, err := ioutil.ReadAll(resp.Body) + contents, err := io.ReadAll(resp.Body) require.NoError(t, err) err = resp.Body.Close() @@ -840,11 +841,11 @@ func TestHandler_HTTP(t *testing.T) { newJSON, err := json.MarshalIndent(results, "", "\t") require.NoError(t, err) - err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0o644) + err = os.WriteFile(test.expected.jsonFile, newJSON, 0o644) require.NoError(t, err) } - data, err := ioutil.ReadFile(test.expected.jsonFile) + data, err := os.ReadFile(test.expected.jsonFile) require.NoError(t, err) assert.JSONEq(t, string(data), string(contents)) }) diff --git a/pkg/api/handler_overview_test.go b/pkg/api/handler_overview_test.go index e5238ce28..00a4bc36c 100644 --- a/pkg/api/handler_overview_test.go +++ b/pkg/api/handler_overview_test.go @@ -2,9 +2,10 @@ package api import ( "encoding/json" - "io/ioutil" + "io" "net/http" "net/http/httptest" + "os" "testing" "github.com/stretchr/testify/assert" @@ -263,7 +264,7 @@ func TestHandler_Overview(t *testing.T) { } assert.Equal(t, resp.Header.Get("Content-Type"), "application/json") - contents, err := ioutil.ReadAll(resp.Body) + contents, err := io.ReadAll(resp.Body) require.NoError(t, err) err = resp.Body.Close() @@ -277,11 +278,11 @@ func TestHandler_Overview(t *testing.T) { newJSON, err := json.MarshalIndent(results, "", "\t") require.NoError(t, err) - err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0o644) + err = os.WriteFile(test.expected.jsonFile, newJSON, 0o644) require.NoError(t, err) } - data, err := ioutil.ReadFile(test.expected.jsonFile) + data, err := os.ReadFile(test.expected.jsonFile) require.NoError(t, err) assert.JSONEq(t, string(data), string(contents)) }) diff --git a/pkg/api/handler_tcp_test.go b/pkg/api/handler_tcp_test.go index ebbc0fed7..f00a99a4b 100644 --- a/pkg/api/handler_tcp_test.go +++ b/pkg/api/handler_tcp_test.go @@ -3,9 +3,10 @@ package api import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "net/http/httptest" + "os" "testing" "github.com/stretchr/testify/assert" @@ -534,7 +535,7 @@ func TestHandler_TCP(t *testing.T) { assert.Equal(t, resp.Header.Get("Content-Type"), "application/json") - contents, err := ioutil.ReadAll(resp.Body) + contents, err := io.ReadAll(resp.Body) require.NoError(t, err) err = resp.Body.Close() @@ -548,11 +549,11 @@ func TestHandler_TCP(t *testing.T) { newJSON, err := json.MarshalIndent(results, "", "\t") require.NoError(t, err) - err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0o644) + err = os.WriteFile(test.expected.jsonFile, newJSON, 0o644) require.NoError(t, err) } - data, err := ioutil.ReadFile(test.expected.jsonFile) + data, err := os.ReadFile(test.expected.jsonFile) require.NoError(t, err) assert.JSONEq(t, string(data), string(contents)) }) diff --git a/pkg/api/handler_test.go b/pkg/api/handler_test.go index 065bb9035..1dd55ebdb 100644 --- a/pkg/api/handler_test.go +++ b/pkg/api/handler_test.go @@ -3,9 +3,10 @@ package api import ( "encoding/json" "flag" - "io/ioutil" + "io" "net/http" "net/http/httptest" + "os" "testing" "github.com/stretchr/testify/assert" @@ -144,7 +145,7 @@ func TestHandler_RawData(t *testing.T) { assert.Equal(t, test.expected.statusCode, resp.StatusCode) assert.Equal(t, resp.Header.Get("Content-Type"), "application/json") - contents, err := ioutil.ReadAll(resp.Body) + contents, err := io.ReadAll(resp.Body) require.NoError(t, err) err = resp.Body.Close() @@ -161,11 +162,11 @@ func TestHandler_RawData(t *testing.T) { newJSON, err := json.MarshalIndent(rtRepr, "", "\t") require.NoError(t, err) - err = ioutil.WriteFile(test.expected.json, newJSON, 0o644) + err = os.WriteFile(test.expected.json, newJSON, 0o644) require.NoError(t, err) } - data, err := ioutil.ReadFile(test.expected.json) + data, err := os.ReadFile(test.expected.json) require.NoError(t, err) assert.JSONEq(t, string(data), string(contents)) }) @@ -267,7 +268,7 @@ func TestHandler_GetMiddleware(t *testing.T) { return } - data, err := ioutil.ReadAll(resp.Body) + data, err := io.ReadAll(resp.Body) require.NoError(t, err) err = resp.Body.Close() diff --git a/pkg/api/handler_udp_test.go b/pkg/api/handler_udp_test.go index 0d5fc14b1..4a5c0116f 100644 --- a/pkg/api/handler_udp_test.go +++ b/pkg/api/handler_udp_test.go @@ -3,9 +3,10 @@ package api import ( "context" "encoding/json" - "io/ioutil" + "io" "net/http" "net/http/httptest" + "os" "testing" "github.com/stretchr/testify/assert" @@ -511,7 +512,7 @@ func TestHandler_UDP(t *testing.T) { assert.Equal(t, resp.Header.Get("Content-Type"), "application/json") - contents, err := ioutil.ReadAll(resp.Body) + contents, err := io.ReadAll(resp.Body) require.NoError(t, err) err = resp.Body.Close() @@ -525,11 +526,11 @@ func TestHandler_UDP(t *testing.T) { newJSON, err := json.MarshalIndent(results, "", "\t") require.NoError(t, err) - err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0o644) + err = os.WriteFile(test.expected.jsonFile, newJSON, 0o644) require.NoError(t, err) } - data, err := ioutil.ReadFile(test.expected.jsonFile) + data, err := os.ReadFile(test.expected.jsonFile) require.NoError(t, err) assert.JSONEq(t, string(data), string(contents)) }) diff --git a/pkg/cli/loader_file.go b/pkg/cli/loader_file.go index dd3624010..f01eb763f 100644 --- a/pkg/cli/loader_file.go +++ b/pkg/cli/loader_file.go @@ -1,7 +1,6 @@ package cli import ( - "io/ioutil" "os" "strings" @@ -56,7 +55,7 @@ func (f *FileLoader) Load(args []string, cmd *cli.Command) (bool, error) { logger := log.WithoutContext() logger.Printf("Configuration loaded from file: %s", configFile) - content, _ := ioutil.ReadFile(configFile) + content, _ := os.ReadFile(configFile) logger.Debug(string(content)) return true, nil diff --git a/pkg/config/dynamic/middlewares.go b/pkg/config/dynamic/middlewares.go index b6f763465..b931de0d4 100644 --- a/pkg/config/dynamic/middlewares.go +++ b/pkg/config/dynamic/middlewares.go @@ -4,7 +4,6 @@ import ( "crypto/tls" "crypto/x509" "fmt" - "io/ioutil" "os" "time" @@ -446,7 +445,7 @@ func (c *ClientTLS) CreateTLSConfig() (*tls.Config, error) { if c.CA != "" { var ca []byte if _, errCA := os.Stat(c.CA); errCA == nil { - ca, err = ioutil.ReadFile(c.CA) + ca, err = os.ReadFile(c.CA) if err != nil { return nil, fmt.Errorf("failed to read CA. %w", err) } diff --git a/pkg/metrics/influxdb_test.go b/pkg/metrics/influxdb_test.go index 9e0bd1735..124392d06 100644 --- a/pkg/metrics/influxdb_test.go +++ b/pkg/metrics/influxdb_test.go @@ -3,7 +3,7 @@ package metrics import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "regexp" @@ -69,7 +69,7 @@ func TestInfluxDB(t *testing.T) { func TestInfluxDBHTTP(t *testing.T) { c := make(chan *string) ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - body, err := ioutil.ReadAll(r.Body) + body, err := io.ReadAll(r.Body) if err != nil { http.Error(w, "can't read body "+err.Error(), http.StatusBadRequest) return diff --git a/pkg/middlewares/accesslog/logger_test.go b/pkg/middlewares/accesslog/logger_test.go index c2449af94..3f37b8312 100644 --- a/pkg/middlewares/accesslog/logger_test.go +++ b/pkg/middlewares/accesslog/logger_test.go @@ -4,7 +4,6 @@ import ( "crypto/tls" "encoding/json" "fmt" - "io/ioutil" "net/http" "net/http/httptest" "net/url" @@ -42,9 +41,7 @@ var ( ) func TestLogRotation(t *testing.T) { - tempDir := createTempDir(t, "traefik_") - - fileName := filepath.Join(tempDir, "traefik.log") + fileName := filepath.Join(t.TempDir(), "traefik.log") rotatedFileName := fileName + ".rotated" config := &types.AccessLog{FilePath: fileName, Format: CommonFormat} @@ -100,7 +97,7 @@ func TestLogRotation(t *testing.T) { func lineCount(t *testing.T, fileName string) int { t.Helper() - fileContents, err := ioutil.ReadFile(fileName) + fileContents, err := os.ReadFile(fileName) if err != nil { t.Fatalf("Error reading from file %s: %s", fileName, err) } @@ -117,8 +114,6 @@ func lineCount(t *testing.T, fileName string) int { } func TestLoggerHeaderFields(t *testing.T) { - tmpDir := createTempDir(t, CommonFormat) - expectedValue := "expectedValue" testCases := []struct { @@ -172,7 +167,7 @@ func TestLoggerHeaderFields(t *testing.T) { for _, test := range testCases { test := test t.Run(test.desc, func(t *testing.T) { - logFile, err := ioutil.TempFile(tmpDir, "*.log") + logFile, err := os.CreateTemp(t.TempDir(), "*.log") require.NoError(t, err) config := &types.AccessLog{ @@ -202,7 +197,7 @@ func TestLoggerHeaderFields(t *testing.T) { writer.WriteHeader(http.StatusOK) })) - logData, err := ioutil.ReadFile(logFile.Name()) + logData, err := os.ReadFile(logFile.Name()) require.NoError(t, err) if test.expected == types.AccessLogDrop { @@ -215,13 +210,11 @@ func TestLoggerHeaderFields(t *testing.T) { } func TestLoggerCLF(t *testing.T) { - tmpDir := createTempDir(t, CommonFormat) - - logFilePath := filepath.Join(tmpDir, logFileNameSuffix) + logFilePath := filepath.Join(t.TempDir(), logFileNameSuffix) config := &types.AccessLog{FilePath: logFilePath, Format: CommonFormat} doLogging(t, config) - logData, err := ioutil.ReadFile(logFilePath) + logData, err := os.ReadFile(logFilePath) require.NoError(t, err) expectedLog := ` TestHost - TestUser [13/Apr/2016:07:14:19 -0700] "POST testpath HTTP/0.0" 123 12 "testReferer" "testUserAgent" 1 "testRouter" "http://127.0.0.1/testService" 1ms` @@ -229,13 +222,11 @@ func TestLoggerCLF(t *testing.T) { } func TestAsyncLoggerCLF(t *testing.T) { - tmpDir := createTempDir(t, CommonFormat) - - logFilePath := filepath.Join(tmpDir, logFileNameSuffix) + logFilePath := filepath.Join(t.TempDir(), logFileNameSuffix) config := &types.AccessLog{FilePath: logFilePath, Format: CommonFormat, BufferingSize: 1024} doLogging(t, config) - logData, err := ioutil.ReadFile(logFilePath) + logData, err := os.ReadFile(logFilePath) require.NoError(t, err) expectedLog := ` TestHost - TestUser [13/Apr/2016:07:14:19 -0700] "POST testpath HTTP/0.0" 123 12 "testReferer" "testUserAgent" 1 "testRouter" "http://127.0.0.1/testService" 1ms` @@ -450,9 +441,7 @@ func TestLoggerJSON(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() - tmpDir := createTempDir(t, JSONFormat) - - logFilePath := filepath.Join(tmpDir, logFileNameSuffix) + logFilePath := filepath.Join(t.TempDir(), logFileNameSuffix) test.config.FilePath = logFilePath if test.tls { @@ -461,7 +450,7 @@ func TestLoggerJSON(t *testing.T) { doLogging(t, test.config) } - logData, err := ioutil.ReadFile(logFilePath) + logData, err := os.ReadFile(logFilePath) require.NoError(t, err) jsonData := make(map[string]interface{}) @@ -675,7 +664,7 @@ func TestNewLogHandlerOutputStdout(t *testing.T) { doLogging(t, test.config) - written, err := ioutil.ReadFile(file.Name()) + written, err := os.ReadFile(file.Name()) require.NoError(t, err, "unable to read captured stdout from file") assertValidLogData(t, test.expectedLog, written) }) @@ -720,7 +709,7 @@ func assertValidLogData(t *testing.T, expected string, logData []byte) { func captureStdout(t *testing.T) (out *os.File, restoreStdout func()) { t.Helper() - file, err := ioutil.TempFile("", "testlogger") + file, err := os.CreateTemp("", "testlogger") require.NoError(t, err, "failed to create temp file") original := os.Stdout @@ -734,17 +723,6 @@ func captureStdout(t *testing.T) (out *os.File, restoreStdout func()) { return file, restoreStdout } -func createTempDir(t *testing.T, prefix string) string { - t.Helper() - - tmpDir, err := ioutil.TempDir("", prefix) - require.NoError(t, err, "failed to create temp dir") - - t.Cleanup(func() { _ = os.RemoveAll(tmpDir) }) - - return tmpDir -} - func doLoggingTLSOpt(t *testing.T, config *types.AccessLog, enableTLS bool) { t.Helper() diff --git a/pkg/middlewares/auth/auth.go b/pkg/middlewares/auth/auth.go index c5891199f..e6c1b6108 100644 --- a/pkg/middlewares/auth/auth.go +++ b/pkg/middlewares/auth/auth.go @@ -1,7 +1,7 @@ package auth import ( - "io/ioutil" + "os" "strings" ) @@ -46,7 +46,7 @@ func loadUsers(fileName string, appendUsers []string) ([]string, error) { } func getLinesFromFile(filename string) ([]string, error) { - dat, err := ioutil.ReadFile(filename) + dat, err := os.ReadFile(filename) if err != nil { return nil, err } diff --git a/pkg/middlewares/auth/basic_auth_test.go b/pkg/middlewares/auth/basic_auth_test.go index 0eb454c9d..9e1b92ad1 100644 --- a/pkg/middlewares/auth/basic_auth_test.go +++ b/pkg/middlewares/auth/basic_auth_test.go @@ -3,7 +3,7 @@ package auth import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "os" @@ -66,7 +66,7 @@ func TestBasicAuthSuccess(t *testing.T) { assert.Equal(t, http.StatusOK, res.StatusCode, "they should be equal") - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) defer res.Body.Close() @@ -97,7 +97,7 @@ func TestBasicAuthUserHeader(t *testing.T) { assert.Equal(t, http.StatusOK, res.StatusCode) - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) defer res.Body.Close() @@ -128,7 +128,7 @@ func TestBasicAuthHeaderRemoved(t *testing.T) { assert.Equal(t, http.StatusOK, res.StatusCode) - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) err = res.Body.Close() require.NoError(t, err) @@ -159,7 +159,7 @@ func TestBasicAuthHeaderPresent(t *testing.T) { assert.Equal(t, http.StatusOK, res.StatusCode) - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) err = res.Body.Close() require.NoError(t, err) @@ -215,9 +215,8 @@ func TestBasicAuthUsersFromFile(t *testing.T) { t.Parallel() // Creates the temporary configuration file with the users - usersFile, err := ioutil.TempFile("", "auth-users") + usersFile, err := os.CreateTemp(t.TempDir(), "auth-users") require.NoError(t, err) - defer os.Remove(usersFile.Name()) _, err = usersFile.Write([]byte(test.userFileContent)) require.NoError(t, err) @@ -250,7 +249,7 @@ func TestBasicAuthUsersFromFile(t *testing.T) { require.Equal(t, http.StatusOK, res.StatusCode, "Cannot authenticate user "+userName) var body []byte - body, err = ioutil.ReadAll(res.Body) + body, err = io.ReadAll(res.Body) require.NoError(t, err) err = res.Body.Close() require.NoError(t, err) @@ -270,7 +269,7 @@ func TestBasicAuthUsersFromFile(t *testing.T) { require.Equal(t, `Basic realm="`+test.realm+`"`, res.Header.Get("WWW-Authenticate")) } - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) err = res.Body.Close() require.NoError(t, err) diff --git a/pkg/middlewares/auth/digest_auth_test.go b/pkg/middlewares/auth/digest_auth_test.go index 4ba746799..066f80e0f 100644 --- a/pkg/middlewares/auth/digest_auth_test.go +++ b/pkg/middlewares/auth/digest_auth_test.go @@ -3,7 +3,7 @@ package auth import ( "context" "fmt" - "io/ioutil" + "io" "net/http" "net/http/httptest" "os" @@ -93,9 +93,8 @@ func TestDigestAuthUsersFromFile(t *testing.T) { t.Parallel() // Creates the temporary configuration file with the users - usersFile, err := ioutil.TempFile("", "auth-users") + usersFile, err := os.CreateTemp(t.TempDir(), "auth-users") require.NoError(t, err) - defer os.Remove(usersFile.Name()) _, err = usersFile.Write([]byte(test.userFileContent)) require.NoError(t, err) @@ -127,7 +126,7 @@ func TestDigestAuthUsersFromFile(t *testing.T) { require.Equal(t, http.StatusOK, res.StatusCode, "Cannot authenticate user "+userName) var body []byte - body, err = ioutil.ReadAll(res.Body) + body, err = io.ReadAll(res.Body) require.NoError(t, err) err = res.Body.Close() require.NoError(t, err) @@ -145,7 +144,7 @@ func TestDigestAuthUsersFromFile(t *testing.T) { require.Equal(t, http.StatusUnauthorized, res.StatusCode) var body []byte - body, err = ioutil.ReadAll(res.Body) + body, err = io.ReadAll(res.Body) require.NoError(t, err) err = res.Body.Close() require.NoError(t, err) diff --git a/pkg/middlewares/auth/forward.go b/pkg/middlewares/auth/forward.go index 65722316a..ed9e7d2ef 100644 --- a/pkg/middlewares/auth/forward.go +++ b/pkg/middlewares/auth/forward.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "io" "net" "net/http" "regexp" @@ -126,7 +126,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) { return } - body, readError := ioutil.ReadAll(forwardResponse.Body) + body, readError := io.ReadAll(forwardResponse.Body) if readError != nil { logMessage := fmt.Sprintf("Error reading body %s. Cause: %s", fa.address, readError) logger.Debug(logMessage) diff --git a/pkg/middlewares/auth/forward_test.go b/pkg/middlewares/auth/forward_test.go index 13a8f5a5f..1aeb5ef9a 100644 --- a/pkg/middlewares/auth/forward_test.go +++ b/pkg/middlewares/auth/forward_test.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "io" - "io/ioutil" "net/http" "net/http/httptest" "testing" @@ -44,7 +43,7 @@ func TestForwardAuthFail(t *testing.T) { require.NoError(t, err) assert.Equal(t, http.StatusForbidden, res.StatusCode) - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) err = res.Body.Close() require.NoError(t, err) @@ -92,7 +91,7 @@ func TestForwardAuthSuccess(t *testing.T) { require.NoError(t, err) assert.Equal(t, http.StatusOK, res.StatusCode) - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) err = res.Body.Close() require.NoError(t, err) @@ -134,7 +133,7 @@ func TestForwardAuthRedirect(t *testing.T) { require.NoError(t, err) assert.Equal(t, "http://example.com/redirect-test", location.String()) - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) err = res.Body.Close() require.NoError(t, err) @@ -187,7 +186,7 @@ func TestForwardAuthRemoveHopByHopHeaders(t *testing.T) { require.NoError(t, err) assert.Equal(t, "http://example.com/redirect-test", location.String(), "they should be equal") - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) assert.NotEmpty(t, string(body), "there should be something in the body") } @@ -238,7 +237,7 @@ func TestForwardAuthFailResponseHeaders(t *testing.T) { assert.Equal(t, value, res.Header[key]) } - body, err := ioutil.ReadAll(res.Body) + body, err := io.ReadAll(res.Body) require.NoError(t, err) err = res.Body.Close() require.NoError(t, err) @@ -489,5 +488,5 @@ type mockBackend struct { } func (b *mockBackend) Setup(componentName string) (opentracing.Tracer, io.Closer, error) { - return b.Tracer, ioutil.NopCloser(nil), nil + return b.Tracer, io.NopCloser(nil), nil } diff --git a/pkg/middlewares/compress/compress_test.go b/pkg/middlewares/compress/compress_test.go index 93f1d6575..f3b01ed0e 100644 --- a/pkg/middlewares/compress/compress_test.go +++ b/pkg/middlewares/compress/compress_test.go @@ -2,7 +2,7 @@ package compress import ( "context" - "io/ioutil" + "io" "net/http" "net/http/httptest" "testing" @@ -205,7 +205,7 @@ func TestIntegrationShouldNotCompress(t *testing.T) { assert.Equal(t, gzipValue, resp.Header.Get(contentEncodingHeader)) assert.Equal(t, acceptEncodingHeader, resp.Header.Get(varyHeader)) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) assert.EqualValues(t, fakeCompressedBody, body) }) @@ -287,7 +287,7 @@ func TestIntegrationShouldCompress(t *testing.T) { assert.Equal(t, gzipValue, resp.Header.Get(contentEncodingHeader)) assert.Equal(t, acceptEncodingHeader, resp.Header.Get(varyHeader)) - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) require.NoError(t, err) if assert.ObjectsAreEqualValues(body, fakeBody) { assert.Fail(t, "expected a compressed body", "got %v", body) diff --git a/pkg/middlewares/retry/retry.go b/pkg/middlewares/retry/retry.go index 57333d9d3..388b3c2a4 100644 --- a/pkg/middlewares/retry/retry.go +++ b/pkg/middlewares/retry/retry.go @@ -4,7 +4,7 @@ import ( "bufio" "context" "fmt" - "io/ioutil" + "io" "math" "net" "net/http" @@ -73,12 +73,12 @@ func (r *retry) GetTracingInformation() (string, ext.SpanKindEnum) { } func (r *retry) ServeHTTP(rw http.ResponseWriter, req *http.Request) { - // if we might make multiple attempts, swap the body for an ioutil.NopCloser + // if we might make multiple attempts, swap the body for an io.NopCloser // cf https://github.com/traefik/traefik/issues/1008 if r.attempts > 1 { body := req.Body defer body.Close() - req.Body = ioutil.NopCloser(body) + req.Body = io.NopCloser(body) } attempts := 1 diff --git a/pkg/middlewares/retry/retry_test.go b/pkg/middlewares/retry/retry_test.go index 47e97efc6..c0a967f7d 100644 --- a/pkg/middlewares/retry/retry_test.go +++ b/pkg/middlewares/retry/retry_test.go @@ -3,10 +3,10 @@ package retry import ( "context" "fmt" + "io" "net/http" "net/http/httptest" "net/http/httptrace" - "strconv" "strings" "testing" "time" @@ -16,10 +16,7 @@ import ( "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares/emptybackendhandler" "github.com/traefik/traefik/v2/pkg/testhelpers" - "github.com/vulcand/oxy/forward" - "github.com/vulcand/oxy/roundrobin" ) func TestRetry(t *testing.T) { @@ -32,14 +29,14 @@ func TestRetry(t *testing.T) { }{ { desc: "no retry on success", - config: dynamic.Retry{Attempts: 1}, + config: dynamic.Retry{Attempts: 5}, wantRetryAttempts: 0, wantResponseStatus: http.StatusOK, amountFaultyEndpoints: 0, }, { desc: "no retry on success with backoff", - config: dynamic.Retry{Attempts: 1, InitialInterval: ptypes.Duration(time.Microsecond * 50)}, + config: dynamic.Retry{Attempts: 5, InitialInterval: ptypes.Duration(time.Microsecond * 50)}, wantRetryAttempts: 0, wantResponseStatus: http.StatusOK, amountFaultyEndpoints: 0, @@ -102,42 +99,28 @@ func TestRetry(t *testing.T) { }, } - backendServer := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - rw.WriteHeader(http.StatusOK) - _, err := rw.Write([]byte("OK")) - if err != nil { - http.Error(rw, err.Error(), http.StatusInternalServerError) - } - })) - - forwarder, err := forward.New() - require.NoError(t, err) - for _, test := range testCases { test := test t.Run(test.desc, func(t *testing.T) { t.Parallel() - loadBalancer, err := roundrobin.New(forwarder) - require.NoError(t, err) + retryAttemps := 0 + next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + retryAttemps++ - // out of range port - basePort := 1133444 - for i := 0; i < test.amountFaultyEndpoints; i++ { - // 192.0.2.0 is a non-routable IP for testing purposes. - // See: https://stackoverflow.com/questions/528538/non-routable-ip-address/18436928#18436928 - // We only use the port specification here because the URL is used as identifier - // in the load balancer and using the exact same URL would not add a new server. - err = loadBalancer.UpsertServer(testhelpers.MustParseURL("http://192.0.2.0:" + strconv.Itoa(basePort+i))) - require.NoError(t, err) - } + if retryAttemps > test.amountFaultyEndpoints { + // calls WroteHeaders on httptrace. + _ = r.Write(io.Discard) - // add the functioning server to the end of the load balancer list - err = loadBalancer.UpsertServer(testhelpers.MustParseURL(backendServer.URL)) - require.NoError(t, err) + rw.WriteHeader(http.StatusOK) + return + } + + rw.WriteHeader(http.StatusBadGateway) + }) retryListener := &countingRetryListener{} - retry, err := New(context.Background(), loadBalancer, test.config, retryListener, "traefikTest") + retry, err := New(context.Background(), next, test.config, retryListener, "traefikTest") require.NoError(t, err) recorder := httptest.NewRecorder() @@ -152,15 +135,9 @@ func TestRetry(t *testing.T) { } func TestRetryEmptyServerList(t *testing.T) { - forwarder, err := forward.New() - require.NoError(t, err) - - loadBalancer, err := roundrobin.New(forwarder) - require.NoError(t, err) - - // The EmptyBackend middleware ensures that there is a 503 - // response status set when there is no backend server in the pool. - next := emptybackendhandler.New(loadBalancer) + next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + rw.WriteHeader(http.StatusServiceUnavailable) + }) retryListener := &countingRetryListener{} retry, err := New(context.Background(), next, dynamic.Retry{Attempts: 3}, retryListener, "traefikTest") @@ -293,47 +270,29 @@ func TestRetryWebsocket(t *testing.T) { }, } - forwarder, err := forward.New() - if err != nil { - t.Fatalf("Error creating forwarder: %v", err) - } - - backendServer := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - upgrader := websocket.Upgrader{} - _, err := upgrader.Upgrade(rw, req, nil) - if err != nil { - http.Error(rw, err.Error(), http.StatusInternalServerError) - } - })) - for _, test := range testCases { test := test t.Run(test.desc, func(t *testing.T) { t.Parallel() - loadBalancer, err := roundrobin.New(forwarder) - if err != nil { - t.Fatalf("Error creating load balancer: %v", err) - } + retryAttemps := 0 + next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + retryAttemps++ - // out of range port - basePort := 1133444 - for i := 0; i < test.amountFaultyEndpoints; i++ { - // 192.0.2.0 is a non-routable IP for testing purposes. - // See: https://stackoverflow.com/questions/528538/non-routable-ip-address/18436928#18436928 - // We only use the port specification here because the URL is used as identifier - // in the load balancer and using the exact same URL would not add a new server. - _ = loadBalancer.UpsertServer(testhelpers.MustParseURL("http://192.0.2.0:" + strconv.Itoa(basePort+i))) - } + if retryAttemps > test.amountFaultyEndpoints { + upgrader := websocket.Upgrader{} + _, err := upgrader.Upgrade(rw, r, nil) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + } + return + } - // add the functioning server to the end of the load balancer list - err = loadBalancer.UpsertServer(testhelpers.MustParseURL(backendServer.URL)) - if err != nil { - t.Fatalf("Fail to upsert server: %v", err) - } + rw.WriteHeader(http.StatusBadGateway) + }) retryListener := &countingRetryListener{} - retryH, err := New(context.Background(), loadBalancer, dynamic.Retry{Attempts: test.maxRequestAttempts}, retryListener, "traefikTest") + retryH, err := New(context.Background(), next, dynamic.Retry{Attempts: test.maxRequestAttempts}, retryListener, "traefikTest") require.NoError(t, err) retryServer := httptest.NewServer(retryH) diff --git a/pkg/pilot/pilot.go b/pkg/pilot/pilot.go index 9edd984c6..7869bd4b5 100644 --- a/pkg/pilot/pilot.go +++ b/pkg/pilot/pilot.go @@ -6,7 +6,7 @@ import ( "encoding/json" "fmt" "hash/fnv" - "io/ioutil" + "io" "net/http" "time" @@ -153,7 +153,7 @@ func (c *client) createUUID() (string, error) { defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return "", fmt.Errorf("failed read response body: %w", err) } @@ -236,7 +236,7 @@ func (c *client) sendDataRetryable(ctx context.Context, req *http.Request) error defer func() { _ = resp.Body.Close() }() - body, err := ioutil.ReadAll(resp.Body) + body, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("failed to read response body: %w", err) } diff --git a/pkg/plugins/client.go b/pkg/plugins/client.go index da9885492..26c1f801b 100644 --- a/pkg/plugins/client.go +++ b/pkg/plugins/client.go @@ -8,7 +8,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "net/url" "os" @@ -68,7 +67,7 @@ func NewClient(opts ClientOptions) (*Client, error) { return nil, err } - goPath, err := ioutil.TempDir(sourcesRootPath, "gop-*") + goPath, err := os.MkdirTemp(sourcesRootPath, "gop-*") if err != nil { return nil, fmt.Errorf("failed to create GoPath: %w", err) } @@ -197,7 +196,7 @@ func (c *Client) Download(ctx context.Context, pName, pVersion string) (string, return hash, nil } - data, _ := ioutil.ReadAll(resp.Body) + data, _ := io.ReadAll(resp.Body) return "", fmt.Errorf("error: %d: %s", resp.StatusCode, string(data)) } @@ -353,7 +352,7 @@ func (c *Client) WriteState(plugins map[string]Descriptor) error { return err } - return ioutil.WriteFile(c.stateFile, mp, 0o600) + return os.WriteFile(c.stateFile, mp, 0o600) } // ResetAll resets all plugins related directories. diff --git a/pkg/provider/acme/local_store.go b/pkg/provider/acme/local_store.go index 7078270ae..33084b320 100644 --- a/pkg/provider/acme/local_store.go +++ b/pkg/provider/acme/local_store.go @@ -2,7 +2,7 @@ package acme import ( "encoding/json" - "io/ioutil" + "io" "os" "sync" @@ -60,7 +60,7 @@ func (s *LocalStore) get(resolverName string) (*StoredData, error) { } defer f.Close() - file, err := ioutil.ReadAll(f) + file, err := io.ReadAll(f) if err != nil { return nil, err } @@ -108,7 +108,7 @@ func (s *LocalStore) listenSaveAction() { logger.Error(err) } - err = ioutil.WriteFile(s.filename, data, 0o600) + err = os.WriteFile(s.filename, data, 0o600) if err != nil { logger.Error(err) } diff --git a/pkg/provider/acme/local_store_test.go b/pkg/provider/acme/local_store_test.go index ad3d1cf6c..44d4ab0fc 100644 --- a/pkg/provider/acme/local_store_test.go +++ b/pkg/provider/acme/local_store_test.go @@ -2,7 +2,7 @@ package acme import ( "fmt" - "io/ioutil" + "os" "path/filepath" "testing" "time" @@ -23,7 +23,7 @@ func TestLocalStore_GetAccount(t *testing.T) { } }`, email) - err := ioutil.WriteFile(acmeFile, []byte(filePayload), 0o600) + err := os.WriteFile(acmeFile, []byte(filePayload), 0o600) require.NoError(t, err) testCases := []struct { @@ -68,7 +68,7 @@ func TestLocalStore_SaveAccount(t *testing.T) { time.Sleep(100 * time.Millisecond) - file, err := ioutil.ReadFile(acmeFile) + file, err := os.ReadFile(acmeFile) require.NoError(t, err) expected := `{ diff --git a/pkg/provider/file/file.go b/pkg/provider/file/file.go index e7781d1b8..d6a8847c5 100644 --- a/pkg/provider/file/file.go +++ b/pkg/provider/file/file.go @@ -5,7 +5,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "path/filepath" "strings" @@ -197,7 +196,7 @@ func flattenCertificates(ctx context.Context, tlsConfig *dynamic.TLSConfiguratio } func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory string, configuration *dynamic.Configuration) (*dynamic.Configuration, error) { - fileList, err := ioutil.ReadDir(directory) + fileList, err := os.ReadDir(directory) if err != nil { return configuration, fmt.Errorf("unable to read directory %s: %w", directory, err) } @@ -436,7 +435,7 @@ func (p *Provider) decodeConfiguration(filePath, content string) (*dynamic.Confi func readFile(filename string) (string, error) { if len(filename) > 0 { - buf, err := ioutil.ReadFile(filename) + buf, err := os.ReadFile(filename) if err != nil { return "", err } diff --git a/pkg/provider/file/file_test.go b/pkg/provider/file/file_test.go index ca6f36728..6dde44321 100644 --- a/pkg/provider/file/file_test.go +++ b/pkg/provider/file/file_test.go @@ -3,7 +3,6 @@ package file import ( "context" "io" - "io/ioutil" "os" "path/filepath" "strconv" @@ -27,13 +26,12 @@ type ProvideTestCase struct { } func TestTLSContent(t *testing.T) { - tempDir := createTempDir(t, "testdir") - defer os.RemoveAll(tempDir) + tempDir := t.TempDir() fileTLS, err := createTempFile("./fixtures/toml/tls_file.cert", tempDir) require.NoError(t, err) - fileConfig, err := ioutil.TempFile(tempDir, "temp*.toml") + fileConfig, err := os.CreateTemp(tempDir, "temp*.toml") require.NoError(t, err) content := ` @@ -245,7 +243,7 @@ func getTestCases() []ProvideTestCase { func createProvider(t *testing.T, test ProvideTestCase, watch bool) *Provider { t.Helper() - tempDir := createTempDir(t, "testdir") + tempDir := t.TempDir() provider := &Provider{} provider.Watch = true @@ -265,7 +263,7 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) *Provider { var file *os.File if watch { var err error - file, err = ioutil.TempFile(tempDir, "temp*"+filepath.Ext(test.filePath)) + file, err = os.CreateTemp(tempDir, "temp*"+filepath.Ext(test.filePath)) require.NoError(t, err) } else { var err error @@ -283,17 +281,6 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) *Provider { return provider } -// createTempDir Helper. -func createTempDir(t *testing.T, dir string) string { - t.Helper() - - d, err := ioutil.TempDir("", dir) - if err != nil { - t.Fatal(err) - } - return d -} - func copyFile(srcPath, dstPath string) error { dst, err := os.OpenFile(dstPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o666) if err != nil { @@ -312,7 +299,7 @@ func copyFile(srcPath, dstPath string) error { } func createTempFile(srcPath, tempDir string) (*os.File, error) { - file, err := ioutil.TempFile(tempDir, "temp*"+filepath.Ext(srcPath)) + file, err := os.CreateTemp(tempDir, "temp*"+filepath.Ext(srcPath)) if err != nil { return nil, err } diff --git a/pkg/provider/http/http.go b/pkg/provider/http/http.go index 37ef0b735..8d1ce329e 100644 --- a/pkg/provider/http/http.go +++ b/pkg/provider/http/http.go @@ -4,7 +4,7 @@ import ( "context" "fmt" "hash/fnv" - "io/ioutil" + "io" "net/http" "time" @@ -139,7 +139,7 @@ func (p *Provider) fetchConfigurationData() ([]byte, error) { return nil, fmt.Errorf("received non-ok response code: %d", res.StatusCode) } - return ioutil.ReadAll(res.Body) + return io.ReadAll(res.Body) } // decodeConfiguration decodes and returns the dynamic configuration from the given data. diff --git a/pkg/provider/kubernetes/crd/client.go b/pkg/provider/kubernetes/crd/client.go index 6ab4c160d..2f2e1b7ad 100644 --- a/pkg/provider/kubernetes/crd/client.go +++ b/pkg/provider/kubernetes/crd/client.go @@ -3,7 +3,6 @@ package crd import ( "errors" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -147,7 +146,7 @@ func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrappe } if caFilePath != "" { - caData, err := ioutil.ReadFile(caFilePath) + caData, err := os.ReadFile(caFilePath) if err != nil { return nil, fmt.Errorf("failed to read CA file %s: %w", caFilePath, err) } diff --git a/pkg/provider/kubernetes/crd/client_mock_test.go b/pkg/provider/kubernetes/crd/client_mock_test.go index 21fcff601..07c39f766 100644 --- a/pkg/provider/kubernetes/crd/client_mock_test.go +++ b/pkg/provider/kubernetes/crd/client_mock_test.go @@ -2,7 +2,7 @@ package crd import ( "fmt" - "io/ioutil" + "os" "path/filepath" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" @@ -46,7 +46,7 @@ func newClientMock(paths ...string) clientMock { var c clientMock for _, path := range paths { - yamlContent, err := ioutil.ReadFile(filepath.FromSlash("./fixtures/" + path)) + yamlContent, err := os.ReadFile(filepath.FromSlash("./fixtures/" + path)) if err != nil { panic(err) } diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 43e612dc8..9b2fa2e60 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -2,7 +2,7 @@ package crd import ( "context" - "io/ioutil" + "os" "path/filepath" "testing" "time" @@ -4394,7 +4394,7 @@ func TestCrossNamespace(t *testing.T) { var k8sObjects []runtime.Object var crdObjects []runtime.Object for _, path := range test.paths { - yamlContent, err := ioutil.ReadFile(filepath.FromSlash("./fixtures/" + path)) + yamlContent, err := os.ReadFile(filepath.FromSlash("./fixtures/" + path)) if err != nil { panic(err) } diff --git a/pkg/provider/kubernetes/gateway/client.go b/pkg/provider/kubernetes/gateway/client.go index 1e42194c1..27d99ac2e 100644 --- a/pkg/provider/kubernetes/gateway/client.go +++ b/pkg/provider/kubernetes/gateway/client.go @@ -4,7 +4,7 @@ import ( "context" "errors" "fmt" - "io/ioutil" + "os" "time" "github.com/traefik/traefik/v2/pkg/log" @@ -138,7 +138,7 @@ func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrappe } if caFilePath != "" { - caData, err := ioutil.ReadFile(caFilePath) + caData, err := os.ReadFile(caFilePath) if err != nil { return nil, fmt.Errorf("failed to read CA file %s: %w", caFilePath, err) } diff --git a/pkg/provider/kubernetes/gateway/client_mock_test.go b/pkg/provider/kubernetes/gateway/client_mock_test.go index 73b7d1eb2..25ff59ac8 100644 --- a/pkg/provider/kubernetes/gateway/client_mock_test.go +++ b/pkg/provider/kubernetes/gateway/client_mock_test.go @@ -2,7 +2,7 @@ package gateway import ( "fmt" - "io/ioutil" + "os" "path/filepath" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" @@ -43,7 +43,7 @@ func newClientMock(paths ...string) clientMock { var c clientMock for _, path := range paths { - yamlContent, err := ioutil.ReadFile(filepath.FromSlash("./fixtures/" + path)) + yamlContent, err := os.ReadFile(filepath.FromSlash("./fixtures/" + path)) if err != nil { panic(err) } diff --git a/pkg/provider/kubernetes/ingress/client.go b/pkg/provider/kubernetes/ingress/client.go index 6c3c5bb77..a37fc1d4d 100644 --- a/pkg/provider/kubernetes/ingress/client.go +++ b/pkg/provider/kubernetes/ingress/client.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "os" "path/filepath" "runtime" @@ -112,7 +111,7 @@ func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrappe } if caFilePath != "" { - caData, err := ioutil.ReadFile(caFilePath) + caData, err := os.ReadFile(caFilePath) if err != nil { return nil, fmt.Errorf("failed to read CA file %s: %w", caFilePath, err) } diff --git a/pkg/provider/kubernetes/ingress/client_mock_test.go b/pkg/provider/kubernetes/ingress/client_mock_test.go index 9ea62d393..94a282990 100644 --- a/pkg/provider/kubernetes/ingress/client_mock_test.go +++ b/pkg/provider/kubernetes/ingress/client_mock_test.go @@ -2,7 +2,7 @@ package ingress import ( "fmt" - "io/ioutil" + "os" "github.com/hashicorp/go-version" "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" @@ -36,7 +36,7 @@ func newClientMock(serverVersion string, paths ...string) clientMock { c.serverVersion = version.Must(version.NewVersion(serverVersion)) for _, path := range paths { - yamlContent, err := ioutil.ReadFile(path) + yamlContent, err := os.ReadFile(path) if err != nil { panic(err) } diff --git a/pkg/provider/traefik/internal_test.go b/pkg/provider/traefik/internal_test.go index 547955413..1e7d5b282 100644 --- a/pkg/provider/traefik/internal_test.go +++ b/pkg/provider/traefik/internal_test.go @@ -4,7 +4,7 @@ import ( "context" "encoding/json" "flag" - "io/ioutil" + "os" "path/filepath" "testing" @@ -271,11 +271,11 @@ func Test_createConfiguration(t *testing.T) { newJSON, err := json.MarshalIndent(cfg, "", " ") require.NoError(t, err) - err = ioutil.WriteFile(filename, newJSON, 0o644) + err = os.WriteFile(filename, newJSON, 0o644) require.NoError(t, err) } - expectedJSON, err := ioutil.ReadFile(filename) + expectedJSON, err := os.ReadFile(filename) require.NoError(t, err) actualJSON, err := json.MarshalIndent(cfg, "", " ") diff --git a/pkg/server/router/router_test.go b/pkg/server/router/router_test.go index 55db73ccc..1e8710a59 100644 --- a/pkg/server/router/router_test.go +++ b/pkg/server/router/router_test.go @@ -2,7 +2,7 @@ package router import ( "context" - "io/ioutil" + "io" "net/http" "net/http/httptest" "strings" @@ -827,7 +827,7 @@ func BenchmarkRouterServe(b *testing.B) { res := &http.Response{ StatusCode: 200, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), } routersConfig := map[string]*dynamic.Router{ @@ -879,7 +879,7 @@ func BenchmarkRouterServe(b *testing.B) { func BenchmarkService(b *testing.B) { res := &http.Response{ StatusCode: 200, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), } serviceConfig := map[string]*dynamic.Service{ diff --git a/pkg/server/server_entrypoint_tcp_test.go b/pkg/server/server_entrypoint_tcp_test.go index a8845d16b..2e147d353 100644 --- a/pkg/server/server_entrypoint_tcp_test.go +++ b/pkg/server/server_entrypoint_tcp_test.go @@ -48,7 +48,7 @@ func TestShutdownTCP(t *testing.T) { for { _, err := http.ReadRequest(bufio.NewReader(conn)) - if errors.Is(err, io.EOF) || (err != nil && strings.HasSuffix(err.Error(), "use of closed network connection")) { + if errors.Is(err, io.EOF) || (err != nil && errors.Is(err, net.ErrClosed)) { return } require.NoError(t, err) diff --git a/pkg/server/service/loadbalancer/mirror/mirror.go b/pkg/server/service/loadbalancer/mirror/mirror.go index d23979cf3..adecf748d 100644 --- a/pkg/server/service/loadbalancer/mirror/mirror.go +++ b/pkg/server/service/loadbalancer/mirror/mirror.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net" "net/http" "sync" @@ -88,7 +87,7 @@ func (m *Mirroring) ServeHTTP(rw http.ResponseWriter, req *http.Request) { } if errors.Is(err, errBodyTooLarge) { - req.Body = ioutil.NopCloser(io.MultiReader(bytes.NewReader(bytesRead), req.Body)) + req.Body = io.NopCloser(io.MultiReader(bytes.NewReader(bytesRead), req.Body)) m.handler.ServeHTTP(rw, req) logger.Debugf("no mirroring, request body larger than allowed size") return @@ -182,7 +181,7 @@ func newReusableRequest(req *http.Request, maxBodySize int64) (*reusableRequest, // unbounded body size if maxBodySize < 0 { - body, err := ioutil.ReadAll(req.Body) + body, err := io.ReadAll(req.Body) if err != nil { return nil, nil, err } @@ -217,7 +216,7 @@ func (rr reusableRequest) clone(ctx context.Context) *http.Request { req := rr.req.Clone(ctx) if rr.body != nil { - req.Body = ioutil.NopCloser(bytes.NewReader(rr.body)) + req.Body = io.NopCloser(bytes.NewReader(rr.body)) } return req diff --git a/pkg/server/service/loadbalancer/mirror/mirror_test.go b/pkg/server/service/loadbalancer/mirror/mirror_test.go index cf1402e37..7353f8bea 100644 --- a/pkg/server/service/loadbalancer/mirror/mirror_test.go +++ b/pkg/server/service/loadbalancer/mirror/mirror_test.go @@ -3,7 +3,7 @@ package mirror import ( "bytes" "context" - "io/ioutil" + "io" "net/http" "net/http/httptest" "sync/atomic" @@ -148,7 +148,7 @@ func TestMirroringWithBody(t *testing.T) { handler := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { assert.NotNil(t, r.Body) - bb, err := ioutil.ReadAll(r.Body) + bb, err := io.ReadAll(r.Body) assert.NoError(t, err) assert.Equal(t, body, bb) rw.WriteHeader(http.StatusOK) @@ -159,7 +159,7 @@ func TestMirroringWithBody(t *testing.T) { for i := 0; i < numMirrors; i++ { err := mirror.AddMirror(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { assert.NotNil(t, r.Body) - bb, err := ioutil.ReadAll(r.Body) + bb, err := io.ReadAll(r.Body) assert.NoError(t, err) assert.Equal(t, body, bb) atomic.AddInt32(&countMirror, 1) @@ -213,13 +213,13 @@ func TestCloneRequest(t *testing.T) { // first call cloned := rr.clone(ctx) - body, err := ioutil.ReadAll(cloned.Body) + body, err := io.ReadAll(cloned.Body) assert.NoError(t, err) assert.Equal(t, bb, body) // second call cloned = rr.clone(ctx) - body, err = ioutil.ReadAll(cloned.Body) + body, err = io.ReadAll(cloned.Body) assert.NoError(t, err) assert.Equal(t, bb, body) }) diff --git a/pkg/server/service/proxy_test.go b/pkg/server/service/proxy_test.go index beba3580f..72805f2a1 100644 --- a/pkg/server/service/proxy_test.go +++ b/pkg/server/service/proxy_test.go @@ -1,7 +1,7 @@ package service import ( - "io/ioutil" + "io" "net/http" "net/http/httptest" "strings" @@ -21,7 +21,7 @@ func (t *staticTransport) RoundTrip(r *http.Request) (*http.Response, error) { func BenchmarkProxy(b *testing.B) { res := &http.Response{ StatusCode: 200, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), } w := httptest.NewRecorder() diff --git a/pkg/tls/certificate.go b/pkg/tls/certificate.go index 032c1cb0b..b18f867e3 100644 --- a/pkg/tls/certificate.go +++ b/pkg/tls/certificate.go @@ -4,7 +4,6 @@ import ( "crypto/tls" "crypto/x509" "fmt" - "io/ioutil" "os" "sort" "strings" @@ -90,7 +89,7 @@ func (f FileOrContent) Read() ([]byte, error) { var content []byte if f.IsPath() { var err error - content, err = ioutil.ReadFile(f.String()) + content, err = os.ReadFile(f.String()) if err != nil { return nil, err } diff --git a/pkg/types/tls.go b/pkg/types/tls.go index 416136e78..8760a7217 100644 --- a/pkg/types/tls.go +++ b/pkg/types/tls.go @@ -5,7 +5,6 @@ import ( "crypto/tls" "crypto/x509" "fmt" - "io/ioutil" "os" "github.com/traefik/traefik/v2/pkg/log" @@ -34,7 +33,7 @@ func (clientTLS *ClientTLS) CreateTLSConfig(ctx context.Context) (*tls.Config, e var ca []byte if _, errCA := os.Stat(clientTLS.CA); errCA == nil { var err error - ca, err = ioutil.ReadFile(clientTLS.CA) + ca, err = os.ReadFile(clientTLS.CA) if err != nil { return nil, fmt.Errorf("failed to read CA. %w", err) } From e898080460f62a9b8ea7b3a6c9f8165ba6c00943 Mon Sep 17 00:00:00 2001 From: Marc Vertes Date: Fri, 5 Mar 2021 14:30:04 +0100 Subject: [PATCH 11/16] feature: tune transport buffer size to increase performance --- pkg/server/service/roundtripper.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/server/service/roundtripper.go b/pkg/server/service/roundtripper.go index f45568fd4..96384c4bc 100644 --- a/pkg/server/service/roundtripper.go +++ b/pkg/server/service/roundtripper.go @@ -123,6 +123,8 @@ func createRoundTripper(cfg *dynamic.ServersTransport) (http.RoundTripper, error IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, + ReadBufferSize: 64 * 1024, + WriteBufferSize: 64 * 1024, } transport.RegisterProtocol("h2c", &h2cTransportWrapper{ From 0e4b6d36fdfe1d7353ef5e4bceafec5fd481a40f Mon Sep 17 00:00:00 2001 From: dom3k Date: Sun, 7 Mar 2021 22:26:03 +0100 Subject: [PATCH 12/16] Use Docker dependency directly without replace directive --- go.mod | 6 ++---- go.sum | 5 +++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index a5fd2b11a..d36dae7a6 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,7 @@ module github.com/traefik/traefik/v2 go 1.16 +// github.com/docker/docker v17.12.0-ce-rc1.0.20200204220554-5f6d6f3f2203+incompatible => v19.03.6 require ( github.com/BurntSushi/toml v0.3.1 github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61 @@ -19,7 +20,7 @@ require ( github.com/davecgh/go-spew v1.1.1 github.com/docker/cli v0.0.0-20200221155518-740919cc7fc0 github.com/docker/distribution v2.7.1+incompatible // indirect - github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 + github.com/docker/docker v17.12.0-ce-rc1.0.20200204220554-5f6d6f3f2203+incompatible github.com/docker/docker-credential-helpers v0.6.3 // indirect github.com/docker/go-connections v0.4.0 github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 // indirect @@ -97,9 +98,6 @@ require ( sigs.k8s.io/service-apis v0.1.0 ) -// Docker v19.03.6 -replace github.com/docker/docker => github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203 - // Containous forks replace ( github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e diff --git a/go.sum b/go.sum index 516778472..867261f56 100644 --- a/go.sum +++ b/go.sum @@ -231,10 +231,11 @@ github.com/docker/cli v0.0.0-20200221155518-740919cc7fc0 h1:hlGHcYGaaHs/yffSubcU github.com/docker/cli v0.0.0-20200221155518-740919cc7fc0/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v17.12.0-ce-rc1.0.20200204220554-5f6d6f3f2203+incompatible h1:VrzTIgiSCSkQxvYPqS92HHDuSrSeniab44r/BruI7qM= +github.com/docker/docker v17.12.0-ce-rc1.0.20200204220554-5f6d6f3f2203+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203 h1:QeBh8wW8pIZKlXxlMOQ8hSCMdJA+2Z/bD/iDyCAS8XU= -github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 h1:X0fj836zx99zFu83v/M79DuBn84IL/Syx1SY6Y5ZEMA= From 71ca23747860d2eaac83da9ada90598b8a4accff Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 8 Mar 2021 09:40:04 +0100 Subject: [PATCH 13/16] Add new GitHub issue chooser. --- .github/ISSUE_TEMPLATE/config.yml | 8 ++++++++ .goreleaser.yml | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/config.yml diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..80c8c86b5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Traefik Community Support + url: https://community.traefik.io/ + about: If you have a question, or are looking for advice, please post on our Discuss forum! The community loves to chime in to help. Happy Coding! + - name: Traefik Helm Chart Issues + url: https://github.com/traefik/traefik-helm-chart + about: Are you submitting an issue or feature enhancement for the Traefik helm chart? Please post in the traefik-helm-chart GitHub Issues. diff --git a/.goreleaser.yml b/.goreleaser.yml index 44beb3025..545ca5281 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -38,8 +38,6 @@ builds: goarch: arm64 - goos: freebsd goarch: arm64 - - goos: darwin - goarch: arm64 changelog: skip: true From 3c8675bb8beb2502dd3af98ae14064fb91c60ef8 Mon Sep 17 00:00:00 2001 From: Julien Salleyron Date: Mon, 8 Mar 2021 09:58:04 +0100 Subject: [PATCH 14/16] Fix flaky tests. Co-authored-by: Ludovic Fernandez --- pkg/metrics/metrics_test.go | 2 +- .../ratelimiter/rate_limiter_test.go | 17 ++++++++++++- pkg/provider/aggregator/aggregator_test.go | 3 ++- pkg/server/configurationwatcher_test.go | 2 +- pkg/server/server_entrypoint_tcp_test.go | 24 ++++++++++--------- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/pkg/metrics/metrics_test.go b/pkg/metrics/metrics_test.go index 522be234f..7036335ea 100644 --- a/pkg/metrics/metrics_test.go +++ b/pkg/metrics/metrics_test.go @@ -30,7 +30,7 @@ func TestScalableHistogram(t *testing.T) { measuredDuration, err := time.ParseDuration(extractedDurationString[0] + "ms") assert.NoError(t, err) - assert.InDelta(t, 500*time.Millisecond, measuredDuration, float64(1*time.Millisecond)) + assert.InDelta(t, 500*time.Millisecond, measuredDuration, float64(15*time.Millisecond)) } func TestNewMultiRegistry(t *testing.T) { diff --git a/pkg/middlewares/ratelimiter/rate_limiter_test.go b/pkg/middlewares/ratelimiter/rate_limiter_test.go index 051b970a2..26d18580b 100644 --- a/pkg/middlewares/ratelimiter/rate_limiter_test.go +++ b/pkg/middlewares/ratelimiter/rate_limiter_test.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "net/http/httptest" + "os" "testing" "time" @@ -279,10 +280,12 @@ func TestRateLimit(t *testing.T) { // actual default value burst = 1 } + period := time.Duration(test.config.Period) if period == 0 { period = time.Second } + if test.config.Average == 0 { if reqCount < 75*test.incomingLoad/100 { t.Fatalf("we (arbitrarily) expect at least 75%% of the requests to go through with no rate limiting, and yet only %d/%d went through", reqCount, test.incomingLoad) @@ -297,14 +300,18 @@ func TestRateLimit(t *testing.T) { // we take into account the configured burst, // because it also helps absorbing non-bursty traffic. rate := float64(test.config.Average) / float64(period) + wantCount := int(int64(rate*float64(test.loadDuration)) + burst) + // Allow for a 2% leeway maxCount := wantCount * 102 / 100 + // With very high CPU loads, // we can expect some extra delay in addition to the rate limiting we already do, // so we allow for some extra leeway there. // Feel free to adjust wrt to the load on e.g. the CI. - minCount := wantCount * 95 / 100 + minCount := computeMinCount(wantCount) + if reqCount < minCount { t.Fatalf("rate was slower than expected: %d requests (wanted > %d) in %v", reqCount, minCount, elapsed) } @@ -314,3 +321,11 @@ func TestRateLimit(t *testing.T) { }) } } + +func computeMinCount(wantCount int) int { + if os.Getenv("CI") != "" { + return wantCount * 60 / 100 + } + + return wantCount * 95 / 100 +} diff --git a/pkg/provider/aggregator/aggregator_test.go b/pkg/provider/aggregator/aggregator_test.go index a6363e819..4bcf2bd79 100644 --- a/pkg/provider/aggregator/aggregator_test.go +++ b/pkg/provider/aggregator/aggregator_test.go @@ -51,7 +51,8 @@ func requireReceivedMessageFromProviders(t *testing.T, cfgCh <-chan dynamic.Mess for range names { select { - case <-time.After(10 * time.Millisecond): + case <-time.After(100 * time.Millisecond): + require.Fail(t, "Timeout while waiting for configuration.") case msg = <-cfgCh: receivedMessagesFrom = append(receivedMessagesFrom, msg.ProviderName) } diff --git a/pkg/server/configurationwatcher_test.go b/pkg/server/configurationwatcher_test.go index 5c31f46df..724d90450 100644 --- a/pkg/server/configurationwatcher_test.go +++ b/pkg/server/configurationwatcher_test.go @@ -216,7 +216,7 @@ func TestListenProvidersDoesNotSkipFlappingConfiguration(t *testing.T) { defer watcher.Stop() // give some time so that the configuration can be processed - time.Sleep(40 * time.Millisecond) + time.Sleep(100 * time.Millisecond) expected := dynamic.Configuration{ HTTP: th.BuildConfiguration( diff --git a/pkg/server/server_entrypoint_tcp_test.go b/pkg/server/server_entrypoint_tcp_test.go index 2e147d353..44b471b2f 100644 --- a/pkg/server/server_entrypoint_tcp_test.go +++ b/pkg/server/server_entrypoint_tcp_test.go @@ -70,6 +70,8 @@ func testShutdown(t *testing.T, router *tcp.Router) { epConfig.LifeCycle.RequestAcceptGraceTimeout = 0 epConfig.LifeCycle.GraceTimeOut = ptypes.Duration(5 * time.Second) + epConfig.RespondingTimeouts.ReadTimeout = ptypes.Duration(5 * time.Second) + epConfig.RespondingTimeouts.WriteTimeout = ptypes.Duration(5 * time.Second) entryPoint, err := NewTCPEntryPoint(context.Background(), &static.EntryPoint{ // We explicitly use an IPV4 address because on Alpine, with an IPV6 address @@ -97,6 +99,11 @@ func testShutdown(t *testing.T, router *tcp.Router) { err = request.Write(conn) require.NoError(t, err) + reader := bufio.NewReader(conn) + // Wait for first byte in response. + _, err = reader.Peek(1) + require.NoError(t, err) + go entryPoint.Shutdown(context.Background()) // Make sure that new connections are not permitted anymore. @@ -123,7 +130,7 @@ func testShutdown(t *testing.T, router *tcp.Router) { // And make sure that the connection we had opened before shutting things down is still operational - resp, err := http.ReadResponse(bufio.NewReader(conn), request) + resp, err := http.ReadResponse(reader, request) require.NoError(t, err) assert.Equal(t, http.StatusOK, resp.StatusCode) } @@ -133,22 +140,17 @@ func startEntrypoint(entryPoint *TCPEntryPoint, router *tcp.Router) (net.Conn, e entryPoint.SwitchRouter(router) - var conn net.Conn - var err error - var epStarted bool for i := 0; i < 10; i++ { - conn, err = net.Dial("tcp", entryPoint.listener.Addr().String()) + conn, err := net.Dial("tcp", entryPoint.listener.Addr().String()) if err != nil { time.Sleep(100 * time.Millisecond) continue } - epStarted = true - break + + return conn, err } - if !epStarted { - return nil, errors.New("entry point never started") - } - return conn, err + + return nil, errors.New("entry point never started") } func TestReadTimeoutWithoutFirstByte(t *testing.T) { From 09d5f59701cd4be8d531537d12813137d1a96223 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Mon, 8 Mar 2021 11:18:04 +0100 Subject: [PATCH 15/16] fix: double close chan on TLS challenge Co-authored-by: Julien Salleyron --- pkg/provider/acme/challenge_tls.go | 32 +++++++++++++++++------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/pkg/provider/acme/challenge_tls.go b/pkg/provider/acme/challenge_tls.go index c04e1b69f..b7f97516d 100644 --- a/pkg/provider/acme/challenge_tls.go +++ b/pkg/provider/acme/challenge_tls.go @@ -63,27 +63,24 @@ func (c *ChallengeTLSALPN) Present(domain, _, keyAuth string) error { timer := time.NewTimer(c.Timeout) - var errC error select { case t := <-timer.C: timer.Stop() - close(c.chans[string(certPEMBlock)]) + + c.muChans.Lock() + c.cleanChan(string(certPEMBlock)) + c.muChans.Unlock() err = c.CleanUp(domain, "", keyAuth) if err != nil { logger.Errorf("Failed to clean up TLS challenge: %v", err) } - errC = fmt.Errorf("timeout %s", t) + return fmt.Errorf("timeout %s", t) case <-ch: // noop + return nil } - - c.muChans.Lock() - delete(c.chans, string(certPEMBlock)) - c.muChans.Unlock() - - return errC } // CleanUp cleans the challenges when certificate is obtained. @@ -115,16 +112,23 @@ func (c *ChallengeTLSALPN) Provide(configurationChan chan<- dynamic.Message, _ * // ListenConfiguration sets a new Configuration into the configurationChan. func (c *ChallengeTLSALPN) ListenConfiguration(conf dynamic.Configuration) { + c.muChans.Lock() + for _, certificate := range conf.TLS.Certificates { if !containsACMETLS1(certificate.Stores) { continue } - c.muChans.Lock() - if _, ok := c.chans[certificate.CertFile.String()]; ok { - close(c.chans[certificate.CertFile.String()]) - } - c.muChans.Unlock() + c.cleanChan(certificate.CertFile.String()) + } + + c.muChans.Unlock() +} + +func (c *ChallengeTLSALPN) cleanChan(key string) { + if _, ok := c.chans[key]; ok { + close(c.chans[key]) + delete(c.chans, key) } } From b1e11f3e885f77b81cebc37e915a173ed57f0ecf Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Doumenjou <925513+jbdoumenjou@users.noreply.github.com> Date: Mon, 8 Mar 2021 18:04:03 +0100 Subject: [PATCH 16/16] Prepare release v2.4.7 --- CHANGELOG.md | 11 +++++++++++ script/gcg/traefik-bugfix.toml | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c981ca4e7..5fd4303e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +## [v2.4.7](https://github.com/traefik/traefik/tree/v2.4.7) (2021-03-08) +[All Commits](https://github.com/traefik/traefik/compare/v2.4.6...v2.4.7) + +**Bug fixes:** +- **[acme]** Fix: double close chan on TLS challenge ([#7956](https://github.com/traefik/traefik/pull/7956) by [ldez](https://github.com/ldez)) +- **[provider]** Bump paerser to v0.1.2 ([#7945](https://github.com/traefik/traefik/pull/7945) by [jbdoumenjou](https://github.com/jbdoumenjou)) +- **[server]** Feature: tune transport buffer size to increase performance ([#7957](https://github.com/traefik/traefik/pull/7957) by [mvertes](https://github.com/mvertes)) + +**Documentation:** +- **[service]** Fix ServersTransport documentation ([#7942](https://github.com/traefik/traefik/pull/7942) by [rtribotte](https://github.com/rtribotte)) + ## [v2.4.6](https://github.com/traefik/traefik/tree/v2.4.6) (2021-03-01) [All Commits](https://github.com/traefik/traefik/compare/v2.4.5...v2.4.6) diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index fe91fd987..0955443ce 100644 --- a/script/gcg/traefik-bugfix.toml +++ b/script/gcg/traefik-bugfix.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example new bugfix v2.4.5 +# example new bugfix v2.4.7 CurrentRef = "v2.4" -PreviousRef = "v2.4.5" +PreviousRef = "v2.4.6" BaseBranch = "v2.4" -FutureCurrentRefName = "v2.4.6" +FutureCurrentRefName = "v2.4.7" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10