Merge current branch v2.4 into master
This commit is contained in:
commit
702e301990
100 changed files with 561 additions and 557 deletions
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
8
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
|
@ -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.
|
|
@ -30,38 +30,64 @@
|
||||||
lines = 230 # default 60
|
lines = 230 # default 60
|
||||||
statements = 120 # default 40
|
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]
|
[linters]
|
||||||
enable-all = true
|
enable-all = true
|
||||||
disable = [
|
disable = [
|
||||||
|
"scopelint", # Deprecated
|
||||||
|
"interfacer", # Deprecated
|
||||||
|
"maligned", # Deprecated
|
||||||
|
"sqlclosecheck", # Not relevant (SQL)
|
||||||
|
"rowserrcheck", # Not relevant (SQL)
|
||||||
|
"lll", # Not relevant
|
||||||
"gocyclo", # FIXME must be fixed
|
"gocyclo", # FIXME must be fixed
|
||||||
"gosec",
|
"cyclop", # Duplicate of gocyclo
|
||||||
"dupl",
|
"gocognit", # Too strict
|
||||||
"maligned",
|
"nestif", # Too many false-positive.
|
||||||
"lll",
|
"prealloc", # Too many false-positive.
|
||||||
"unparam",
|
"makezero", # Not relevant
|
||||||
"prealloc",
|
"ifshort", # Not relevant
|
||||||
"scopelint",
|
"dupl", # Too strict
|
||||||
|
"gosec", # Too strict
|
||||||
"gochecknoinits",
|
"gochecknoinits",
|
||||||
"gochecknoglobals",
|
"gochecknoglobals",
|
||||||
"godox",
|
|
||||||
"gocognit",
|
|
||||||
"bodyclose", # Too many false-positive and panics.
|
|
||||||
"wsl", # Too strict
|
"wsl", # Too strict
|
||||||
|
"nlreturn", # Not relevant
|
||||||
"gomnd", # Too strict
|
"gomnd", # Too strict
|
||||||
"stylecheck", # skip because report issues related to some generated files.
|
"stylecheck", # skip because report issues related to some generated files.
|
||||||
"testpackage", # Too strict
|
"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
|
"tparallel", # Not relevant
|
||||||
"paralleltest", # Not relevant
|
"paralleltest", # Not relevant
|
||||||
|
"exhaustive", # Not relevant
|
||||||
"exhaustivestruct", # Not relevant
|
"exhaustivestruct", # Not relevant
|
||||||
"makezero", # not relevant
|
"goerr113", # Too strict
|
||||||
"forbidigo", # not relevant
|
"wrapcheck", # Too strict
|
||||||
"ifshort", # not relevant
|
"noctx", # Too strict
|
||||||
|
"bodyclose", # Too many false-positive and panics.
|
||||||
|
"unparam", # Too strict
|
||||||
|
"godox", # Too strict
|
||||||
|
"forcetypeassert", # Too strict
|
||||||
]
|
]
|
||||||
|
|
||||||
[issues]
|
[issues]
|
||||||
|
@ -69,9 +95,9 @@
|
||||||
max-per-linter = 0
|
max-per-linter = 0
|
||||||
max-same-issues = 0
|
max-same-issues = 0
|
||||||
exclude = [
|
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",
|
"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",
|
"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]]
|
[[issues.exclude-rules]]
|
||||||
path = "(.+)_test.go"
|
path = "(.+)_test.go"
|
||||||
|
@ -88,18 +114,12 @@
|
||||||
[[issues.exclude-rules]]
|
[[issues.exclude-rules]]
|
||||||
path = "pkg/h2c/h2c.go"
|
path = "pkg/h2c/h2c.go"
|
||||||
text = "Error return value of `rw.Write` is not checked"
|
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]]
|
[[issues.exclude-rules]]
|
||||||
path = "pkg/provider/docker/builder_test.go"
|
path = "pkg/provider/docker/builder_test.go"
|
||||||
text = "(U1000: func )?`(.+)` is unused"
|
text = "(U1000: func )?`(.+)` is unused"
|
||||||
[[issues.exclude-rules]]
|
[[issues.exclude-rules]]
|
||||||
path = "pkg/provider/kubernetes/builder_(endpoint|service)_test.go"
|
path = "pkg/provider/kubernetes/builder_(endpoint|service)_test.go"
|
||||||
text = "(U1000: func )?`(.+)` is unused"
|
text = "(U1000: func )?`(.+)` is unused"
|
||||||
[[issues.exclude-rules]]
|
|
||||||
path = "pkg/config/parser/.+_test.go"
|
|
||||||
text = "U1000: field `(foo|fuu)` is unused"
|
|
||||||
[[issues.exclude-rules]]
|
[[issues.exclude-rules]]
|
||||||
path = "pkg/server/service/bufferpool.go"
|
path = "pkg/server/service/bufferpool.go"
|
||||||
text = "SA6002: argument should be pointer-like to avoid allocations"
|
text = "SA6002: argument should be pointer-like to avoid allocations"
|
||||||
|
@ -109,9 +129,6 @@
|
||||||
[[issues.exclude-rules]]
|
[[issues.exclude-rules]]
|
||||||
path = "pkg/server/middleware/middlewares.go"
|
path = "pkg/server/middleware/middlewares.go"
|
||||||
text = "Function 'buildConstructor' has too many statements"
|
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]]
|
[[issues.exclude-rules]]
|
||||||
path = "pkg/tracing/haystack/logger.go"
|
path = "pkg/tracing/haystack/logger.go"
|
||||||
linters = ["goprintffuncname"]
|
linters = ["goprintffuncname"]
|
||||||
|
|
|
@ -38,8 +38,6 @@ builds:
|
||||||
goarch: arm64
|
goarch: arm64
|
||||||
- goos: freebsd
|
- goos: freebsd
|
||||||
goarch: arm64
|
goarch: arm64
|
||||||
- goos: darwin
|
|
||||||
goarch: arm64
|
|
||||||
|
|
||||||
changelog:
|
changelog:
|
||||||
skip: true
|
skip: true
|
||||||
|
|
24
CHANGELOG.md
24
CHANGELOG.md
|
@ -1,3 +1,27 @@
|
||||||
|
## [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)
|
||||||
|
|
||||||
|
**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)
|
## [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)
|
[All Commits](https://github.com/traefik/traefik/compare/v2.4.3...v2.4.5)
|
||||||
|
|
||||||
|
|
6
Makefile
6
Makefile
|
@ -63,18 +63,18 @@ generate-webui: build-webui-image
|
||||||
mkdir -p static; \
|
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 npm run build:nc; \
|
||||||
docker run --rm -v "$$PWD/static":'/src/static' traefik-webui chown -R $(shell id -u):$(shell id -g) ../static; \
|
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
|
fi
|
||||||
|
|
||||||
## Build the linux binary
|
## Build the linux binary
|
||||||
binary: generate-webui $(PRE_TARGET)
|
binary: generate-webui $(PRE_TARGET)
|
||||||
$(if $(PRE_TARGET),$(DOCKER_RUN_TRAEFIK)) ./script/make.sh generate binary
|
$(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
|
crossbinary-default: generate-webui build-dev-image
|
||||||
$(DOCKER_RUN_TRAEFIK_NOTTY) ./script/make.sh generate crossbinary-default
|
$(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:
|
crossbinary-default-parallel:
|
||||||
$(MAKE) generate-webui
|
$(MAKE) generate-webui
|
||||||
$(MAKE) build-dev-image crossbinary-default
|
$(MAKE) build-dev-image crossbinary-default
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM golang:1.15-alpine
|
FROM golang:1.16-alpine
|
||||||
|
|
||||||
RUN apk --update upgrade \
|
RUN apk --update upgrade \
|
||||||
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
|
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
|
||||||
|
@ -19,7 +19,7 @@ RUN mkdir -p /usr/local/bin \
|
||||||
&& chmod +x /usr/local/bin/go-bindata
|
&& chmod +x /usr/local/bin/go-bindata
|
||||||
|
|
||||||
# Download golangci-lint binary to bin folder in $GOPATH
|
# 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
|
# 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
|
RUN curl -sfL https://raw.githubusercontent.com/client9/misspell/master/install-misspell.sh | bash -s -- -b $GOPATH/bin v0.3.4
|
||||||
|
|
|
@ -13,10 +13,8 @@ func ContextWithSignal(ctx context.Context) context.Context {
|
||||||
signals := make(chan os.Signal)
|
signals := make(chan os.Signal)
|
||||||
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
|
||||||
go func() {
|
go func() {
|
||||||
select {
|
<-signals
|
||||||
case <-signals:
|
cancel()
|
||||||
cancel()
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
return newCtx
|
return newCtx
|
||||||
}
|
}
|
||||||
|
|
|
@ -258,6 +258,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
|
||||||
providerAggregator,
|
providerAggregator,
|
||||||
time.Duration(staticConfiguration.Providers.ProvidersThrottleDuration),
|
time.Duration(staticConfiguration.Providers.ProvidersThrottleDuration),
|
||||||
getDefaultsEntrypoints(staticConfiguration),
|
getDefaultsEntrypoints(staticConfiguration),
|
||||||
|
"internal",
|
||||||
)
|
)
|
||||||
|
|
||||||
// TLS
|
// TLS
|
||||||
|
@ -372,30 +373,32 @@ func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.Pr
|
||||||
|
|
||||||
var resolvers []*acme.Provider
|
var resolvers []*acme.Provider
|
||||||
for name, resolver := range c.CertificatesResolvers {
|
for name, resolver := range c.CertificatesResolvers {
|
||||||
if resolver.ACME != nil {
|
if resolver.ACME == nil {
|
||||||
if localStores[resolver.ACME.Storage] == nil {
|
continue
|
||||||
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 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
|
return resolvers
|
||||||
|
|
|
@ -30,7 +30,7 @@ Successfully tagged traefik-webui:latest
|
||||||
[...]
|
[...]
|
||||||
docker build -t "traefik-dev:4475--feature-documentation" -f build.Dockerfile .
|
docker build -t "traefik-dev:4475--feature-documentation" -f build.Dockerfile .
|
||||||
Sending build context to Docker daemon 279MB
|
Sending build context to Docker daemon 279MB
|
||||||
Step 1/10 : FROM golang:1.14-alpine
|
Step 1/10 : FROM golang:1.16-alpine
|
||||||
---> f4bfb3d22bda
|
---> f4bfb3d22bda
|
||||||
[...]
|
[...]
|
||||||
Successfully built 5c3c1a911277
|
Successfully built 5c3c1a911277
|
||||||
|
@ -62,7 +62,7 @@ PRE_TARGET= make test-unit
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
|
|
||||||
- `go` v1.14+
|
- `go` v1.16+
|
||||||
- environment variable `GO111MODULE=on`
|
- environment variable `GO111MODULE=on`
|
||||||
- [go-bindata](https://github.com/containous/go-bindata) `GO111MODULE=off go get -u github.com/containous/go-bindata/...`
|
- [go-bindata](https://github.com/containous/go-bindata) `GO111MODULE=off go get -u github.com/containous/go-bindata/...`
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ plugin's module name.
|
||||||
plugin's version.
|
plugin's version.
|
||||||
|
|
||||||
`--global.checknewversion`:
|
`--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`:
|
`--global.sendanonymoususage`:
|
||||||
Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. (Default: ```false```)
|
Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. (Default: ```false```)
|
||||||
|
@ -703,7 +703,7 @@ Display additional provider logs. (Default: ```false```)
|
||||||
Watch provider. (Default: ```true```)
|
Watch provider. (Default: ```true```)
|
||||||
|
|
||||||
`--providers.providersthrottleduration`:
|
`--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`:
|
`--providers.rancher`:
|
||||||
Enable Rancher backend with default settings. (Default: ```false```)
|
Enable Rancher backend with default settings. (Default: ```false```)
|
||||||
|
@ -811,7 +811,7 @@ The amount of time to wait for a server's response headers after fully writing t
|
||||||
Disable SSL certificate verification. (Default: ```false```)
|
Disable SSL certificate verification. (Default: ```false```)
|
||||||
|
|
||||||
`--serverstransport.maxidleconnsperhost`:
|
`--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`:
|
`--serverstransport.rootcas`:
|
||||||
Add cert file for self-signed certificate.
|
Add cert file for self-signed certificate.
|
||||||
|
|
|
@ -193,7 +193,7 @@ plugin's module name.
|
||||||
plugin's version.
|
plugin's version.
|
||||||
|
|
||||||
`TRAEFIK_GLOBAL_CHECKNEWVERSION`:
|
`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`:
|
`TRAEFIK_GLOBAL_SENDANONYMOUSUSAGE`:
|
||||||
Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. (Default: ```false```)
|
Periodically send anonymous usage statistics. If the option is not specified, it will be enabled by default. (Default: ```false```)
|
||||||
|
@ -703,7 +703,7 @@ Display additional provider logs. (Default: ```false```)
|
||||||
Watch provider. (Default: ```true```)
|
Watch provider. (Default: ```true```)
|
||||||
|
|
||||||
`TRAEFIK_PROVIDERS_PROVIDERSTHROTTLEDURATION`:
|
`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`:
|
`TRAEFIK_PROVIDERS_RANCHER`:
|
||||||
Enable Rancher backend with default settings. (Default: ```false```)
|
Enable Rancher backend with default settings. (Default: ```false```)
|
||||||
|
@ -811,7 +811,7 @@ The amount of time to wait for a server's response headers after fully writing t
|
||||||
Disable SSL certificate verification. (Default: ```false```)
|
Disable SSL certificate verification. (Default: ```false```)
|
||||||
|
|
||||||
`TRAEFIK_SERVERSTRANSPORT_MAXIDLECONNSPERHOST`:
|
`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`:
|
`TRAEFIK_SERVERSTRANSPORT_ROOTCAS`:
|
||||||
Add cert file for self-signed certificate.
|
Add cert file for self-signed certificate.
|
||||||
|
|
|
@ -132,10 +132,11 @@ you'd add the tag `traefik.http.services.{name-of-your-choice}.loadbalancer.pass
|
||||||
|
|
||||||
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
|
??? info "`traefik.http.services.<service_name>.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.
|
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar
|
traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar@file
|
||||||
```
|
```
|
||||||
|
|
||||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||||
|
|
|
@ -287,10 +287,11 @@ you'd add the label `traefik.http.services.<name-of-your-choice>.loadbalancer.pa
|
||||||
|
|
||||||
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
|
??? info "`traefik.http.services.<service_name>.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.
|
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- "traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar"
|
- "traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar@file"
|
||||||
```
|
```
|
||||||
|
|
||||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||||
|
|
|
@ -135,10 +135,11 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
|
||||||
|
|
||||||
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
|
??? info "`traefik.http.services.<service_name>.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.
|
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar
|
traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar@file
|
||||||
```
|
```
|
||||||
|
|
||||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||||
|
|
|
@ -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:
|
You can find an excerpt of the available custom resources in the table below:
|
||||||
|
|
||||||
| Kind | Purpose | Concept Behind |
|
| Kind | Purpose | Concept Behind |
|
||||||
|------------------------------------------|---------------------------------------------------------------|----------------------------------------------------------------|
|
|--------------------------------------------|--------------------------------------------------------------------|----------------------------------------------------------------|
|
||||||
| [IngressRoute](#kind-ingressroute) | HTTP Routing | [HTTP router](../routers/index.md#configuring-http-routers) |
|
| [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) |
|
| [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) |
|
| [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) |
|
| [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) |
|
| [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) |
|
| [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) |
|
| [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`
|
### Kind: `IngressRoute`
|
||||||
|
|
||||||
|
|
|
@ -112,11 +112,12 @@ A Story of key & values
|
||||||
|
|
||||||
??? info "`traefik/http/services/<service_name>/loadbalancer/serverstransport`"
|
??? info "`traefik/http/services/<service_name>/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.
|
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||||
|
|
||||||
| Key (Path) | Value |
|
| Key (Path) | Value |
|
||||||
|-----------------------------------------------------------------|----------|
|
|-----------------------------------------------------------------|---------------|
|
||||||
| `traefik/http/services/myservice/loadbalancer/serverstransport` | `foobar` |
|
| `traefik/http/services/myservice/loadbalancer/serverstransport` | `foobar@file` |
|
||||||
|
|
||||||
??? info "`traefik/http/services/<service_name>/loadbalancer/passhostheader`"
|
??? info "`traefik/http/services/<service_name>/loadbalancer/passhostheader`"
|
||||||
|
|
||||||
|
|
|
@ -161,11 +161,12 @@ For example, to change the passHostHeader behavior, you'd add the label `"traefi
|
||||||
```
|
```
|
||||||
|
|
||||||
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
|
??? info "`traefik.http.services.<service_name>.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.
|
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||||
|
|
||||||
```json
|
```json
|
||||||
"traefik.http.services.<service_name>.loadbalancer.serverstransport": "foobar"
|
"traefik.http.services.<service_name>.loadbalancer.serverstransport": "foobar@file"
|
||||||
```
|
```
|
||||||
|
|
||||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||||
|
|
|
@ -168,10 +168,11 @@ you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.pa
|
||||||
|
|
||||||
??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`"
|
??? info "`traefik.http.services.<service_name>.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.
|
See [serverstransport](../services/index.md#serverstransport) for more information.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- "traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar"
|
- "traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar@file"
|
||||||
```
|
```
|
||||||
|
|
||||||
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`"
|
||||||
|
|
|
@ -332,7 +332,7 @@ Below are the available options for the health check mechanism:
|
||||||
!!! info "Recovering Servers"
|
!!! info "Recovering Servers"
|
||||||
|
|
||||||
Traefik keeps monitoring the health of unhealthy 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"
|
!!! warning "Health check in Kubernetes"
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ RUN npm install
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# BUILD
|
# BUILD
|
||||||
FROM golang:1.15-alpine as gobuild
|
FROM golang:1.16-alpine as gobuild
|
||||||
|
|
||||||
RUN apk --update upgrade \
|
RUN apk --update upgrade \
|
||||||
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
|
&& apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \
|
||||||
|
|
15
go.mod
15
go.mod
|
@ -1,7 +1,8 @@
|
||||||
module github.com/traefik/traefik/v2
|
module github.com/traefik/traefik/v2
|
||||||
|
|
||||||
go 1.15
|
go 1.16
|
||||||
|
|
||||||
|
// github.com/docker/docker v17.12.0-ce-rc1.0.20200204220554-5f6d6f3f2203+incompatible => v19.03.6
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61
|
github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61
|
||||||
|
@ -18,7 +19,7 @@ require (
|
||||||
github.com/davecgh/go-spew v1.1.1
|
github.com/davecgh/go-spew v1.1.1
|
||||||
github.com/docker/cli v0.0.0-20200221155518-740919cc7fc0
|
github.com/docker/cli v0.0.0-20200221155518-740919cc7fc0
|
||||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
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/docker-credential-helpers v0.6.3 // indirect
|
||||||
github.com/docker/go-connections v0.4.0
|
github.com/docker/go-connections v0.4.0
|
||||||
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 // indirect
|
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 // indirect
|
||||||
|
@ -70,14 +71,14 @@ require (
|
||||||
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154
|
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154
|
||||||
github.com/tinylib/msgp v1.0.2 // indirect
|
github.com/tinylib/msgp v1.0.2 // indirect
|
||||||
github.com/traefik/gziphandler v1.1.2-0.20210212101304-175e0fad6888
|
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.8
|
github.com/traefik/yaegi v0.9.13
|
||||||
github.com/uber/jaeger-client-go v2.25.0+incompatible
|
github.com/uber/jaeger-client-go v2.25.0+incompatible
|
||||||
github.com/uber/jaeger-lib v2.2.0+incompatible
|
github.com/uber/jaeger-lib v2.2.0+incompatible
|
||||||
github.com/unrolled/render v1.0.2
|
github.com/unrolled/render v1.0.2
|
||||||
github.com/unrolled/secure v1.0.7
|
github.com/unrolled/secure v1.0.7
|
||||||
github.com/vdemeester/shakers v0.1.0
|
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
|
github.com/vulcand/predicate v1.1.0
|
||||||
go.elastic.co/apm v1.7.0
|
go.elastic.co/apm v1.7.0
|
||||||
go.elastic.co/apm/module/apmot v1.7.0
|
go.elastic.co/apm/module/apmot v1.7.0
|
||||||
|
@ -87,7 +88,6 @@ require (
|
||||||
google.golang.org/grpc v1.27.1
|
google.golang.org/grpc v1.27.1
|
||||||
gopkg.in/DataDog/dd-trace-go.v1 v1.19.0
|
gopkg.in/DataDog/dd-trace-go.v1 v1.19.0
|
||||||
gopkg.in/fsnotify.v1 v1.4.7
|
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
|
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776
|
||||||
k8s.io/api v0.19.2
|
k8s.io/api v0.19.2
|
||||||
k8s.io/apiextensions-apiserver v0.18.6
|
k8s.io/apiextensions-apiserver v0.18.6
|
||||||
|
@ -99,9 +99,6 @@ require (
|
||||||
sigs.k8s.io/service-apis v0.1.0
|
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
|
// Containous forks
|
||||||
replace (
|
replace (
|
||||||
github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e
|
github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e
|
||||||
|
|
26
go.sum
26
go.sum
|
@ -79,11 +79,9 @@ github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61/g
|
||||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||||
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
|
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
|
||||||
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||||
github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk=
|
|
||||||
github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||||
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
|
||||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||||
github.com/Masterminds/sprig/v3 v3.1.0 h1:j7GpgZ7PdFqNsmncycTHsLmVPf5/3wJtlgW9TNDYD9Y=
|
|
||||||
github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA=
|
github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA=
|
||||||
github.com/Masterminds/sprig/v3 v3.2.0 h1:P1ekkbuU73Ui/wS0nK1HOM37hh4xdfZo485UPf8rc+Y=
|
github.com/Masterminds/sprig/v3 v3.2.0 h1:P1ekkbuU73Ui/wS0nK1HOM37hh4xdfZo485UPf8rc+Y=
|
||||||
github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI=
|
github.com/Masterminds/sprig/v3 v3.2.0/go.mod h1:tWhwTbUTndesPNeF0C900vKoq283u6zp4APT9vaF3SI=
|
||||||
|
@ -105,7 +103,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.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
github.com/Shopify/sarama v1.23.1 h1:XxJBCZEoWJtoWjf/xRbmGUpAmTZGnuuF0ON0EvxxBrs=
|
github.com/Shopify/sarama v1.23.1 h1:XxJBCZEoWJtoWjf/xRbmGUpAmTZGnuuF0ON0EvxxBrs=
|
||||||
github.com/Shopify/sarama v1.23.1/go.mod h1:XLH1GYJnLVE0XCr6KdJGVJRTwY30moWNJ4sERjXX6fs=
|
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/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 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
|
||||||
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||||
|
@ -245,10 +242,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/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 h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
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 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
|
||||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
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 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
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=
|
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 h1:X0fj836zx99zFu83v/M79DuBn84IL/Syx1SY6Y5ZEMA=
|
||||||
|
@ -563,7 +561,6 @@ github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df h1:MZf03xP9WdakyXhOWuAD5
|
||||||
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4=
|
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhKWFeDesPjMj+wCHReeknARU3wqlyN4=
|
||||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
|
|
||||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||||
|
@ -709,7 +706,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.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||||
github.com/nats-io/nkeys v0.1.3/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/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/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
|
||||||
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
|
||||||
|
@ -934,7 +930,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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
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.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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
@ -950,10 +945,10 @@ 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/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 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/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.2 h1:0zvJgdwp2dNUodZHfgf+3IcaeJH2B28NcCGM+iZVtds=
|
||||||
github.com/traefik/paerser v0.1.1/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE=
|
github.com/traefik/paerser v0.1.2/go.mod h1:yYnAgdEC2wJH5CgG75qGWC8SsFDEapg09o9RrA6FfrE=
|
||||||
github.com/traefik/yaegi v0.9.8 h1:sYGKV2d911B9olVsSO/nRmjIh+CQTffAUSzoyv4a4/4=
|
github.com/traefik/yaegi v0.9.13 h1:LQzMIjTp3fFyAULaWel88iJz1QL2lBd0bbaOSV8or4o=
|
||||||
github.com/traefik/yaegi v0.9.8/go.mod h1:FAYnRlZyuVlEkvnkHq3bvJ1lW5be6XuwgLdkYgYG6Lk=
|
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 h1:0Z+qVsyeiQdWfcAUeJyF0IEKAPvhJwwpwPi2WGtBIiE=
|
||||||
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
|
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=
|
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||||
|
@ -978,8 +973,8 @@ github.com/vdemeester/shakers v0.1.0/go.mod h1:IZ1HHynUOQt32iQ3rvAeVddXLd19h/6LW
|
||||||
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
|
||||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||||
github.com/vulcand/oxy v1.1.0 h1:DbBijGo1+6cFqR9jarkMxasdj0lgWwrrFtue6ijek4Q=
|
github.com/vulcand/oxy v1.2.0 h1:Y2Wt1EgQddA/qMnp1+YXjehPsyw2Gy8CAfavkFF+fQk=
|
||||||
github.com/vulcand/oxy v1.1.0/go.mod h1:ADiMYHi8gkGl2987yQIzDRoXZilANF4WtKaQ92OppKY=
|
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 h1:Gq/uWopa4rx/tnZu2opOSBqHK63Yqlou/SzrbwdJiNg=
|
||||||
github.com/vulcand/predicate v1.1.0/go.mod h1:mlccC5IRBoc2cIFmCB8ZM62I3VDb6p2GXESMHa3CnZg=
|
github.com/vulcand/predicate v1.1.0/go.mod h1:mlccC5IRBoc2cIFmCB8ZM62I3VDb6p2GXESMHa3CnZg=
|
||||||
github.com/vultr/govultr/v2 v2.0.0 h1:+lAtqfWy3g9VwL7tT2Fpyad8Vv4MxOhT/NU8O5dk+EQ=
|
github.com/vultr/govultr/v2 v2.0.0 h1:+lAtqfWy3g9VwL7tT2Fpyad8Vv4MxOhT/NU8O5dk+EQ=
|
||||||
|
@ -1008,7 +1003,6 @@ go.elastic.co/fastjson v1.0.0 h1:ooXV/ABvf+tBul26jcVViPT3sBir0PvXgibYB1IQQzg=
|
||||||
go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs=
|
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.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.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/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 v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||||
go.etcd.io/etcd v3.3.13+incompatible h1:jCejD5EMnlGxFvcGRyEV4VGlENZc7oPQX6o0t7n3xbw=
|
go.etcd.io/etcd v3.3.13+incompatible h1:jCejD5EMnlGxFvcGRyEV4VGlENZc7oPQX6o0t7n3xbw=
|
||||||
|
@ -1380,8 +1374,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/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 h1:cIuC1OLRGZrld+16ZJvvZxVJeKPsvd5eUIvxfoN5hSM=
|
||||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
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 h1:hHMV/yKPwMnJhPuPx7pH2Uw/3Qyf+thJYlisUc44010=
|
||||||
gopkg.in/jcmturner/gokrb5.v7 v7.2.3/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
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=
|
gopkg.in/jcmturner/rpc.v1 v1.1.0 h1:QHIUxTX1ISuAv9dD2wJ9HWQVuWDX/Zc0PfeC2tjc4rU=
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -58,7 +57,7 @@ func (s *AccessLogSuite) TestAccessLog(c *check.C) {
|
||||||
defer display(c)
|
defer display(c)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
traefikLog, err := ioutil.ReadFile(traefikTestLogFile)
|
traefikLog, err := os.ReadFile(traefikTestLogFile)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
log.WithoutContext().Info(string(traefikLog))
|
log.WithoutContext().Info(string(traefikLog))
|
||||||
}()
|
}()
|
||||||
|
@ -545,7 +544,7 @@ func (s *AccessLogSuite) TestAccessLogAuthFrontendSuccess(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkNoOtherTraefikProblems(c *check.C) {
|
func checkNoOtherTraefikProblems(c *check.C) {
|
||||||
traefikLog, err := ioutil.ReadFile(traefikTestLogFile)
|
traefikLog, err := os.ReadFile(traefikTestLogFile)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
if len(traefikLog) > 0 {
|
if len(traefikLog) > 0 {
|
||||||
fmt.Printf("%s\n", string(traefikLog))
|
fmt.Printf("%s\n", string(traefikLog))
|
||||||
|
@ -583,7 +582,7 @@ func checkAccessLogExactValuesOutput(c *check.C, values []accessLogValue) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractLines(c *check.C) []string {
|
func extractLines(c *check.C) []string {
|
||||||
accessLog, err := ioutil.ReadFile(traefikTestAccessLogFile)
|
accessLog, err := os.ReadFile(traefikTestAccessLogFile)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
lines := strings.Split(string(accessLog), "\n")
|
lines := strings.Split(string(accessLog), "\n")
|
||||||
|
@ -613,7 +612,7 @@ func ensureWorkingDirectoryIsClean() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkTraefikStarted(c *check.C) []byte {
|
func checkTraefikStarted(c *check.C) []byte {
|
||||||
traefikLog, err := ioutil.ReadFile(traefikTestLogFile)
|
traefikLog, err := os.ReadFile(traefikTestLogFile)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
if len(traefikLog) > 0 {
|
if len(traefikLog) > 0 {
|
||||||
fmt.Printf("%s\n", string(traefikLog))
|
fmt.Printf("%s\n", string(traefikLog))
|
||||||
|
@ -663,7 +662,7 @@ func waitForTraefik(c *check.C, containerName string) {
|
||||||
func displayTraefikLogFile(c *check.C, path string) {
|
func displayTraefikLogFile(c *check.C, path string) {
|
||||||
if c.Failed() {
|
if c.Failed() {
|
||||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
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())
|
fmt.Printf("%s: Traefik logs: \n", c.TestName())
|
||||||
if errRead == nil {
|
if errRead == nil {
|
||||||
fmt.Println(content)
|
fmt.Println(content)
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -67,7 +66,7 @@ func setupPebbleRootCA() (*http.Transport, error) {
|
||||||
os.Setenv("LEGO_CA_CERTIFICATES", path)
|
os.Setenv("LEGO_CA_CERTIFICATES", path)
|
||||||
os.Setenv("LEGO_CA_SERVER_NAME", "pebble")
|
os.Setenv("LEGO_CA_SERVER_NAME", "pebble")
|
||||||
|
|
||||||
customCAs, err := ioutil.ReadFile(path)
|
customCAs, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package integration
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -138,11 +137,11 @@ func (s *ConsulSuite) TestSimpleConfiguration(c *check.C) {
|
||||||
expectedJSON := filepath.FromSlash("testdata/rawdata-consul.json")
|
expectedJSON := filepath.FromSlash("testdata/rawdata-consul.json")
|
||||||
|
|
||||||
if *updateExpected {
|
if *updateExpected {
|
||||||
err = ioutil.WriteFile(expectedJSON, got, 0o666)
|
err = os.WriteFile(expectedJSON, got, 0o666)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected, err := ioutil.ReadFile(expectedJSON)
|
expected, err := os.ReadFile(expectedJSON)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
if !bytes.Equal(expected, got) {
|
if !bytes.Equal(expected, got) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package integration
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -135,7 +135,7 @@ func (s *DockerSuite) TestDefaultDockerContainers(c *check.C) {
|
||||||
resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK)
|
resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
var version map[string]interface{}
|
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)
|
resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
var version map[string]interface{}
|
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)
|
resp, err := try.ResponseUntilStatusCode(req, 1500*time.Millisecond, http.StatusOK)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
var version map[string]interface{}
|
var version map[string]interface{}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package integration
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -138,11 +137,11 @@ func (s *EtcdSuite) TestSimpleConfiguration(c *check.C) {
|
||||||
expectedJSON := filepath.FromSlash("testdata/rawdata-etcd.json")
|
expectedJSON := filepath.FromSlash("testdata/rawdata-etcd.json")
|
||||||
|
|
||||||
if *updateExpected {
|
if *updateExpected {
|
||||||
err = ioutil.WriteFile(expectedJSON, got, 0o666)
|
err = os.WriteFile(expectedJSON, got, 0o666)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected, err := ioutil.ReadFile(expectedJSON)
|
expected, err := os.ReadFile(expectedJSON)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
if !bytes.Equal(expected, got) {
|
if !bytes.Equal(expected, got) {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
"io/ioutil"
|
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
@ -35,9 +34,9 @@ type myserver struct {
|
||||||
|
|
||||||
func (s *GRPCSuite) SetUpSuite(c *check.C) {
|
func (s *GRPCSuite) SetUpSuite(c *check.C) {
|
||||||
var err error
|
var err error
|
||||||
LocalhostCert, err = ioutil.ReadFile("./resources/tls/local.cert")
|
LocalhostCert, err = os.ReadFile("./resources/tls/local.cert")
|
||||||
c.Assert(err, check.IsNil)
|
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)
|
c.Assert(err, check.IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +111,7 @@ func callHelloClientGRPC(name string, secure bool) (string, error) {
|
||||||
} else {
|
} else {
|
||||||
client, closer, err = getHelloClientGRPCh2c()
|
client, closer, err = getHelloClientGRPCh2c()
|
||||||
}
|
}
|
||||||
defer closer()
|
defer func() { _ = closer() }()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -139,6 +138,7 @@ func callStreamExampleClientGRPC() (helloworld.Greeter_StreamExampleClient, func
|
||||||
|
|
||||||
func (s *GRPCSuite) TestGRPC(c *check.C) {
|
func (s *GRPCSuite) TestGRPC(c *check.C) {
|
||||||
lis, err := net.Listen("tcp", ":0")
|
lis, err := net.Listen("tcp", ":0")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
_, port, err := net.SplitHostPort(lis.Addr().String())
|
_, port, err := net.SplitHostPort(lis.Addr().String())
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
@ -181,6 +181,7 @@ func (s *GRPCSuite) TestGRPC(c *check.C) {
|
||||||
|
|
||||||
func (s *GRPCSuite) TestGRPCh2c(c *check.C) {
|
func (s *GRPCSuite) TestGRPCh2c(c *check.C) {
|
||||||
lis, err := net.Listen("tcp", ":0")
|
lis, err := net.Listen("tcp", ":0")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
_, port, err := net.SplitHostPort(lis.Addr().String())
|
_, port, err := net.SplitHostPort(lis.Addr().String())
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
@ -219,6 +220,7 @@ func (s *GRPCSuite) TestGRPCh2c(c *check.C) {
|
||||||
|
|
||||||
func (s *GRPCSuite) TestGRPCh2cTermination(c *check.C) {
|
func (s *GRPCSuite) TestGRPCh2cTermination(c *check.C) {
|
||||||
lis, err := net.Listen("tcp", ":0")
|
lis, err := net.Listen("tcp", ":0")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
_, port, err := net.SplitHostPort(lis.Addr().String())
|
_, port, err := net.SplitHostPort(lis.Addr().String())
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
@ -261,6 +263,7 @@ func (s *GRPCSuite) TestGRPCh2cTermination(c *check.C) {
|
||||||
|
|
||||||
func (s *GRPCSuite) TestGRPCInsecure(c *check.C) {
|
func (s *GRPCSuite) TestGRPCInsecure(c *check.C) {
|
||||||
lis, err := net.Listen("tcp", ":0")
|
lis, err := net.Listen("tcp", ":0")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
_, port, err := net.SplitHostPort(lis.Addr().String())
|
_, port, err := net.SplitHostPort(lis.Addr().String())
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
@ -340,7 +343,7 @@ func (s *GRPCSuite) TestGRPCBuffer(c *check.C) {
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
var client helloworld.Greeter_StreamExampleClient
|
var client helloworld.Greeter_StreamExampleClient
|
||||||
client, closer, err := callStreamExampleClientGRPC()
|
client, closer, err := callStreamExampleClientGRPC()
|
||||||
defer closer()
|
defer func() { _ = closer() }()
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
received := make(chan bool)
|
received := make(chan bool)
|
||||||
|
@ -400,8 +403,10 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) {
|
||||||
|
|
||||||
var client helloworld.Greeter_StreamExampleClient
|
var client helloworld.Greeter_StreamExampleClient
|
||||||
client, closer, err := callStreamExampleClientGRPC()
|
client, closer, err := callStreamExampleClientGRPC()
|
||||||
defer closer()
|
defer func() {
|
||||||
defer func() { stopStreamExample <- true }()
|
_ = closer()
|
||||||
|
stopStreamExample <- true
|
||||||
|
}()
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
received := make(chan bool)
|
received := make(chan bool)
|
||||||
|
@ -425,6 +430,7 @@ func (s *GRPCSuite) TestGRPCBufferWithFlushInterval(c *check.C) {
|
||||||
|
|
||||||
func (s *GRPCSuite) TestGRPCWithRetry(c *check.C) {
|
func (s *GRPCSuite) TestGRPCWithRetry(c *check.C) {
|
||||||
lis, err := net.Listen("tcp", ":0")
|
lis, err := net.Listen("tcp", ":0")
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
_, port, err := net.SplitHostPort(lis.Addr().String())
|
_, port, err := net.SplitHostPort(lis.Addr().String())
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
@ -143,7 +142,7 @@ func (s *BaseSuite) traefikCmd(args ...string) (*exec.Cmd, func(*check.C)) {
|
||||||
func (s *BaseSuite) displayLogK3S(c *check.C) {
|
func (s *BaseSuite) displayLogK3S(c *check.C) {
|
||||||
filePath := "./fixtures/k8s/config.skip/k3s.log"
|
filePath := "./fixtures/k8s/config.skip/k3s.log"
|
||||||
if _, err := os.Stat(filePath); err == nil {
|
if _, err := os.Stat(filePath); err == nil {
|
||||||
content, errR := ioutil.ReadFile(filePath)
|
content, errR := os.ReadFile(filePath)
|
||||||
if errR != nil {
|
if errR != nil {
|
||||||
log.WithoutContext().Error(errR)
|
log.WithoutContext().Error(errR)
|
||||||
}
|
}
|
||||||
|
@ -178,7 +177,7 @@ func (s *BaseSuite) adaptFile(c *check.C, path string, tempObjects interface{})
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
folder, prefix := filepath.Split(path)
|
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)
|
c.Assert(err, checker.IsNil)
|
||||||
defer tmpFile.Close()
|
defer tmpFile.Close()
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -164,14 +163,14 @@ func testConfiguration(c *check.C, path, apiPort string) {
|
||||||
newJSON, err := json.MarshalIndent(rtRepr, "", "\t")
|
newJSON, err := json.MarshalIndent(rtRepr, "", "\t")
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
err = ioutil.WriteFile(expectedJSON, newJSON, 0o644)
|
err = os.WriteFile(expectedJSON, newJSON, 0o644)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
c.Errorf("We do not want a passing test in file update mode")
|
c.Errorf("We do not want a passing test in file update mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchesConfig(wantConfig string, buf *bytes.Buffer) try.ResponseCondition {
|
func matchesConfig(wantConfig string, buf *bytes.Buffer) try.ResponseCondition {
|
||||||
return func(res *http.Response) error {
|
return func(res *http.Response) error {
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read response body: %w", err)
|
return fmt.Errorf("failed to read response body: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -198,7 +197,7 @@ func matchesConfig(wantConfig string, buf *bytes.Buffer) try.ResponseCondition {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
expected, err := ioutil.ReadFile(wantConfig)
|
expected, err := os.ReadFile(wantConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -130,14 +129,14 @@ func (s *LogRotationSuite) TestTraefikLogRotation(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func logAccessLogFile(c *check.C, fileName string) {
|
func logAccessLogFile(c *check.C, fileName string) {
|
||||||
output, err := ioutil.ReadFile(fileName)
|
output, err := os.ReadFile(fileName)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
c.Logf("Contents of file %s\n%s", fileName, string(output))
|
c.Logf("Contents of file %s\n%s", fileName, string(output))
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyEmptyErrorLog(c *check.C, name string) {
|
func verifyEmptyErrorLog(c *check.C, name string) {
|
||||||
err := try.Do(5*time.Second, func() error {
|
err := try.Do(5*time.Second, func() error {
|
||||||
traefikLog, e2 := ioutil.ReadFile(name)
|
traefikLog, e2 := os.ReadFile(name)
|
||||||
if e2 != nil {
|
if e2 != nil {
|
||||||
return e2
|
return e2
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package integration
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -138,11 +137,11 @@ func (s *RedisSuite) TestSimpleConfiguration(c *check.C) {
|
||||||
expectedJSON := filepath.FromSlash("testdata/rawdata-redis.json")
|
expectedJSON := filepath.FromSlash("testdata/rawdata-redis.json")
|
||||||
|
|
||||||
if *updateExpected {
|
if *updateExpected {
|
||||||
err = ioutil.WriteFile(expectedJSON, got, 0o666)
|
err = os.WriteFile(expectedJSON, got, 0o666)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected, err := ioutil.ReadFile(expectedJSON)
|
expected, err := os.ReadFile(expectedJSON)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
if !bytes.Equal(expected, got) {
|
if !bytes.Equal(expected, got) {
|
||||||
|
|
|
@ -203,10 +203,10 @@ func (s *RestSuite) TestSimpleConfiguration(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range testCase {
|
for _, test := range testCase {
|
||||||
json, err := json.Marshal(test.config)
|
data, err := json.Marshal(test.config)
|
||||||
c.Assert(err, checker.IsNil)
|
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)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
response, err := http.DefaultClient.Do(request)
|
response, err := http.DefaultClient.Do(request)
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
|
@ -688,7 +688,7 @@ func (s *SimpleSuite) TestWRR(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
c.Assert(response.StatusCode, checker.Equals, http.StatusOK)
|
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)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
if strings.Contains(string(body), server1) {
|
if strings.Contains(string(body), server1) {
|
||||||
|
@ -739,7 +739,7 @@ func (s *SimpleSuite) TestWRRSticky(c *check.C) {
|
||||||
req.AddCookie(cookie)
|
req.AddCookie(cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(response.Body)
|
body, err := io.ReadAll(response.Body)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
if strings.Contains(string(body), server1) {
|
if strings.Contains(string(body), server1) {
|
||||||
|
@ -819,7 +819,7 @@ func (s *SimpleSuite) TestMirrorWithBody(c *check.C) {
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
verifyBody := func(req *http.Request) {
|
verifyBody := func(req *http.Request) {
|
||||||
b, _ := ioutil.ReadAll(req.Body)
|
b, _ := io.ReadAll(req.Body)
|
||||||
switch req.Header.Get("Size") {
|
switch req.Header.Get("Size") {
|
||||||
case "20":
|
case "20":
|
||||||
if !bytes.Equal(b, body20) {
|
if !bytes.Equal(b, body20) {
|
||||||
|
@ -1030,7 +1030,7 @@ func (s *SimpleSuite) TestContentTypeDisableAutoDetect(c *check.C) {
|
||||||
|
|
||||||
rw.WriteHeader(http.StatusOK)
|
rw.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
data, err := ioutil.ReadFile("fixtures/test.pdf")
|
data, err := os.ReadFile("fixtures/test.pdf")
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
_, err = rw.Write(data)
|
_, err = rw.Write(data)
|
||||||
|
|
|
@ -2,7 +2,6 @@ package integration
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
@ -26,11 +25,11 @@ func (s *TLSClientHeadersSuite) SetUpSuite(c *check.C) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *TLSClientHeadersSuite) TestTLSClientHeaders(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)
|
c.Assert(err, check.IsNil)
|
||||||
serverCertContent, err := ioutil.ReadFile(certPemPath)
|
serverCertContent, err := os.ReadFile(certPemPath)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
ServerKeyContent, err := ioutil.ReadFile(certKeyPath)
|
ServerKeyContent, err := os.ReadFile(certKeyPath)
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
|
|
||||||
file := s.adaptFile(c, "fixtures/tlsclientheaders/simple.toml", struct {
|
file := s.adaptFile(c, "fixtures/tlsclientheaders/simple.toml", struct {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package try
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"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.
|
// The condition returns an error if the request body does not contain all the given strings.
|
||||||
func BodyContains(values ...string) ResponseCondition {
|
func BodyContains(values ...string) ResponseCondition {
|
||||||
return func(res *http.Response) error {
|
return func(res *http.Response) error {
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read response body: %w", err)
|
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.
|
// The condition returns an error if the request body contain one of the given strings.
|
||||||
func BodyNotContains(values ...string) ResponseCondition {
|
func BodyNotContains(values ...string) ResponseCondition {
|
||||||
return func(res *http.Response) error {
|
return func(res *http.Response) error {
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read response body: %w", err)
|
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.
|
// The condition returns an error if the request body does not contain one of the given strings.
|
||||||
func BodyContainsOr(values ...string) ResponseCondition {
|
func BodyContainsOr(values ...string) ResponseCondition {
|
||||||
return func(res *http.Response) error {
|
return func(res *http.Response) error {
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read response body: %w", err)
|
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.
|
// The condition returns an error if the request body does not have body content.
|
||||||
func HasBody() ResponseCondition {
|
func HasBody() ResponseCondition {
|
||||||
return func(res *http.Response) error {
|
return func(res *http.Response) error {
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read response body: %w", err)
|
return fmt.Errorf("failed to read response body: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ func Do(timeout time.Duration, operation DoCondition) error {
|
||||||
fmt.Print("*")
|
fmt.Print("*")
|
||||||
if err = operation(); err == nil {
|
if err = operation(); err == nil {
|
||||||
fmt.Println("+")
|
fmt.Println("+")
|
||||||
return err
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
@ -279,7 +278,7 @@ func (s *WebsocketSuite) TestSSLTermination(c *check.C) {
|
||||||
|
|
||||||
// Add client self-signed cert
|
// Add client self-signed cert
|
||||||
roots := x509.NewCertPool()
|
roots := x509.NewCertPool()
|
||||||
certContent, err := ioutil.ReadFile("./resources/tls/local.cert")
|
certContent, err := os.ReadFile("./resources/tls/local.cert")
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
roots.AppendCertsFromPEM(certContent)
|
roots.AppendCertsFromPEM(certContent)
|
||||||
gorillawebsocket.DefaultDialer.TLSClientConfig = &tls.Config{
|
gorillawebsocket.DefaultDialer.TLSClientConfig = &tls.Config{
|
||||||
|
@ -461,8 +460,7 @@ func (s *WebsocketSuite) TestSSLhttp2(c *check.C) {
|
||||||
}))
|
}))
|
||||||
|
|
||||||
ts.TLS = &tls.Config{}
|
ts.TLS = &tls.Config{}
|
||||||
ts.TLS.NextProtos = append(ts.TLS.NextProtos, `h2`)
|
ts.TLS.NextProtos = append(ts.TLS.NextProtos, `h2`, `http/1.1`)
|
||||||
ts.TLS.NextProtos = append(ts.TLS.NextProtos, `http/1.1`)
|
|
||||||
ts.StartTLS()
|
ts.StartTLS()
|
||||||
|
|
||||||
file := s.adaptFile(c, "fixtures/websocket/config_https.toml", struct {
|
file := s.adaptFile(c, "fixtures/websocket/config_https.toml", struct {
|
||||||
|
@ -485,7 +483,7 @@ func (s *WebsocketSuite) TestSSLhttp2(c *check.C) {
|
||||||
|
|
||||||
// Add client self-signed cert
|
// Add client self-signed cert
|
||||||
roots := x509.NewCertPool()
|
roots := x509.NewCertPool()
|
||||||
certContent, err := ioutil.ReadFile("./resources/tls/local.cert")
|
certContent, err := os.ReadFile("./resources/tls/local.cert")
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
roots.AppendCertsFromPEM(certContent)
|
roots.AppendCertsFromPEM(certContent)
|
||||||
gorillawebsocket.DefaultDialer.TLSClientConfig = &tls.Config{
|
gorillawebsocket.DefaultDialer.TLSClientConfig = &tls.Config{
|
||||||
|
|
|
@ -3,7 +3,6 @@ package integration
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -138,11 +137,11 @@ func (s *ZookeeperSuite) TestSimpleConfiguration(c *check.C) {
|
||||||
expectedJSON := filepath.FromSlash("testdata/rawdata-zk.json")
|
expectedJSON := filepath.FromSlash("testdata/rawdata-zk.json")
|
||||||
|
|
||||||
if *updateExpected {
|
if *updateExpected {
|
||||||
err = ioutil.WriteFile(expectedJSON, got, 0o666)
|
err = os.WriteFile(expectedJSON, got, 0o666)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected, err := ioutil.ReadFile(expectedJSON)
|
expected, err := os.ReadFile(expectedJSON)
|
||||||
c.Assert(err, checker.IsNil)
|
c.Assert(err, checker.IsNil)
|
||||||
|
|
||||||
if !bytes.Equal(expected, got) {
|
if !bytes.Equal(expected, got) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"github.com/traefik/paerser/flag"
|
"github.com/traefik/paerser/flag"
|
||||||
"github.com/traefik/paerser/generator"
|
"github.com/traefik/paerser/generator"
|
||||||
"github.com/traefik/paerser/parser"
|
"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"
|
"github.com/traefik/traefik/v2/pkg/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ func main() {
|
||||||
func genStaticConfDoc(outputFile, prefix string, encodeFn func(interface{}) ([]parser.Flat, error)) {
|
func genStaticConfDoc(outputFile, prefix string, encodeFn func(interface{}) ([]parser.Flat, error)) {
|
||||||
logger := log.WithoutContext().WithField("file", outputFile)
|
logger := log.WithoutContext().WithField("file", outputFile)
|
||||||
|
|
||||||
element := &static.Configuration{}
|
element := &cmd.NewTraefikConfiguration().Configuration
|
||||||
|
|
||||||
generator.Generate(element)
|
generator.Generate(element)
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ func Do(baseConfig interface{}, indent bool) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func doOnJSON(input string) string {
|
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)
|
return xurls.Relaxed().ReplaceAllString(mailExp.ReplaceAllString(input, maskLarge+"\""), maskLarge)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package anonymize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
cleanJSON, err := Do(config, true)
|
cleanJSON, err := Do(config, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
if *updateExpected {
|
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")
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
cleanJSON, err := Do(config, true)
|
cleanJSON, err := Do(config, true)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
if *updateExpected {
|
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")
|
expected := strings.TrimSuffix(string(expectedConfiguration), "\n")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package anonymize
|
package anonymize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -9,12 +9,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_doOnJSON(t *testing.T) {
|
func Test_doOnJSON(t *testing.T) {
|
||||||
baseConfiguration, err := ioutil.ReadFile("./testdata/example.json")
|
baseConfiguration, err := os.ReadFile("./testdata/example.json")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
anomConfiguration := doOnJSON(string(baseConfiguration))
|
anomConfiguration := doOnJSON(string(baseConfiguration))
|
||||||
|
|
||||||
expectedConfiguration, err := ioutil.ReadFile("./testdata/expected.json")
|
expectedConfiguration, err := os.ReadFile("./testdata/expected.json")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.JSONEq(t, string(expectedConfiguration), anomConfiguration)
|
assert.JSONEq(t, string(expectedConfiguration), anomConfiguration)
|
||||||
|
|
|
@ -3,9 +3,10 @@ package api
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ func TestHandler_EntryPoints(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, resp.Header.Get("Content-Type"), "application/json")
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
|
@ -226,11 +227,11 @@ func TestHandler_EntryPoints(t *testing.T) {
|
||||||
newJSON, err := json.MarshalIndent(results, "", "\t")
|
newJSON, err := json.MarshalIndent(results, "", "\t")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0o644)
|
err = os.WriteFile(test.expected.jsonFile, newJSON, 0o644)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(test.expected.jsonFile)
|
data, err := os.ReadFile(test.expected.jsonFile)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.JSONEq(t, string(data), string(contents))
|
assert.JSONEq(t, string(data), string(contents))
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,9 +4,10 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -826,7 +827,7 @@ func TestHandler_HTTP(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, resp.Header.Get("Content-Type"), "application/json")
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
|
@ -840,11 +841,11 @@ func TestHandler_HTTP(t *testing.T) {
|
||||||
newJSON, err := json.MarshalIndent(results, "", "\t")
|
newJSON, err := json.MarshalIndent(results, "", "\t")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0o644)
|
err = os.WriteFile(test.expected.jsonFile, newJSON, 0o644)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(test.expected.jsonFile)
|
data, err := os.ReadFile(test.expected.jsonFile)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.JSONEq(t, string(data), string(contents))
|
assert.JSONEq(t, string(data), string(contents))
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,9 +2,10 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"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")
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
|
@ -277,11 +278,11 @@ func TestHandler_Overview(t *testing.T) {
|
||||||
newJSON, err := json.MarshalIndent(results, "", "\t")
|
newJSON, err := json.MarshalIndent(results, "", "\t")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0o644)
|
err = os.WriteFile(test.expected.jsonFile, newJSON, 0o644)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(test.expected.jsonFile)
|
data, err := os.ReadFile(test.expected.jsonFile)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.JSONEq(t, string(data), string(contents))
|
assert.JSONEq(t, string(data), string(contents))
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,9 +3,10 @@ package api
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"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")
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
|
@ -548,11 +549,11 @@ func TestHandler_TCP(t *testing.T) {
|
||||||
newJSON, err := json.MarshalIndent(results, "", "\t")
|
newJSON, err := json.MarshalIndent(results, "", "\t")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0o644)
|
err = os.WriteFile(test.expected.jsonFile, newJSON, 0o644)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(test.expected.jsonFile)
|
data, err := os.ReadFile(test.expected.jsonFile)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.JSONEq(t, string(data), string(contents))
|
assert.JSONEq(t, string(data), string(contents))
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,9 +3,10 @@ package api
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"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, test.expected.statusCode, resp.StatusCode)
|
||||||
assert.Equal(t, resp.Header.Get("Content-Type"), "application/json")
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
|
@ -161,11 +162,11 @@ func TestHandler_RawData(t *testing.T) {
|
||||||
newJSON, err := json.MarshalIndent(rtRepr, "", "\t")
|
newJSON, err := json.MarshalIndent(rtRepr, "", "\t")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(test.expected.json, newJSON, 0o644)
|
err = os.WriteFile(test.expected.json, newJSON, 0o644)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(test.expected.json)
|
data, err := os.ReadFile(test.expected.json)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.JSONEq(t, string(data), string(contents))
|
assert.JSONEq(t, string(data), string(contents))
|
||||||
})
|
})
|
||||||
|
@ -267,7 +268,7 @@ func TestHandler_GetMiddleware(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
data, err := io.ReadAll(resp.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
|
|
|
@ -3,9 +3,10 @@ package api
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"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")
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
|
@ -525,11 +526,11 @@ func TestHandler_UDP(t *testing.T) {
|
||||||
newJSON, err := json.MarshalIndent(results, "", "\t")
|
newJSON, err := json.MarshalIndent(results, "", "\t")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0o644)
|
err = os.WriteFile(test.expected.jsonFile, newJSON, 0o644)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadFile(test.expected.jsonFile)
|
data, err := os.ReadFile(test.expected.jsonFile)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.JSONEq(t, string(data), string(contents))
|
assert.JSONEq(t, string(data), string(contents))
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -56,7 +55,7 @@ func (f *FileLoader) Load(args []string, cmd *cli.Command) (bool, error) {
|
||||||
logger := log.WithoutContext()
|
logger := log.WithoutContext()
|
||||||
logger.Printf("Configuration loaded from file: %s", configFile)
|
logger.Printf("Configuration loaded from file: %s", configFile)
|
||||||
|
|
||||||
content, _ := ioutil.ReadFile(configFile)
|
content, _ := os.ReadFile(configFile)
|
||||||
logger.Debug(string(content))
|
logger.Debug(string(content))
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
@ -79,7 +78,7 @@ func loadConfigFiles(configFile string, element interface{}) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = file.Decode(filePath, element); err != nil {
|
if err := file.Decode(filePath, element); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return filePath, nil
|
return filePath, nil
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -446,7 +445,7 @@ func (c *ClientTLS) CreateTLSConfig() (*tls.Config, error) {
|
||||||
if c.CA != "" {
|
if c.CA != "" {
|
||||||
var ca []byte
|
var ca []byte
|
||||||
if _, errCA := os.Stat(c.CA); errCA == nil {
|
if _, errCA := os.Stat(c.CA); errCA == nil {
|
||||||
ca, err = ioutil.ReadFile(c.CA)
|
ca, err = os.ReadFile(c.CA)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read CA. %w", err)
|
return nil, fmt.Errorf("failed to read CA. %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,21 @@ func TestJobBackOff(t *testing.T) {
|
||||||
exp.MinJobInterval = testMinJobInterval
|
exp.MinJobInterval = testMinJobInterval
|
||||||
exp.Reset()
|
exp.Reset()
|
||||||
|
|
||||||
expectedResults := []time.Duration{500, 500, 500, 1000, 2000, 4000, 5000, 5000, 500, 1000, 2000, 4000, 5000, 5000}
|
expectedResults := []time.Duration{
|
||||||
for i, d := range expectedResults {
|
500 * time.Millisecond,
|
||||||
expectedResults[i] = d * 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 {
|
for i, expected := range expectedResults {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package metrics
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -79,7 +79,7 @@ func TestInfluxDB(t *testing.T) {
|
||||||
func TestInfluxDBHTTP(t *testing.T) {
|
func TestInfluxDBHTTP(t *testing.T) {
|
||||||
c := make(chan *string)
|
c := make(chan *string)
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
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 {
|
if err != nil {
|
||||||
http.Error(w, "can't read body "+err.Error(), http.StatusBadRequest)
|
http.Error(w, "can't read body "+err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
|
|
@ -30,7 +30,7 @@ func TestScalableHistogram(t *testing.T) {
|
||||||
measuredDuration, err := time.ParseDuration(extractedDurationString[0] + "ms")
|
measuredDuration, err := time.ParseDuration(extractedDurationString[0] + "ms")
|
||||||
assert.NoError(t, err)
|
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) {
|
func TestNewMultiRegistry(t *testing.T) {
|
||||||
|
|
|
@ -402,7 +402,7 @@ func newCollector(metricName string, labels stdprometheus.Labels, c stdprometheu
|
||||||
|
|
||||||
// collector wraps a Collector object from the Prometheus client library.
|
// collector wraps a Collector object from the Prometheus client library.
|
||||||
// It adds information on how many generations this metric should be present
|
// 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 {
|
type collector struct {
|
||||||
id string
|
id string
|
||||||
labels stdprometheus.Labels
|
labels stdprometheus.Labels
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -42,9 +41,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLogRotation(t *testing.T) {
|
func TestLogRotation(t *testing.T) {
|
||||||
tempDir := createTempDir(t, "traefik_")
|
fileName := filepath.Join(t.TempDir(), "traefik.log")
|
||||||
|
|
||||||
fileName := filepath.Join(tempDir, "traefik.log")
|
|
||||||
rotatedFileName := fileName + ".rotated"
|
rotatedFileName := fileName + ".rotated"
|
||||||
|
|
||||||
config := &types.AccessLog{FilePath: fileName, Format: CommonFormat}
|
config := &types.AccessLog{FilePath: fileName, Format: CommonFormat}
|
||||||
|
@ -100,7 +97,7 @@ func TestLogRotation(t *testing.T) {
|
||||||
|
|
||||||
func lineCount(t *testing.T, fileName string) int {
|
func lineCount(t *testing.T, fileName string) int {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
fileContents, err := ioutil.ReadFile(fileName)
|
fileContents, err := os.ReadFile(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error reading from file %s: %s", fileName, err)
|
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) {
|
func TestLoggerHeaderFields(t *testing.T) {
|
||||||
tmpDir := createTempDir(t, CommonFormat)
|
|
||||||
|
|
||||||
expectedValue := "expectedValue"
|
expectedValue := "expectedValue"
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
@ -172,7 +167,7 @@ func TestLoggerHeaderFields(t *testing.T) {
|
||||||
for _, test := range testCases {
|
for _, test := range testCases {
|
||||||
test := test
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
config := &types.AccessLog{
|
config := &types.AccessLog{
|
||||||
|
@ -202,7 +197,7 @@ func TestLoggerHeaderFields(t *testing.T) {
|
||||||
writer.WriteHeader(http.StatusOK)
|
writer.WriteHeader(http.StatusOK)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
logData, err := ioutil.ReadFile(logFile.Name())
|
logData, err := os.ReadFile(logFile.Name())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
if test.expected == types.AccessLogDrop {
|
if test.expected == types.AccessLogDrop {
|
||||||
|
@ -215,13 +210,11 @@ func TestLoggerHeaderFields(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoggerCLF(t *testing.T) {
|
func TestLoggerCLF(t *testing.T) {
|
||||||
tmpDir := createTempDir(t, CommonFormat)
|
logFilePath := filepath.Join(t.TempDir(), logFileNameSuffix)
|
||||||
|
|
||||||
logFilePath := filepath.Join(tmpDir, logFileNameSuffix)
|
|
||||||
config := &types.AccessLog{FilePath: logFilePath, Format: CommonFormat}
|
config := &types.AccessLog{FilePath: logFilePath, Format: CommonFormat}
|
||||||
doLogging(t, config)
|
doLogging(t, config)
|
||||||
|
|
||||||
logData, err := ioutil.ReadFile(logFilePath)
|
logData, err := os.ReadFile(logFilePath)
|
||||||
require.NoError(t, err)
|
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`
|
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) {
|
func TestAsyncLoggerCLF(t *testing.T) {
|
||||||
tmpDir := createTempDir(t, CommonFormat)
|
logFilePath := filepath.Join(t.TempDir(), logFileNameSuffix)
|
||||||
|
|
||||||
logFilePath := filepath.Join(tmpDir, logFileNameSuffix)
|
|
||||||
config := &types.AccessLog{FilePath: logFilePath, Format: CommonFormat, BufferingSize: 1024}
|
config := &types.AccessLog{FilePath: logFilePath, Format: CommonFormat, BufferingSize: 1024}
|
||||||
doLogging(t, config)
|
doLogging(t, config)
|
||||||
|
|
||||||
logData, err := ioutil.ReadFile(logFilePath)
|
logData, err := os.ReadFile(logFilePath)
|
||||||
require.NoError(t, err)
|
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`
|
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`
|
||||||
|
@ -452,9 +443,7 @@ func TestLoggerJSON(t *testing.T) {
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tmpDir := createTempDir(t, JSONFormat)
|
logFilePath := filepath.Join(t.TempDir(), logFileNameSuffix)
|
||||||
|
|
||||||
logFilePath := filepath.Join(tmpDir, logFileNameSuffix)
|
|
||||||
|
|
||||||
test.config.FilePath = logFilePath
|
test.config.FilePath = logFilePath
|
||||||
if test.tls {
|
if test.tls {
|
||||||
|
@ -463,7 +452,7 @@ func TestLoggerJSON(t *testing.T) {
|
||||||
doLogging(t, test.config)
|
doLogging(t, test.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
logData, err := ioutil.ReadFile(logFilePath)
|
logData, err := os.ReadFile(logFilePath)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
jsonData := make(map[string]interface{})
|
jsonData := make(map[string]interface{})
|
||||||
|
@ -677,7 +666,7 @@ func TestNewLogHandlerOutputStdout(t *testing.T) {
|
||||||
|
|
||||||
doLogging(t, test.config)
|
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")
|
require.NoError(t, err, "unable to read captured stdout from file")
|
||||||
assertValidLogData(t, test.expectedLog, written)
|
assertValidLogData(t, test.expectedLog, written)
|
||||||
})
|
})
|
||||||
|
@ -713,16 +702,16 @@ func assertValidLogData(t *testing.T, expected string, logData []byte) {
|
||||||
assert.Equal(t, resultExpected[OriginContentSize], result[OriginContentSize], formatErrMessage)
|
assert.Equal(t, resultExpected[OriginContentSize], result[OriginContentSize], formatErrMessage)
|
||||||
assert.Equal(t, resultExpected[RequestRefererHeader], result[RequestRefererHeader], formatErrMessage)
|
assert.Equal(t, resultExpected[RequestRefererHeader], result[RequestRefererHeader], formatErrMessage)
|
||||||
assert.Equal(t, resultExpected[RequestUserAgentHeader], result[RequestUserAgentHeader], 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[RouterName], result[RouterName], formatErrMessage)
|
||||||
assert.Equal(t, resultExpected[ServiceURL], result[ServiceURL], 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()) {
|
func captureStdout(t *testing.T) (out *os.File, restoreStdout func()) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
file, err := ioutil.TempFile("", "testlogger")
|
file, err := os.CreateTemp("", "testlogger")
|
||||||
require.NoError(t, err, "failed to create temp file")
|
require.NoError(t, err, "failed to create temp file")
|
||||||
|
|
||||||
original := os.Stdout
|
original := os.Stdout
|
||||||
|
@ -736,17 +725,6 @@ func captureStdout(t *testing.T) (out *os.File, restoreStdout func()) {
|
||||||
return file, restoreStdout
|
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) {
|
func doLoggingTLSOpt(t *testing.T, config *types.AccessLog, enableTLS bool) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ func loadUsers(fileName string, appendUsers []string) ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLinesFromFile(filename string) ([]string, error) {
|
func getLinesFromFile(filename string) ([]string, error) {
|
||||||
dat, err := ioutil.ReadFile(filename)
|
dat, err := os.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package auth
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
|
@ -66,7 +66,7 @@ func TestBasicAuthSuccess(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, res.StatusCode, "they should be equal")
|
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)
|
require.NoError(t, err)
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ func TestBasicAuthUserHeader(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, res.StatusCode)
|
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ func TestBasicAuthHeaderRemoved(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, res.StatusCode)
|
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = res.Body.Close()
|
err = res.Body.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -159,7 +159,7 @@ func TestBasicAuthHeaderPresent(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, http.StatusOK, res.StatusCode)
|
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = res.Body.Close()
|
err = res.Body.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -215,9 +215,8 @@ func TestBasicAuthUsersFromFile(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Creates the temporary configuration file with the users
|
// 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)
|
require.NoError(t, err)
|
||||||
defer os.Remove(usersFile.Name())
|
|
||||||
|
|
||||||
_, err = usersFile.Write([]byte(test.userFileContent))
|
_, err = usersFile.Write([]byte(test.userFileContent))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -250,7 +249,7 @@ func TestBasicAuthUsersFromFile(t *testing.T) {
|
||||||
require.Equal(t, http.StatusOK, res.StatusCode, "Cannot authenticate user "+userName)
|
require.Equal(t, http.StatusOK, res.StatusCode, "Cannot authenticate user "+userName)
|
||||||
|
|
||||||
var body []byte
|
var body []byte
|
||||||
body, err = ioutil.ReadAll(res.Body)
|
body, err = io.ReadAll(res.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = res.Body.Close()
|
err = res.Body.Close()
|
||||||
require.NoError(t, err)
|
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"))
|
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)
|
require.NoError(t, err)
|
||||||
err = res.Body.Close()
|
err = res.Body.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -3,7 +3,7 @@ package auth
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
|
@ -93,9 +93,8 @@ func TestDigestAuthUsersFromFile(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Creates the temporary configuration file with the users
|
// 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)
|
require.NoError(t, err)
|
||||||
defer os.Remove(usersFile.Name())
|
|
||||||
|
|
||||||
_, err = usersFile.Write([]byte(test.userFileContent))
|
_, err = usersFile.Write([]byte(test.userFileContent))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -127,7 +126,7 @@ func TestDigestAuthUsersFromFile(t *testing.T) {
|
||||||
require.Equal(t, http.StatusOK, res.StatusCode, "Cannot authenticate user "+userName)
|
require.Equal(t, http.StatusOK, res.StatusCode, "Cannot authenticate user "+userName)
|
||||||
|
|
||||||
var body []byte
|
var body []byte
|
||||||
body, err = ioutil.ReadAll(res.Body)
|
body, err = io.ReadAll(res.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = res.Body.Close()
|
err = res.Body.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -145,7 +144,7 @@ func TestDigestAuthUsersFromFile(t *testing.T) {
|
||||||
require.Equal(t, http.StatusUnauthorized, res.StatusCode)
|
require.Equal(t, http.StatusUnauthorized, res.StatusCode)
|
||||||
|
|
||||||
var body []byte
|
var body []byte
|
||||||
body, err = ioutil.ReadAll(res.Body)
|
body, err = io.ReadAll(res.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = res.Body.Close()
|
err = res.Body.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -126,7 +126,7 @@ func (fa *forwardAuth) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
body, readError := ioutil.ReadAll(forwardResponse.Body)
|
body, readError := io.ReadAll(forwardResponse.Body)
|
||||||
if readError != nil {
|
if readError != nil {
|
||||||
logMessage := fmt.Sprintf("Error reading body %s. Cause: %s", fa.address, readError)
|
logMessage := fmt.Sprintf("Error reading body %s. Cause: %s", fa.address, readError)
|
||||||
logger.Debug(logMessage)
|
logger.Debug(logMessage)
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -44,7 +43,7 @@ func TestForwardAuthFail(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, http.StatusForbidden, res.StatusCode)
|
assert.Equal(t, http.StatusForbidden, res.StatusCode)
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = res.Body.Close()
|
err = res.Body.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -92,7 +91,7 @@ func TestForwardAuthSuccess(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, http.StatusOK, res.StatusCode)
|
assert.Equal(t, http.StatusOK, res.StatusCode)
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = res.Body.Close()
|
err = res.Body.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -134,7 +133,7 @@ func TestForwardAuthRedirect(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "http://example.com/redirect-test", location.String())
|
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)
|
require.NoError(t, err)
|
||||||
err = res.Body.Close()
|
err = res.Body.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -187,7 +186,7 @@ func TestForwardAuthRemoveHopByHopHeaders(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, "http://example.com/redirect-test", location.String(), "they should be equal")
|
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)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, string(body), "there should be something in the body")
|
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])
|
assert.Equal(t, value, res.Header[key])
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
body, err := io.ReadAll(res.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = res.Body.Close()
|
err = res.Body.Close()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -489,5 +488,5 @@ type mockBackend struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *mockBackend) Setup(componentName string) (opentracing.Tracer, io.Closer, error) {
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package compress
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -205,7 +205,7 @@ func TestIntegrationShouldNotCompress(t *testing.T) {
|
||||||
assert.Equal(t, gzipValue, resp.Header.Get(contentEncodingHeader))
|
assert.Equal(t, gzipValue, resp.Header.Get(contentEncodingHeader))
|
||||||
assert.Equal(t, acceptEncodingHeader, resp.Header.Get(varyHeader))
|
assert.Equal(t, acceptEncodingHeader, resp.Header.Get(varyHeader))
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.EqualValues(t, fakeCompressedBody, body)
|
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, gzipValue, resp.Header.Get(contentEncodingHeader))
|
||||||
assert.Equal(t, acceptEncodingHeader, resp.Header.Get(varyHeader))
|
assert.Equal(t, acceptEncodingHeader, resp.Header.Get(varyHeader))
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
if assert.ObjectsAreEqualValues(body, fakeBody) {
|
if assert.ObjectsAreEqualValues(body, fakeBody) {
|
||||||
assert.Fail(t, "expected a compressed body", "got %v", body)
|
assert.Fail(t, "expected a compressed body", "got %v", body)
|
||||||
|
|
|
@ -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
|
// check the recorder code against the configured http status code ranges
|
||||||
code := catcher.getCode()
|
code := catcher.getCode()
|
||||||
for _, block := range c.httpCodeRanges {
|
for _, block := range c.httpCodeRanges {
|
||||||
if code >= block[0] && code <= block[1] {
|
if code < block[0] || code > block[1] {
|
||||||
logger.Debugf("Caught HTTP Status Code %d, returning error page", code)
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
var query string
|
logger.Debugf("Caught HTTP Status Code %d, returning error page", code)
|
||||||
if len(c.backendQuery) > 0 {
|
|
||||||
query = "/" + strings.TrimPrefix(c.backendQuery, "/")
|
|
||||||
query = strings.ReplaceAll(query, "{status}", strconv.Itoa(code))
|
|
||||||
}
|
|
||||||
|
|
||||||
pageReq, err := newRequest(backendURL + query)
|
var query string
|
||||||
if err != nil {
|
if len(c.backendQuery) > 0 {
|
||||||
logger.Error(err)
|
query = "/" + strings.TrimPrefix(c.backendQuery, "/")
|
||||||
rw.WriteHeader(code)
|
query = strings.ReplaceAll(query, "{status}", strconv.Itoa(code))
|
||||||
_, err = fmt.Fprint(rw, http.StatusText(code))
|
}
|
||||||
if err != nil {
|
|
||||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
recorderErrorPage := newResponseRecorder(ctx, rw)
|
pageReq, err := newRequest(backendURL + query)
|
||||||
utils.CopyHeaders(pageReq.Header, req.Header)
|
if err != nil {
|
||||||
|
logger.Error(err)
|
||||||
c.backendHandler.ServeHTTP(recorderErrorPage, pageReq.WithContext(req.Context()))
|
|
||||||
|
|
||||||
utils.CopyHeaders(rw.Header(), recorderErrorPage.Header())
|
|
||||||
rw.WriteHeader(code)
|
rw.WriteHeader(code)
|
||||||
|
_, err = fmt.Fprint(rw, http.StatusText(code))
|
||||||
if _, err = rw.Write(recorderErrorPage.GetBody().Bytes()); err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
return
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -279,10 +280,12 @@ func TestRateLimit(t *testing.T) {
|
||||||
// actual default value
|
// actual default value
|
||||||
burst = 1
|
burst = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
period := time.Duration(test.config.Period)
|
period := time.Duration(test.config.Period)
|
||||||
if period == 0 {
|
if period == 0 {
|
||||||
period = time.Second
|
period = time.Second
|
||||||
}
|
}
|
||||||
|
|
||||||
if test.config.Average == 0 {
|
if test.config.Average == 0 {
|
||||||
if reqCount < 75*test.incomingLoad/100 {
|
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)
|
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,
|
// we take into account the configured burst,
|
||||||
// because it also helps absorbing non-bursty traffic.
|
// because it also helps absorbing non-bursty traffic.
|
||||||
rate := float64(test.config.Average) / float64(period)
|
rate := float64(test.config.Average) / float64(period)
|
||||||
|
|
||||||
wantCount := int(int64(rate*float64(test.loadDuration)) + burst)
|
wantCount := int(int64(rate*float64(test.loadDuration)) + burst)
|
||||||
|
|
||||||
// Allow for a 2% leeway
|
// Allow for a 2% leeway
|
||||||
maxCount := wantCount * 102 / 100
|
maxCount := wantCount * 102 / 100
|
||||||
|
|
||||||
// With very high CPU loads,
|
// With very high CPU loads,
|
||||||
// we can expect some extra delay in addition to the rate limiting we already do,
|
// we can expect some extra delay in addition to the rate limiting we already do,
|
||||||
// so we allow for some extra leeway there.
|
// so we allow for some extra leeway there.
|
||||||
// Feel free to adjust wrt to the load on e.g. the CI.
|
// Feel free to adjust wrt to the load on e.g. the CI.
|
||||||
minCount := wantCount * 95 / 100
|
minCount := computeMinCount(wantCount)
|
||||||
|
|
||||||
if reqCount < minCount {
|
if reqCount < minCount {
|
||||||
t.Fatalf("rate was slower than expected: %d requests (wanted > %d) in %v", reqCount, minCount, elapsed)
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -73,12 +73,12 @@ func (r *retry) GetTracingInformation() (string, ext.SpanKindEnum) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *retry) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
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
|
// cf https://github.com/traefik/traefik/issues/1008
|
||||||
if r.attempts > 1 {
|
if r.attempts > 1 {
|
||||||
body := req.Body
|
body := req.Body
|
||||||
defer body.Close()
|
defer body.Close()
|
||||||
req.Body = ioutil.NopCloser(body)
|
req.Body = io.NopCloser(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
attempts := 1
|
attempts := 1
|
||||||
|
|
|
@ -3,10 +3,10 @@ package retry
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/http/httptrace"
|
"net/http/httptrace"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -16,10 +16,7 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
ptypes "github.com/traefik/paerser/types"
|
ptypes "github.com/traefik/paerser/types"
|
||||||
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
"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/traefik/traefik/v2/pkg/testhelpers"
|
||||||
"github.com/vulcand/oxy/forward"
|
|
||||||
"github.com/vulcand/oxy/roundrobin"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRetry(t *testing.T) {
|
func TestRetry(t *testing.T) {
|
||||||
|
@ -32,14 +29,14 @@ func TestRetry(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
desc: "no retry on success",
|
desc: "no retry on success",
|
||||||
config: dynamic.Retry{Attempts: 1},
|
config: dynamic.Retry{Attempts: 5},
|
||||||
wantRetryAttempts: 0,
|
wantRetryAttempts: 0,
|
||||||
wantResponseStatus: http.StatusOK,
|
wantResponseStatus: http.StatusOK,
|
||||||
amountFaultyEndpoints: 0,
|
amountFaultyEndpoints: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
desc: "no retry on success with backoff",
|
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,
|
wantRetryAttempts: 0,
|
||||||
wantResponseStatus: http.StatusOK,
|
wantResponseStatus: http.StatusOK,
|
||||||
amountFaultyEndpoints: 0,
|
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 {
|
for _, test := range testCases {
|
||||||
test := test
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
loadBalancer, err := roundrobin.New(forwarder)
|
retryAttemps := 0
|
||||||
require.NoError(t, err)
|
next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
retryAttemps++
|
||||||
|
|
||||||
// out of range port
|
if retryAttemps > test.amountFaultyEndpoints {
|
||||||
basePort := 1133444
|
// calls WroteHeaders on httptrace.
|
||||||
for i := 0; i < test.amountFaultyEndpoints; i++ {
|
_ = r.Write(io.Discard)
|
||||||
// 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the functioning server to the end of the load balancer list
|
rw.WriteHeader(http.StatusOK)
|
||||||
err = loadBalancer.UpsertServer(testhelpers.MustParseURL(backendServer.URL))
|
return
|
||||||
require.NoError(t, err)
|
}
|
||||||
|
|
||||||
|
rw.WriteHeader(http.StatusBadGateway)
|
||||||
|
})
|
||||||
|
|
||||||
retryListener := &countingRetryListener{}
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
recorder := httptest.NewRecorder()
|
recorder := httptest.NewRecorder()
|
||||||
|
@ -152,15 +135,9 @@ func TestRetry(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRetryEmptyServerList(t *testing.T) {
|
func TestRetryEmptyServerList(t *testing.T) {
|
||||||
forwarder, err := forward.New()
|
next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
require.NoError(t, err)
|
rw.WriteHeader(http.StatusServiceUnavailable)
|
||||||
|
})
|
||||||
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)
|
|
||||||
|
|
||||||
retryListener := &countingRetryListener{}
|
retryListener := &countingRetryListener{}
|
||||||
retry, err := New(context.Background(), next, dynamic.Retry{Attempts: 3}, retryListener, "traefikTest")
|
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 {
|
for _, test := range testCases {
|
||||||
test := test
|
test := test
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
loadBalancer, err := roundrobin.New(forwarder)
|
retryAttemps := 0
|
||||||
if err != nil {
|
next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
t.Fatalf("Error creating load balancer: %v", err)
|
retryAttemps++
|
||||||
}
|
|
||||||
|
|
||||||
// out of range port
|
if retryAttemps > test.amountFaultyEndpoints {
|
||||||
basePort := 1133444
|
upgrader := websocket.Upgrader{}
|
||||||
for i := 0; i < test.amountFaultyEndpoints; i++ {
|
_, err := upgrader.Upgrade(rw, r, nil)
|
||||||
// 192.0.2.0 is a non-routable IP for testing purposes.
|
if err != nil {
|
||||||
// See: https://stackoverflow.com/questions/528538/non-routable-ip-address/18436928#18436928
|
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||||
// 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.
|
return
|
||||||
_ = loadBalancer.UpsertServer(testhelpers.MustParseURL("http://192.0.2.0:" + strconv.Itoa(basePort+i)))
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// add the functioning server to the end of the load balancer list
|
rw.WriteHeader(http.StatusBadGateway)
|
||||||
err = loadBalancer.UpsertServer(testhelpers.MustParseURL(backendServer.URL))
|
})
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Fail to upsert server: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
retryListener := &countingRetryListener{}
|
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)
|
require.NoError(t, err)
|
||||||
|
|
||||||
retryServer := httptest.NewServer(retryH)
|
retryServer := httptest.NewServer(retryH)
|
||||||
|
|
|
@ -27,12 +27,12 @@ func (n MockTracer) Extract(format, carrier interface{}) (opentracing.SpanContex
|
||||||
return nil, opentracing.ErrSpanContextNotFound
|
return nil, opentracing.ErrSpanContextNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
// MockSpanContext.
|
// MockSpanContext a span context mock.
|
||||||
type MockSpanContext struct{}
|
type MockSpanContext struct{}
|
||||||
|
|
||||||
func (n MockSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {}
|
func (n MockSpanContext) ForeachBaggageItem(handler func(k, v string) bool) {}
|
||||||
|
|
||||||
// MockSpan.
|
// MockSpan a span mock.
|
||||||
type MockSpan struct {
|
type MockSpan struct {
|
||||||
OpName string
|
OpName string
|
||||||
Tags map[string]interface{}
|
Tags map[string]interface{}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ func (c *client) createUUID() (string, error) {
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed read response body: %w", err)
|
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() }()
|
defer func() { _ = resp.Body.Close() }()
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read response body: %w", err)
|
return fmt.Errorf("failed to read response body: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -68,7 +67,7 @@ func NewClient(opts ClientOptions) (*Client, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
goPath, err := ioutil.TempDir(sourcesRootPath, "gop-*")
|
goPath, err := os.MkdirTemp(sourcesRootPath, "gop-*")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create GoPath: %w", err)
|
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
|
return hash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
data, _ := ioutil.ReadAll(resp.Body)
|
data, _ := io.ReadAll(resp.Body)
|
||||||
return "", fmt.Errorf("error: %d: %s", resp.StatusCode, string(data))
|
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 err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioutil.WriteFile(c.stateFile, mp, 0o600)
|
return os.WriteFile(c.stateFile, mp, 0o600)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetAll resets all plugins related directories.
|
// ResetAll resets all plugins related directories.
|
||||||
|
|
|
@ -63,27 +63,24 @@ func (c *ChallengeTLSALPN) Present(domain, _, keyAuth string) error {
|
||||||
|
|
||||||
timer := time.NewTimer(c.Timeout)
|
timer := time.NewTimer(c.Timeout)
|
||||||
|
|
||||||
var errC error
|
|
||||||
select {
|
select {
|
||||||
case t := <-timer.C:
|
case t := <-timer.C:
|
||||||
timer.Stop()
|
timer.Stop()
|
||||||
close(c.chans[string(certPEMBlock)])
|
|
||||||
|
c.muChans.Lock()
|
||||||
|
c.cleanChan(string(certPEMBlock))
|
||||||
|
c.muChans.Unlock()
|
||||||
|
|
||||||
err = c.CleanUp(domain, "", keyAuth)
|
err = c.CleanUp(domain, "", keyAuth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to clean up TLS challenge: %v", err)
|
logger.Errorf("Failed to clean up TLS challenge: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
errC = fmt.Errorf("timeout %s", t)
|
return fmt.Errorf("timeout %s", t)
|
||||||
case <-ch:
|
case <-ch:
|
||||||
// noop
|
// noop
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
c.muChans.Lock()
|
|
||||||
delete(c.chans, string(certPEMBlock))
|
|
||||||
c.muChans.Unlock()
|
|
||||||
|
|
||||||
return errC
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanUp cleans the challenges when certificate is obtained.
|
// 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.
|
// ListenConfiguration sets a new Configuration into the configurationChan.
|
||||||
func (c *ChallengeTLSALPN) ListenConfiguration(conf dynamic.Configuration) {
|
func (c *ChallengeTLSALPN) ListenConfiguration(conf dynamic.Configuration) {
|
||||||
|
c.muChans.Lock()
|
||||||
|
|
||||||
for _, certificate := range conf.TLS.Certificates {
|
for _, certificate := range conf.TLS.Certificates {
|
||||||
if !containsACMETLS1(certificate.Stores) {
|
if !containsACMETLS1(certificate.Stores) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
c.muChans.Lock()
|
c.cleanChan(certificate.CertFile.String())
|
||||||
if _, ok := c.chans[certificate.CertFile.String()]; ok {
|
}
|
||||||
close(c.chans[certificate.CertFile.String()])
|
|
||||||
}
|
c.muChans.Unlock()
|
||||||
c.muChans.Unlock()
|
}
|
||||||
|
|
||||||
|
func (c *ChallengeTLSALPN) cleanChan(key string) {
|
||||||
|
if _, ok := c.chans[key]; ok {
|
||||||
|
close(c.chans[key])
|
||||||
|
delete(c.chans, key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ package acme
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ func (s *LocalStore) get(resolverName string) (*StoredData, error) {
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
file, err := ioutil.ReadAll(f)
|
file, err := io.ReadAll(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ func (s *LocalStore) listenSaveAction() {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ioutil.WriteFile(s.filename, data, 0o600)
|
err = os.WriteFile(s.filename, data, 0o600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package acme
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -23,7 +23,7 @@ func TestLocalStore_GetAccount(t *testing.T) {
|
||||||
}
|
}
|
||||||
}`, email)
|
}`, email)
|
||||||
|
|
||||||
err := ioutil.WriteFile(acmeFile, []byte(filePayload), 0o600)
|
err := os.WriteFile(acmeFile, []byte(filePayload), 0o600)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
|
@ -68,7 +68,7 @@ func TestLocalStore_SaveAccount(t *testing.T) {
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
file, err := ioutil.ReadFile(acmeFile)
|
file, err := os.ReadFile(acmeFile)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
expected := `{
|
expected := `{
|
||||||
|
|
|
@ -119,10 +119,6 @@ func (p ProviderAggregator) Init() error {
|
||||||
|
|
||||||
// Provide calls the provide method of every providers.
|
// Provide calls the provide method of every providers.
|
||||||
func (p ProviderAggregator) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error {
|
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 {
|
if p.fileProvider != nil {
|
||||||
launchProvider(configurationChan, pool, p.fileProvider)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,11 @@ func TestProviderAggregator_Provide(t *testing.T) {
|
||||||
errCh <- aggregator.Provide(cfgCh, pool)
|
errCh <- aggregator.Provide(cfgCh, pool)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Make sure the internal provider is always called first, followed by the file provider.
|
// Make sure the file provider is always called first.
|
||||||
requireReceivedMessageFromProviders(t, cfgCh, []string{"internal"})
|
|
||||||
requireReceivedMessageFromProviders(t, cfgCh, []string{"file"})
|
requireReceivedMessageFromProviders(t, cfgCh, []string{"file"})
|
||||||
|
|
||||||
// Check if all providers have been called, the order doesn't matter.
|
// 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)
|
require.NoError(t, <-errCh)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +51,8 @@ func requireReceivedMessageFromProviders(t *testing.T, cfgCh <-chan dynamic.Mess
|
||||||
|
|
||||||
for range names {
|
for range names {
|
||||||
select {
|
select {
|
||||||
case <-time.After(10 * time.Millisecond):
|
case <-time.After(100 * time.Millisecond):
|
||||||
|
require.Fail(t, "Timeout while waiting for configuration.")
|
||||||
case msg = <-cfgCh:
|
case msg = <-cfgCh:
|
||||||
receivedMessagesFrom = append(receivedMessagesFrom, msg.ProviderName)
|
receivedMessagesFrom = append(receivedMessagesFrom, msg.ProviderName)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"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) {
|
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 {
|
if err != nil {
|
||||||
return configuration, fmt.Errorf("unable to read directory %s: %w", directory, err)
|
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) {
|
func readFile(filename string) (string, error) {
|
||||||
if len(filename) > 0 {
|
if len(filename) > 0 {
|
||||||
buf, err := ioutil.ReadFile(filename)
|
buf, err := os.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@ package file
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -27,13 +26,12 @@ type ProvideTestCase struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTLSContent(t *testing.T) {
|
func TestTLSContent(t *testing.T) {
|
||||||
tempDir := createTempDir(t, "testdir")
|
tempDir := t.TempDir()
|
||||||
defer os.RemoveAll(tempDir)
|
|
||||||
|
|
||||||
fileTLS, err := createTempFile("./fixtures/toml/tls_file.cert", tempDir)
|
fileTLS, err := createTempFile("./fixtures/toml/tls_file.cert", tempDir)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
fileConfig, err := ioutil.TempFile(tempDir, "temp*.toml")
|
fileConfig, err := os.CreateTemp(tempDir, "temp*.toml")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
content := `
|
content := `
|
||||||
|
@ -245,7 +243,7 @@ func getTestCases() []ProvideTestCase {
|
||||||
func createProvider(t *testing.T, test ProvideTestCase, watch bool) *Provider {
|
func createProvider(t *testing.T, test ProvideTestCase, watch bool) *Provider {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
tempDir := createTempDir(t, "testdir")
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
provider := &Provider{}
|
provider := &Provider{}
|
||||||
provider.Watch = true
|
provider.Watch = true
|
||||||
|
@ -265,7 +263,7 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) *Provider {
|
||||||
var file *os.File
|
var file *os.File
|
||||||
if watch {
|
if watch {
|
||||||
var err error
|
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)
|
require.NoError(t, err)
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
|
@ -283,17 +281,6 @@ func createProvider(t *testing.T, test ProvideTestCase, watch bool) *Provider {
|
||||||
return 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 {
|
func copyFile(srcPath, dstPath string) error {
|
||||||
dst, err := os.OpenFile(dstPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o666)
|
dst, err := os.OpenFile(dstPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -312,7 +299,7 @@ func copyFile(srcPath, dstPath string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTempFile(srcPath, tempDir string) (*os.File, 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/fnv"
|
"hash/fnv"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ func (p *Provider) fetchConfigurationData() ([]byte, error) {
|
||||||
return nil, fmt.Errorf("received non-ok response code: %d", res.StatusCode)
|
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.
|
// decodeConfiguration decodes and returns the dynamic configuration from the given data.
|
||||||
|
|
|
@ -3,7 +3,6 @@ package crd
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
@ -147,7 +146,7 @@ func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrappe
|
||||||
}
|
}
|
||||||
|
|
||||||
if caFilePath != "" {
|
if caFilePath != "" {
|
||||||
caData, err := ioutil.ReadFile(caFilePath)
|
caData, err := os.ReadFile(caFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read CA file %s: %w", caFilePath, err)
|
return nil, fmt.Errorf("failed to read CA file %s: %w", caFilePath, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package crd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
"github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1"
|
||||||
|
@ -46,7 +46,7 @@ func newClientMock(paths ...string) clientMock {
|
||||||
var c clientMock
|
var c clientMock
|
||||||
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
yamlContent, err := ioutil.ReadFile(filepath.FromSlash("./fixtures/" + path))
|
yamlContent, err := os.ReadFile(filepath.FromSlash("./fixtures/" + path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package crd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -4537,7 +4537,7 @@ func TestCrossNamespace(t *testing.T) {
|
||||||
var k8sObjects []runtime.Object
|
var k8sObjects []runtime.Object
|
||||||
var crdObjects []runtime.Object
|
var crdObjects []runtime.Object
|
||||||
for _, path := range test.paths {
|
for _, path := range test.paths {
|
||||||
yamlContent, err := ioutil.ReadFile(filepath.FromSlash("./fixtures/" + path))
|
yamlContent, err := os.ReadFile(filepath.FromSlash("./fixtures/" + path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/traefik/traefik/v2/pkg/log"
|
"github.com/traefik/traefik/v2/pkg/log"
|
||||||
|
@ -138,7 +138,7 @@ func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrappe
|
||||||
}
|
}
|
||||||
|
|
||||||
if caFilePath != "" {
|
if caFilePath != "" {
|
||||||
caData, err := ioutil.ReadFile(caFilePath)
|
caData, err := os.ReadFile(caFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read CA file %s: %w", caFilePath, err)
|
return nil, fmt.Errorf("failed to read CA file %s: %w", caFilePath, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package gateway
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s"
|
"github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s"
|
||||||
|
@ -43,7 +43,7 @@ func newClientMock(paths ...string) clientMock {
|
||||||
var c clientMock
|
var c clientMock
|
||||||
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
yamlContent, err := ioutil.ReadFile(filepath.FromSlash("./fixtures/" + path))
|
yamlContent, err := os.ReadFile(filepath.FromSlash("./fixtures/" + path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -550,23 +550,24 @@ func (p *Provider) makeGatewayStatus(listenerStatuses []v1alpha1.ListenerStatus)
|
||||||
|
|
||||||
gatewayStatus.Listeners = listenerStatuses
|
gatewayStatus.Listeners = listenerStatuses
|
||||||
|
|
||||||
// update "Scheduled" status with "ResourcesAvailable" reason
|
gatewayStatus.Conditions = append(gatewayStatus.Conditions,
|
||||||
gatewayStatus.Conditions = append(gatewayStatus.Conditions, metav1.Condition{
|
// update "Scheduled" status with "ResourcesAvailable" reason
|
||||||
Type: string(v1alpha1.GatewayConditionScheduled),
|
metav1.Condition{
|
||||||
Status: metav1.ConditionTrue,
|
Type: string(v1alpha1.GatewayConditionScheduled),
|
||||||
Reason: "ResourcesAvailable",
|
Status: metav1.ConditionTrue,
|
||||||
Message: "Resources available",
|
Reason: "ResourcesAvailable",
|
||||||
LastTransitionTime: metav1.Now(),
|
Message: "Resources available",
|
||||||
})
|
LastTransitionTime: metav1.Now(),
|
||||||
|
},
|
||||||
// update "Ready" status with "ListenersValid" reason
|
// update "Ready" status with "ListenersValid" reason
|
||||||
gatewayStatus.Conditions = append(gatewayStatus.Conditions, metav1.Condition{
|
metav1.Condition{
|
||||||
Type: string(v1alpha1.GatewayConditionReady),
|
Type: string(v1alpha1.GatewayConditionReady),
|
||||||
Status: metav1.ConditionTrue,
|
Status: metav1.ConditionTrue,
|
||||||
Reason: "ListenersValid",
|
Reason: "ListenersValid",
|
||||||
Message: "Listeners valid",
|
Message: "Listeners valid",
|
||||||
LastTransitionTime: metav1.Now(),
|
LastTransitionTime: metav1.Now(),
|
||||||
})
|
},
|
||||||
|
)
|
||||||
|
|
||||||
return gatewayStatus, nil
|
return gatewayStatus, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
@ -112,7 +111,7 @@ func newExternalClusterClient(endpoint, token, caFilePath string) (*clientWrappe
|
||||||
}
|
}
|
||||||
|
|
||||||
if caFilePath != "" {
|
if caFilePath != "" {
|
||||||
caData, err := ioutil.ReadFile(caFilePath)
|
caData, err := os.ReadFile(caFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read CA file %s: %w", caFilePath, err)
|
return nil, fmt.Errorf("failed to read CA file %s: %w", caFilePath, err)
|
||||||
}
|
}
|
||||||
|
@ -341,7 +340,7 @@ func (c *clientWrapper) updateIngressStatusOld(src *networkingv1beta1.Ingress, i
|
||||||
}
|
}
|
||||||
|
|
||||||
// isLoadBalancerIngressEquals returns true if the given slices are equal, false otherwise.
|
// 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) {
|
if len(aSlice) != len(bSlice) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package ingress
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"os"
|
||||||
|
|
||||||
"github.com/hashicorp/go-version"
|
"github.com/hashicorp/go-version"
|
||||||
"github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s"
|
"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))
|
c.serverVersion = version.Must(version.NewVersion(serverVersion))
|
||||||
|
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
yamlContent, err := ioutil.ReadFile(path)
|
yamlContent, err := os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"io/ioutil"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -271,11 +271,11 @@ func Test_createConfiguration(t *testing.T) {
|
||||||
newJSON, err := json.MarshalIndent(cfg, "", " ")
|
newJSON, err := json.MarshalIndent(cfg, "", " ")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(filename, newJSON, 0o644)
|
err = os.WriteFile(filename, newJSON, 0o644)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedJSON, err := ioutil.ReadFile(filename)
|
expectedJSON, err := os.ReadFile(filename)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
actualJSON, err := json.MarshalIndent(cfg, "", " ")
|
actualJSON, err := json.MarshalIndent(cfg, "", " ")
|
||||||
|
|
|
@ -28,6 +28,7 @@ type ConfigurationWatcher struct {
|
||||||
configurationValidatedChan chan dynamic.Message
|
configurationValidatedChan chan dynamic.Message
|
||||||
providerConfigUpdateMap map[string]chan dynamic.Message
|
providerConfigUpdateMap map[string]chan dynamic.Message
|
||||||
|
|
||||||
|
requiredProvider string
|
||||||
configurationListeners []func(dynamic.Configuration)
|
configurationListeners []func(dynamic.Configuration)
|
||||||
|
|
||||||
routinesPool *safe.Pool
|
routinesPool *safe.Pool
|
||||||
|
@ -39,6 +40,7 @@ func NewConfigurationWatcher(
|
||||||
pvd provider.Provider,
|
pvd provider.Provider,
|
||||||
providersThrottleDuration time.Duration,
|
providersThrottleDuration time.Duration,
|
||||||
defaultEntryPoints []string,
|
defaultEntryPoints []string,
|
||||||
|
requiredProvider string,
|
||||||
) *ConfigurationWatcher {
|
) *ConfigurationWatcher {
|
||||||
watcher := &ConfigurationWatcher{
|
watcher := &ConfigurationWatcher{
|
||||||
provider: pvd,
|
provider: pvd,
|
||||||
|
@ -48,6 +50,7 @@ func NewConfigurationWatcher(
|
||||||
providersThrottleDuration: providersThrottleDuration,
|
providersThrottleDuration: providersThrottleDuration,
|
||||||
routinesPool: routinesPool,
|
routinesPool: routinesPool,
|
||||||
defaultEntryPoints: defaultEntryPoints,
|
defaultEntryPoints: defaultEntryPoints,
|
||||||
|
requiredProvider: requiredProvider,
|
||||||
}
|
}
|
||||||
|
|
||||||
currentConfigurations := make(dynamic.Configurations)
|
currentConfigurations := make(dynamic.Configurations)
|
||||||
|
@ -146,8 +149,11 @@ func (c *ConfigurationWatcher) loadMessage(configMsg dynamic.Message) {
|
||||||
conf := mergeConfiguration(newConfigurations, c.defaultEntryPoints)
|
conf := mergeConfiguration(newConfigurations, c.defaultEntryPoints)
|
||||||
conf = applyModel(conf)
|
conf = applyModel(conf)
|
||||||
|
|
||||||
for _, listener := range c.configurationListeners {
|
// We wait for first configuration of the require provider before applying configurations.
|
||||||
listener(conf)
|
if _, ok := newConfigurations[c.requiredProvider]; c.requiredProvider == "" || ok {
|
||||||
|
for _, listener := range c.configurationListeners {
|
||||||
|
listener(conf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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{})
|
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
|
publishedConfigCount := 0
|
||||||
watcher.AddListener(func(_ dynamic.Configuration) {
|
watcher.AddListener(func(_ dynamic.Configuration) {
|
||||||
|
@ -136,7 +136,7 @@ func TestListenProvidersSkipsEmptyConfigs(t *testing.T) {
|
||||||
messages: []dynamic.Message{{ProviderName: "mock"}},
|
messages: []dynamic.Message{{ProviderName: "mock"}},
|
||||||
}
|
}
|
||||||
|
|
||||||
watcher := NewConfigurationWatcher(routinesPool, pvd, time.Second, []string{})
|
watcher := NewConfigurationWatcher(routinesPool, pvd, time.Second, []string{}, "")
|
||||||
watcher.AddListener(func(_ dynamic.Configuration) {
|
watcher.AddListener(func(_ dynamic.Configuration) {
|
||||||
t.Error("An empty configuration was published but it should not")
|
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},
|
messages: []dynamic.Message{message, message},
|
||||||
}
|
}
|
||||||
|
|
||||||
watcher := NewConfigurationWatcher(routinesPool, pvd, 0, []string{})
|
watcher := NewConfigurationWatcher(routinesPool, pvd, 0, []string{}, "")
|
||||||
|
|
||||||
alreadyCalled := false
|
alreadyCalled := false
|
||||||
watcher.AddListener(func(_ dynamic.Configuration) {
|
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
|
var lastConfig dynamic.Configuration
|
||||||
watcher.AddListener(func(conf dynamic.Configuration) {
|
watcher.AddListener(func(conf dynamic.Configuration) {
|
||||||
|
@ -216,7 +216,7 @@ func TestListenProvidersDoesNotSkipFlappingConfiguration(t *testing.T) {
|
||||||
defer watcher.Stop()
|
defer watcher.Stop()
|
||||||
|
|
||||||
// give some time so that the configuration can be processed
|
// give some time so that the configuration can be processed
|
||||||
time.Sleep(40 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
expected := dynamic.Configuration{
|
expected := dynamic.Configuration{
|
||||||
HTTP: th.BuildConfiguration(
|
HTTP: th.BuildConfiguration(
|
||||||
|
@ -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
|
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
|
publishedConfigCount := 0
|
||||||
watcher.AddListener(func(configuration dynamic.Configuration) {
|
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
|
publishedConfigCount := 0
|
||||||
watcher.AddListener(func(configuration dynamic.Configuration) {
|
watcher.AddListener(func(configuration dynamic.Configuration) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -827,7 +827,7 @@ func BenchmarkRouterServe(b *testing.B) {
|
||||||
|
|
||||||
res := &http.Response{
|
res := &http.Response{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: ioutil.NopCloser(strings.NewReader("")),
|
Body: io.NopCloser(strings.NewReader("")),
|
||||||
}
|
}
|
||||||
|
|
||||||
routersConfig := map[string]*dynamic.Router{
|
routersConfig := map[string]*dynamic.Router{
|
||||||
|
@ -879,7 +879,7 @@ func BenchmarkRouterServe(b *testing.B) {
|
||||||
func BenchmarkService(b *testing.B) {
|
func BenchmarkService(b *testing.B) {
|
||||||
res := &http.Response{
|
res := &http.Response{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: ioutil.NopCloser(strings.NewReader("")),
|
Body: io.NopCloser(strings.NewReader("")),
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceConfig := map[string]*dynamic.Service{
|
serviceConfig := map[string]*dynamic.Service{
|
||||||
|
|
|
@ -362,11 +362,11 @@ func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = tc.SetKeepAlive(true); err != nil {
|
if err := tc.SetKeepAlive(true); err != nil {
|
||||||
return nil, err
|
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
|
// Some systems, such as OpenBSD, have no user-settable per-socket TCP
|
||||||
// keepalive options.
|
// keepalive options.
|
||||||
if !errors.Is(err, syscall.ENOPROTOOPT) {
|
if !errors.Is(err, syscall.ENOPROTOOPT) {
|
||||||
|
|
|
@ -48,7 +48,7 @@ func TestShutdownTCP(t *testing.T) {
|
||||||
for {
|
for {
|
||||||
_, err := http.ReadRequest(bufio.NewReader(conn))
|
_, 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
|
return
|
||||||
}
|
}
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -70,6 +70,8 @@ func testShutdown(t *testing.T, router *tcp.Router) {
|
||||||
|
|
||||||
epConfig.LifeCycle.RequestAcceptGraceTimeout = 0
|
epConfig.LifeCycle.RequestAcceptGraceTimeout = 0
|
||||||
epConfig.LifeCycle.GraceTimeOut = ptypes.Duration(5 * time.Second)
|
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{
|
entryPoint, err := NewTCPEntryPoint(context.Background(), &static.EntryPoint{
|
||||||
// We explicitly use an IPV4 address because on Alpine, with an IPV6 address
|
// 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)
|
err = request.Write(conn)
|
||||||
require.NoError(t, err)
|
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())
|
go entryPoint.Shutdown(context.Background())
|
||||||
|
|
||||||
// Make sure that new connections are not permitted anymore.
|
// 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
|
// 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)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
@ -133,22 +140,17 @@ func startEntrypoint(entryPoint *TCPEntryPoint, router *tcp.Router) (net.Conn, e
|
||||||
|
|
||||||
entryPoint.SwitchRouter(router)
|
entryPoint.SwitchRouter(router)
|
||||||
|
|
||||||
var conn net.Conn
|
|
||||||
var err error
|
|
||||||
var epStarted bool
|
|
||||||
for i := 0; i < 10; i++ {
|
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 {
|
if err != nil {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
epStarted = true
|
|
||||||
break
|
return conn, err
|
||||||
}
|
}
|
||||||
if !epStarted {
|
|
||||||
return nil, errors.New("entry point never started")
|
return nil, errors.New("entry point never started")
|
||||||
}
|
|
||||||
return conn, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReadTimeoutWithoutFirstByte(t *testing.T) {
|
func TestReadTimeoutWithoutFirstByte(t *testing.T) {
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -88,7 +87,7 @@ func (m *Mirroring) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.Is(err, errBodyTooLarge) {
|
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)
|
m.handler.ServeHTTP(rw, req)
|
||||||
logger.Debugf("no mirroring, request body larger than allowed size")
|
logger.Debugf("no mirroring, request body larger than allowed size")
|
||||||
return
|
return
|
||||||
|
@ -147,8 +146,8 @@ func (b blackHoleResponseWriter) Header() http.Header {
|
||||||
return http.Header{}
|
return http.Header{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b blackHoleResponseWriter) Write(bytes []byte) (int, error) {
|
func (b blackHoleResponseWriter) Write(data []byte) (int, error) {
|
||||||
return len(bytes), nil
|
return len(data), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b blackHoleResponseWriter) WriteHeader(statusCode int) {}
|
func (b blackHoleResponseWriter) WriteHeader(statusCode int) {}
|
||||||
|
@ -182,7 +181,7 @@ func newReusableRequest(req *http.Request, maxBodySize int64) (*reusableRequest,
|
||||||
|
|
||||||
// unbounded body size
|
// unbounded body size
|
||||||
if maxBodySize < 0 {
|
if maxBodySize < 0 {
|
||||||
body, err := ioutil.ReadAll(req.Body)
|
body, err := io.ReadAll(req.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -217,7 +216,7 @@ func (rr reusableRequest) clone(ctx context.Context) *http.Request {
|
||||||
req := rr.req.Clone(ctx)
|
req := rr.req.Clone(ctx)
|
||||||
|
|
||||||
if rr.body != nil {
|
if rr.body != nil {
|
||||||
req.Body = ioutil.NopCloser(bytes.NewReader(rr.body))
|
req.Body = io.NopCloser(bytes.NewReader(rr.body))
|
||||||
}
|
}
|
||||||
|
|
||||||
return req
|
return req
|
||||||
|
|
|
@ -3,7 +3,7 @@ package mirror
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
@ -148,7 +148,7 @@ func TestMirroringWithBody(t *testing.T) {
|
||||||
|
|
||||||
handler := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
handler := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
assert.NotNil(t, r.Body)
|
assert.NotNil(t, r.Body)
|
||||||
bb, err := ioutil.ReadAll(r.Body)
|
bb, err := io.ReadAll(r.Body)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, body, bb)
|
assert.Equal(t, body, bb)
|
||||||
rw.WriteHeader(http.StatusOK)
|
rw.WriteHeader(http.StatusOK)
|
||||||
|
@ -159,7 +159,7 @@ func TestMirroringWithBody(t *testing.T) {
|
||||||
for i := 0; i < numMirrors; i++ {
|
for i := 0; i < numMirrors; i++ {
|
||||||
err := mirror.AddMirror(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
err := mirror.AddMirror(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||||
assert.NotNil(t, r.Body)
|
assert.NotNil(t, r.Body)
|
||||||
bb, err := ioutil.ReadAll(r.Body)
|
bb, err := io.ReadAll(r.Body)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, body, bb)
|
assert.Equal(t, body, bb)
|
||||||
atomic.AddInt32(&countMirror, 1)
|
atomic.AddInt32(&countMirror, 1)
|
||||||
|
@ -213,13 +213,13 @@ func TestCloneRequest(t *testing.T) {
|
||||||
|
|
||||||
// first call
|
// first call
|
||||||
cloned := rr.clone(ctx)
|
cloned := rr.clone(ctx)
|
||||||
body, err := ioutil.ReadAll(cloned.Body)
|
body, err := io.ReadAll(cloned.Body)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, bb, body)
|
assert.Equal(t, bb, body)
|
||||||
|
|
||||||
// second call
|
// second call
|
||||||
cloned = rr.clone(ctx)
|
cloned = rr.clone(ctx)
|
||||||
body, err = ioutil.ReadAll(cloned.Body)
|
body, err = io.ReadAll(cloned.Body)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, bb, body)
|
assert.Equal(t, bb, body)
|
||||||
})
|
})
|
||||||
|
|
|
@ -24,6 +24,19 @@ type stickyCookie struct {
|
||||||
httpOnly bool
|
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.
|
// New creates a new load balancer.
|
||||||
func New(sticky *dynamic.Sticky) *Balancer {
|
func New(sticky *dynamic.Sticky) *Balancer {
|
||||||
balancer := &Balancer{}
|
balancer := &Balancer{}
|
||||||
|
@ -68,19 +81,6 @@ func (b *Balancer) Pop() interface{} {
|
||||||
return h
|
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) {
|
func (b *Balancer) nextServer() (*namedHandler, error) {
|
||||||
b.mutex.Lock()
|
b.mutex.Lock()
|
||||||
defer b.mutex.Unlock()
|
defer b.mutex.Unlock()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -21,7 +21,7 @@ func (t *staticTransport) RoundTrip(r *http.Request) (*http.Response, error) {
|
||||||
func BenchmarkProxy(b *testing.B) {
|
func BenchmarkProxy(b *testing.B) {
|
||||||
res := &http.Response{
|
res := &http.Response{
|
||||||
StatusCode: 200,
|
StatusCode: 200,
|
||||||
Body: ioutil.NopCloser(strings.NewReader("")),
|
Body: io.NopCloser(strings.NewReader("")),
|
||||||
}
|
}
|
||||||
|
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
|
@ -123,6 +123,8 @@ func createRoundTripper(cfg *dynamic.ServersTransport) (http.RoundTripper, error
|
||||||
IdleConnTimeout: 90 * time.Second,
|
IdleConnTimeout: 90 * time.Second,
|
||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
|
ReadBufferSize: 64 * 1024,
|
||||||
|
WriteBufferSize: 64 * 1024,
|
||||||
}
|
}
|
||||||
|
|
||||||
transport.RegisterProtocol("h2c", &h2cTransportWrapper{
|
transport.RegisterProtocol("h2c", &h2cTransportWrapper{
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -90,7 +89,7 @@ func (f FileOrContent) Read() ([]byte, error) {
|
||||||
var content []byte
|
var content []byte
|
||||||
if f.IsPath() {
|
if f.IsPath() {
|
||||||
var err error
|
var err error
|
||||||
content, err = ioutil.ReadFile(f.String())
|
content, err = os.ReadFile(f.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/traefik/traefik/v2/pkg/log"
|
"github.com/traefik/traefik/v2/pkg/log"
|
||||||
|
@ -34,7 +33,7 @@ func (clientTLS *ClientTLS) CreateTLSConfig(ctx context.Context) (*tls.Config, e
|
||||||
var ca []byte
|
var ca []byte
|
||||||
if _, errCA := os.Stat(clientTLS.CA); errCA == nil {
|
if _, errCA := os.Stat(clientTLS.CA); errCA == nil {
|
||||||
var err error
|
var err error
|
||||||
ca, err = ioutil.ReadFile(clientTLS.CA)
|
ca, err = os.ReadFile(clientTLS.CA)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to read CA. %w", err)
|
return nil, fmt.Errorf("failed to read CA. %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,10 @@ git config --global user.email "$TRAEFIKER_EMAIL"
|
||||||
git config --global user.name "Traefiker"
|
git config --global user.name "Traefiker"
|
||||||
|
|
||||||
# load ssh key
|
# load ssh key
|
||||||
|
: "${encrypted_83c521e11abe_key:?}" # ensures variable is defined
|
||||||
|
: "${encrypted_83c521e11abe_iv:?}" # same
|
||||||
echo "Loading key..."
|
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)"
|
eval "$(ssh-agent -s)"
|
||||||
chmod 600 ~/.ssh/traefiker_rsa
|
chmod 600 ~/.ssh/traefiker_rsa
|
||||||
ssh-add ~/.ssh/traefiker_rsa
|
ssh-add ~/.ssh/traefiker_rsa
|
||||||
|
@ -22,10 +24,10 @@ ssh-add ~/.ssh/traefiker_rsa
|
||||||
echo "Updating traefik-library-imag repo..."
|
echo "Updating traefik-library-imag repo..."
|
||||||
git clone git@github.com:traefik/traefik-library-image.git
|
git clone git@github.com:traefik/traefik-library-image.git
|
||||||
cd traefik-library-image
|
cd traefik-library-image
|
||||||
./updatev2.sh $VERSION
|
./updatev2.sh "$VERSION"
|
||||||
git add -A
|
git add -A
|
||||||
echo $VERSION | git commit --file -
|
echo "$VERSION" | git commit --file -
|
||||||
echo $VERSION | git tag -a $VERSION --file -
|
echo "$VERSION" | git tag -a "$VERSION" --file -
|
||||||
git push -q --follow-tags -u origin master > /dev/null 2>&1
|
git push -q --follow-tags -u origin master > /dev/null 2>&1
|
||||||
|
|
||||||
cd ..
|
cd ..
|
||||||
|
|
|
@ -4,11 +4,11 @@ RepositoryName = "traefik"
|
||||||
OutputType = "file"
|
OutputType = "file"
|
||||||
FileName = "traefik_changelog.md"
|
FileName = "traefik_changelog.md"
|
||||||
|
|
||||||
# example new bugfix v2.4.5
|
# example new bugfix v2.4.7
|
||||||
CurrentRef = "v2.4"
|
CurrentRef = "v2.4"
|
||||||
PreviousRef = "v2.4.4"
|
PreviousRef = "v2.4.6"
|
||||||
BaseBranch = "v2.4"
|
BaseBranch = "v2.4"
|
||||||
FutureCurrentRefName = "v2.4.5"
|
FutureCurrentRefName = "v2.4.7"
|
||||||
|
|
||||||
ThresholdPreviousRef = 10
|
ThresholdPreviousRef = 10
|
||||||
ThresholdCurrentRef = 10
|
ThresholdCurrentRef = 10
|
||||||
|
|
Loading…
Reference in a new issue