diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 0df46760d7886bddf7a5c6eb5b17d2e49ebb2b34..6f48169bbd96cafebc21ba820995d8c6557aad7a 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -2,11 +2,11 @@ PLEASE READ THIS MESSAGE. Documentation fixes or enhancements: -- for Traefik v2: use branch v2.9 +- for Traefik v2: use branch v2.10 - for Traefik v3: use branch master Bug fixes: -- for Traefik v2: use branch v2.9 +- for Traefik v2: use branch v2.10 - for Traefik v3: use branch master Enhancements: diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 110edf6cb2deb57457551592e1f415df23038fef..a219162d19df65c73823f68422e679f717a1bb08 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -6,7 +6,7 @@ on: - '*' env: - GO_VERSION: 1.19 + GO_VERSION: '1.20' CGO_ENABLED: 0 IN_DOCKER: "" diff --git a/.github/workflows/check_doc.yml b/.github/workflows/check_doc.yml index ee7465fcbfb6b51ab9ba73fc3cdbe8d49b07e0bb..c800ad248e31c5d307fecc62a436eaf0c9c99666 100644 --- a/.github/workflows/check_doc.yml +++ b/.github/workflows/check_doc.yml @@ -19,3 +19,7 @@ jobs: - name: Check documentation run: make docs-pull-images docs + env: + # These variables are not passed to workflows that are triggered by a pull request from a fork. + DOCS_VERIFY_SKIP: ${{ vars.DOCS_VERIFY_SKIP }} + DOCS_LINT_SKIP: ${{ vars.DOCS_LINT_SKIP }} diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 66227331f5fc02babf1af74f79c4f5883c220874..7ef7f7ed3ed5a512af84e87a4d62627ee0e2c6d5 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -7,7 +7,7 @@ on: - v* env: - STRUCTOR_VERSION: v1.11.2 + STRUCTOR_VERSION: v1.13.1 MIXTUS_VERSION: v0.4.1 jobs: @@ -41,12 +41,12 @@ jobs: - name: Build documentation run: $HOME/bin/structor -o traefik -r traefik --dockerfile-url="https://raw.githubusercontent.com/traefik/traefik/v1.7/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/traefik/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/traefik/structor/master/requirements-override.txt" --force-edit-url --exp-branch=master --debug env: - STRUCTOR_LATEST_TAG: ${{ secrets.STRUCTOR_LATEST_TAG }} + STRUCTOR_LATEST_TAG: ${{ vars.STRUCTOR_LATEST_TAG }} - name: Apply seo run: $HOME/bin/seo -path=./site -product=traefik - name: Publish documentation - run: $HOME/bin/mixtus --dst-doc-path="./traefik" --dst-owner=traefik --dst-repo-name=doc --git-user-email="30906710+traefiker@users.noreply.github.com" --git-user-name=traefiker --src-doc-path="./site" --src-owner=containous --src-repo-name=traefik + run: $HOME/bin/mixtus --dst-doc-path="./traefik" --dst-owner=traefik --dst-repo-name=doc --git-user-email="30906710+traefiker@users.noreply.github.com" --git-user-name=traefiker --src-doc-path="./site" --src-owner=traefik --src-repo-name=traefik env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN_REPO }} diff --git a/.github/workflows/test-unit.yaml b/.github/workflows/test-unit.yaml index c819cd1aa6d5b4fcc3f0d6fb483c57e56105e696..ad9edcf4144bd424c5715fb7888480689516f414 100644 --- a/.github/workflows/test-unit.yaml +++ b/.github/workflows/test-unit.yaml @@ -6,7 +6,7 @@ on: - '*' env: - GO_VERSION: 1.19 + GO_VERSION: '1.20' IN_DOCKER: "" jobs: diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml index beb87eec15872df44f1b8b63b91f9739f07bcea8..69de25cf4bde453f94325d46189224a74c6d6dba 100644 --- a/.github/workflows/validate.yaml +++ b/.github/workflows/validate.yaml @@ -6,8 +6,8 @@ on: - '*' env: - GO_VERSION: 1.19 - GOLANGCI_LINT_VERSION: v1.50.0 + GO_VERSION: '1.20' + GOLANGCI_LINT_VERSION: v1.51.2 MISSSPELL_VERSION: v0.4.0 IN_DOCKER: "" diff --git a/.golangci.yml b/.golangci.yml index f6f2085f7c61bbad8e48559200c4322386cb22df..c8baa7f6b15b49947f80a5a4a847ca4cd0d6154a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -179,3 +179,7 @@ issues: text: 'Duplicate words \(sub\) found' linters: - dupword + - path: pkg/provider/kubernetes/crd/kubernetes.go + text: "Function 'loadConfigurationFromCRD' has too many statements" + linters: + - funlen diff --git a/.goreleaser.yml b/.goreleaser.yml index 9194b4a1e363871f9758966be9c539ab307cb399..a6fc323d38a13d7a5383efdb507cb6c72a5e9fc2 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -11,7 +11,7 @@ builds: env: - CGO_ENABLED=0 ldflags: - - -s -w -X github.com/traefik/traefik/v2/pkg/version.Version={{.Version}} -X github.com/traefik/traefik/v2/pkg/version.Codename={{.Env.CODENAME}} -X github.com/traefik/traefik/v2/pkg/version.BuildDate={{.Date}} + - -s -w -X github.com/traefik/traefik/v3/pkg/version.Version={{.Version}} -X github.com/traefik/traefik/v3/pkg/version.Codename={{.Env.CODENAME}} -X github.com/traefik/traefik/v3/pkg/version.BuildDate={{.Date}} flags: - -trimpath goos: diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 2aab6ab3e87e2be2003128e6523401908c6bb856..95ea73ed1485f62332cd8f3917aacbab843b60bc 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -19,7 +19,7 @@ global_job_config: prologue: commands: - curl -sSfL https://raw.githubusercontent.com/ldez/semgo/master/godownloader.sh | sudo sh -s -- -b "/usr/local/bin" - - sudo semgo go1.19 + - sudo semgo go1.20 - export "GOPATH=$(go env GOPATH)" - export "SEMAPHORE_GIT_DIR=${GOPATH}/src/github.com/traefik/${SEMAPHORE_PROJECT_NAME}" - export "PATH=${GOPATH}/bin:${PATH}" diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a393f2178751287fb070062cd0681316a614bfa..cc9a911ca286cc1215d7ab3f2bf690680d364824 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,69 @@ +## [v2.10.0-rc1](https://github.com/traefik/traefik/tree/v2.10.0-rc1) (2023-03-22) +[All Commits](https://github.com/traefik/traefik/compare/b3f162a8a61d89beaa9edc8adc12cc4cb3e1de0f...v2.10.0-rc1) + +**Enhancements:** +- **[docker]** Expose ContainerName in Docker provider ([#9770](https://github.com/traefik/traefik/pull/9770) by [quinot](https://github.com/quinot)) +- **[hub]** hub: get out of experimental. ([#9792](https://github.com/traefik/traefik/pull/9792) by [mpl](https://github.com/mpl)) +- **[k8s/crd]** Introduce traefik.io API Group CRDs ([#9765](https://github.com/traefik/traefik/pull/9765) by [rtribotte](https://github.com/rtribotte)) +- **[k8s/ingress,k8s/crd,k8s]** Native Kubernetes service load-balancing ([#9740](https://github.com/traefik/traefik/pull/9740) by [rtribotte](https://github.com/rtribotte)) +- **[middleware,metrics]** Add prometheus metric requests_total with headers ([#9783](https://github.com/traefik/traefik/pull/9783) by [rtribotte](https://github.com/rtribotte)) +- **[nomad]** Support multiple namespaces in the Nomad Provider ([#9794](https://github.com/traefik/traefik/pull/9794) by [rtribotte](https://github.com/rtribotte)) +- **[tracing]** Add support to send DataDog traces via Unix Socket ([#9714](https://github.com/traefik/traefik/pull/9714) by [der-eismann](https://github.com/der-eismann)) + +**Documentation:** +- docs: update order of log levels ([#9791](https://github.com/traefik/traefik/pull/9791) by [svx](https://github.com/svx)) + +**Misc:** +- Merge current v2.9 into v2.10 ([#9798](https://github.com/traefik/traefik/pull/9798) by [ldez](https://github.com/ldez)) + +## [v2.9.9](https://github.com/traefik/traefik/tree/v2.9.9) (2023-03-21) +[All Commits](https://github.com/traefik/traefik/compare/v2.9.8...v2.9.9) + +**Bug fixes:** +- **[acme]** Update go-acme/lego to v4.10.2 ([#9749](https://github.com/traefik/traefik/pull/9749) by [ldez](https://github.com/ldez)) +- **[http3]** Update quic-go to v0.33.0 ([#9737](https://github.com/traefik/traefik/pull/9737) by [ldez](https://github.com/ldez)) +- **[metrics]** Include user-defined default cert for traefik_tls_certs_not_after metric ([#9742](https://github.com/traefik/traefik/pull/9742) by [rtribotte](https://github.com/rtribotte)) +- **[middleware]** Update vulcand/oxy to a0e9f7ff1040 ([#9750](https://github.com/traefik/traefik/pull/9750) by [ldez](https://github.com/ldez)) +- **[nomad]** Fix default configuration settings for Nomad Provider ([#9758](https://github.com/traefik/traefik/pull/9758) by [aofei](https://github.com/aofei)) +- **[nomad]** Fix Nomad client TLS defaults ([#9795](https://github.com/traefik/traefik/pull/9795) by [rtribotte](https://github.com/rtribotte)) +- **[server]** Remove User-Agent header removal from ReverseProxy director func ([#9752](https://github.com/traefik/traefik/pull/9752) by [rtribotte](https://github.com/rtribotte)) + +**Documentation:** +- **[middleware]** Clarify ratelimit middleware ([#9777](https://github.com/traefik/traefik/pull/9777) by [mpl](https://github.com/mpl)) +- **[tcp]** Correcting variable name 'server address' in TCP Router ([#9743](https://github.com/traefik/traefik/pull/9743) by [ralphg6](https://github.com/ralphg6)) + +## [v2.9.8](https://github.com/traefik/traefik/tree/v2.9.8) (2023-02-15) +[All Commits](https://github.com/traefik/traefik/compare/v2.9.7...v2.9.8) + +**Bug fixes:** +- **[server]** Update golang.org/x/net to v0.7.0 ([#9716](https://github.com/traefik/traefik/pull/9716) by [ldez](https://github.com/ldez)) + +## [v2.9.7](https://github.com/traefik/traefik/tree/v2.9.7) (2023-02-14) +[All Commits](https://github.com/traefik/traefik/compare/v2.9.6...v2.9.7) + +**Bug fixes:** +- **[acme]** Update go-acme/lego to v4.10.0 ([#9705](https://github.com/traefik/traefik/pull/9705) by [ldez](https://github.com/ldez)) +- **[ecs]** Prevent panicking when a container has no network interfaces ([#9661](https://github.com/traefik/traefik/pull/9661) by [rtribotte](https://github.com/rtribotte)) +- **[file]** Make file provider more resilient wrt first configuration ([#9595](https://github.com/traefik/traefik/pull/9595) by [mpl](https://github.com/mpl)) +- **[logs]** Differentiate UDP stream and TCP connection in logs ([#9687](https://github.com/traefik/traefik/pull/9687) by [rtribotte](https://github.com/rtribotte)) +- **[middleware]** Prevent from no rate limiting when average is zero ([#9621](https://github.com/traefik/traefik/pull/9621) by [witalisoft](https://github.com/witalisoft)) +- **[middleware]** Prevents superfluous WriteHeader call in the error middleware ([#9620](https://github.com/traefik/traefik/pull/9620) by [tomMoulard](https://github.com/tomMoulard)) +- **[middleware]** Sanitize X-Forwarded-Proto header in RedirectScheme middleware ([#9598](https://github.com/traefik/traefik/pull/9598) by [ldez](https://github.com/ldez)) +- **[plugins]** Update paerser to v0.2.0 ([#9671](https://github.com/traefik/traefik/pull/9671) by [ldez](https://github.com/ldez)) +- **[plugins]** Update Yaegi to v0.15.0 ([#9700](https://github.com/traefik/traefik/pull/9700) by [ldez](https://github.com/ldez)) +- **[tls,http3]** Bump quic-go to 89769f409f ([#9685](https://github.com/traefik/traefik/pull/9685) by [mpl](https://github.com/mpl)) +- **[tls,tcp]** Adds the support for IPv6 in the TCP HostSNI matcher ([#9692](https://github.com/traefik/traefik/pull/9692) by [rtribotte](https://github.com/rtribotte)) + +**Documentation:** +- **[acme]** Add CNAME support and gotchas ([#9698](https://github.com/traefik/traefik/pull/9698) by [mpl](https://github.com/mpl)) +- **[acme]** Further Let's Encrypt ratelimit warnings ([#9627](https://github.com/traefik/traefik/pull/9627) by [hcooper](https://github.com/hcooper)) +- **[k8s]** Add info admonition about routing to k8 services ([#9645](https://github.com/traefik/traefik/pull/9645) by [svx](https://github.com/svx)) +- **[k8s]** Improve TLSStore CRD documentation ([#9579](https://github.com/traefik/traefik/pull/9579) by [mloiseleur](https://github.com/mloiseleur)) +- **[middleware]** doc: add note about remoteaddr strategy ([#9701](https://github.com/traefik/traefik/pull/9701) by [mpl](https://github.com/mpl)) +- Update copyright to match new standard ([#9651](https://github.com/traefik/traefik/pull/9651) by [paulocfjunior](https://github.com/paulocfjunior)) +- Update copyright for 2023 ([#9631](https://github.com/traefik/traefik/pull/9631) by [kevinpollet](https://github.com/kevinpollet)) +- Update submitting pull requests to include language about drafts ([#9609](https://github.com/traefik/traefik/pull/9609) by [tfny](https://github.com/tfny)) + ## [v3.0.0-beta2](https://github.com/traefik/traefik/tree/v3.0.0-beta2) (2022-12-07) [All Commits](https://github.com/traefik/traefik/compare/v3.0.0-beta1...v3.0.0-beta2) @@ -142,13 +208,7 @@ Release canceled. - **[acme]** Fix ACME panic ([#9365](https://github.com/traefik/traefik/pull/9365) by [ldez](https://github.com/ldez)) **Documentation:** -- Prepare release v2.9.0 ([#9409](https://github.com/traefik/traefik/pull/9409) by [tomMoulard](https://github.com/tomMoulard)) - **[metrics]** Rework metrics overview page ([#9366](https://github.com/traefik/traefik/pull/9366) by [ddtmachado](https://github.com/ddtmachado)) -- Prepare release v2.9.0-rc5 ([#9402](https://github.com/traefik/traefik/pull/9402) by [ldez](https://github.com/ldez)) -- Prepare release v2.9.0-rc4 ([#9372](https://github.com/traefik/traefik/pull/9372) by [kevinpollet](https://github.com/kevinpollet)) -- Prepare release v2.9.0-rc3 ([#9344](https://github.com/traefik/traefik/pull/9344) by [kevinpollet](https://github.com/kevinpollet)) -- Prepare release v2.9.0-rc2 ([6c2c561](https://github.com/traefik/traefik/commit/6c2c561d8f935d76ccd07d28e1455c7768adc153) by [ldez](https://github.com/ldez)) -- Prepare release v2.9.0-rc1 ([#9334](https://github.com/traefik/traefik/pull/9334) by [rtribotte](https://github.com/rtribotte)) **Misc:** - Merge current v2.8 into v2.9 ([#9400](https://github.com/traefik/traefik/pull/9400) by [ldez](https://github.com/ldez)) diff --git a/LICENSE.md b/LICENSE.md index 62a9962058f85d06713644ac8bf83ca1d7d4d3be..d56287566534b55a433dca6b479766a2c3ce751f 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 544eddb9282bf0b95490b78c57a1630380d65a64..7d0faa8cebdac5a25e04efea22bcb45714b8fc3a 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [](https://twitter.com/intent/follow?screen_name=traefik) Traefik (pronounced _traffic_) is a modern HTTP reverse proxy and load balancer that makes deploying microservices easy. -Traefik integrates with your existing infrastructure components ([Docker](https://www.docker.com/), [Swarm mode](https://docs.docker.com/engine/swarm/), [Kubernetes](https://kubernetes.io), [Marathon](https://mesosphere.github.io/marathon/), [Consul](https://www.consul.io/), [Etcd](https://coreos.com/etcd/), [Rancher](https://rancher.com), [Amazon ECS](https://aws.amazon.com/ecs), ...) and configures itself automatically and dynamically. +Traefik integrates with your existing infrastructure components ([Docker](https://www.docker.com/), [Swarm mode](https://docs.docker.com/engine/swarm/), [Kubernetes](https://kubernetes.io), [Consul](https://www.consul.io/), [Etcd](https://coreos.com/etcd/), [Rancher v2](https://rancher.com), [Amazon ECS](https://aws.amazon.com/ecs), ...) and configures itself automatically and dynamically. Pointing Traefik at your orchestrator should be the _only_ configuration step you need. --- @@ -58,7 +58,7 @@ _(But if you'd rather configure some of your routes manually, Traefik supports t - Circuit breakers, retry - See the magic through its clean web UI - Websocket, HTTP/2, gRPC ready -- Provides metrics (Rest, Prometheus, Datadog, Statsd, InfluxDB) +- Provides metrics (Rest, Prometheus, Datadog, Statsd, InfluxDB 2.X) - Keeps access logs (JSON, CLF) - Fast - Exposes a Rest API @@ -68,8 +68,6 @@ _(But if you'd rather configure some of your routes manually, Traefik supports t - [Docker](https://doc.traefik.io/traefik/providers/docker/) / [Swarm mode](https://doc.traefik.io/traefik/providers/docker/) - [Kubernetes](https://doc.traefik.io/traefik/providers/kubernetes-crd/) -- [Marathon](https://doc.traefik.io/traefik/providers/marathon/) -- [Rancher](https://doc.traefik.io/traefik/providers/rancher/) (Metadata) - [File](https://doc.traefik.io/traefik/providers/file/) ## Quickstart diff --git a/build.Dockerfile b/build.Dockerfile index cf4ab860897aec764f22e16b06f7dbc6b49a6f50..6d4ba8625abc07cce3955a91568313dfc545b43d 100644 --- a/build.Dockerfile +++ b/build.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.19-alpine +FROM golang:1.20-alpine RUN apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \ && update-ca-certificates \ diff --git a/cmd/configuration.go b/cmd/configuration.go index 3e4f38f92a8ebd889699ec9c86b051664ad21a72..d65bdf04d4c41fd59f563fcd697d14eee5f7ef94 100644 --- a/cmd/configuration.go +++ b/cmd/configuration.go @@ -4,7 +4,7 @@ import ( "time" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/static" ) // TraefikCmdConfiguration wraps the static configuration and extra parameters. @@ -28,6 +28,10 @@ func NewTraefikConfiguration() *TraefikCmdConfiguration { ServersTransport: &static.ServersTransport{ MaxIdleConnsPerHost: 200, }, + TCPServersTransport: &static.TCPServersTransport{ + DialTimeout: ptypes.Duration(30 * time.Second), + DialKeepAlive: ptypes.Duration(15 * time.Second), + }, }, ConfigFile: "", } diff --git a/cmd/healthcheck/healthcheck.go b/cmd/healthcheck/healthcheck.go index fbeaee566860fe8abed5cffa0d373c3860161a63..a3b720eb655745ccb5f8b6a1e7519ac6fef9e8e7 100644 --- a/cmd/healthcheck/healthcheck.go +++ b/cmd/healthcheck/healthcheck.go @@ -8,7 +8,7 @@ import ( "time" "github.com/traefik/paerser/cli" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/static" ) // NewCmd builds a new HealthCheck command. diff --git a/cmd/internal/gen/main.go b/cmd/internal/gen/main.go index 8e9c3735a3dbf640e4b09441c8648cd12ed30414..f5fd5bb35945fb0eb4d936cfb897746d043f267b 100644 --- a/cmd/internal/gen/main.go +++ b/cmd/internal/gen/main.go @@ -11,7 +11,7 @@ import ( "strings" ) -const rootPkg = "github.com/traefik/traefik/v2/pkg/config/dynamic" +const rootPkg = "github.com/traefik/traefik/v3/pkg/config/dynamic" const ( destModuleName = "github.com/traefik/genconf" @@ -57,8 +57,8 @@ func run(dest string) error { } centrifuge.IncludedImports = []string{ - "github.com/traefik/traefik/v2/pkg/tls", - "github.com/traefik/traefik/v2/pkg/types", + "github.com/traefik/traefik/v3/pkg/tls", + "github.com/traefik/traefik/v3/pkg/types", } centrifuge.ExcludedTypes = []string{ @@ -71,8 +71,8 @@ func run(dest string) error { } centrifuge.ExcludedFiles = []string{ - "github.com/traefik/traefik/v2/pkg/types/logs.go", - "github.com/traefik/traefik/v2/pkg/types/metrics.go", + "github.com/traefik/traefik/v3/pkg/types/logs.go", + "github.com/traefik/traefik/v3/pkg/types/metrics.go", } centrifuge.TypeCleaner = cleanType @@ -87,11 +87,11 @@ func run(dest string) error { } func cleanType(typ types.Type, base string) string { - if typ.String() == "github.com/traefik/traefik/v2/pkg/tls.FileOrContent" { + if typ.String() == "github.com/traefik/traefik/v3/pkg/tls.FileOrContent" { return "string" } - if typ.String() == "[]github.com/traefik/traefik/v2/pkg/tls.FileOrContent" { + if typ.String() == "[]github.com/traefik/traefik/v3/pkg/tls.FileOrContent" { return "[]string" } @@ -103,8 +103,8 @@ func cleanType(typ types.Type, base string) string { return strings.ReplaceAll(typ.String(), base+".", "") } - if strings.Contains(typ.String(), "github.com/traefik/traefik/v2/pkg/") { - return strings.ReplaceAll(typ.String(), "github.com/traefik/traefik/v2/pkg/", "") + if strings.Contains(typ.String(), "github.com/traefik/traefik/v3/pkg/") { + return strings.ReplaceAll(typ.String(), "github.com/traefik/traefik/v3/pkg/", "") } return typ.String() @@ -114,9 +114,9 @@ func cleanPackage(src string) string { switch src { case "github.com/traefik/paerser/types": return "" - case "github.com/traefik/traefik/v2/pkg/tls": + case "github.com/traefik/traefik/v3/pkg/tls": return path.Join(destModuleName, destPkg, "tls") - case "github.com/traefik/traefik/v2/pkg/types": + case "github.com/traefik/traefik/v3/pkg/types": return path.Join(destModuleName, destPkg, "types") default: return src diff --git a/cmd/traefik/logger.go b/cmd/traefik/logger.go index 27f31917044029b8cde269a3963b5cdcf678d59f..4a3a10893af1c7fbf0294a150c468a993dd5f5e8 100644 --- a/cmd/traefik/logger.go +++ b/cmd/traefik/logger.go @@ -11,8 +11,8 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/sirupsen/logrus" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/logs" ) func init() { diff --git a/cmd/traefik/plugins.go b/cmd/traefik/plugins.go index f94535f925a627171a5b1fa738bf92ee783aa22e..41c9bff602e70ca8d5623212c92822830c74de7c 100644 --- a/cmd/traefik/plugins.go +++ b/cmd/traefik/plugins.go @@ -3,8 +3,8 @@ package main import ( "fmt" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/plugins" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/plugins" ) const outputDir = "./plugins-storage/" diff --git a/cmd/traefik/traefik.go b/cmd/traefik/traefik.go index 9d02567954568be2cdc27f93b8c8449cb83f8a20..bd3daf14f274ada660251324a0c19d5526329d43 100644 --- a/cmd/traefik/traefik.go +++ b/cmd/traefik/traefik.go @@ -21,31 +21,32 @@ import ( "github.com/sirupsen/logrus" "github.com/spiffe/go-spiffe/v2/workloadapi" "github.com/traefik/paerser/cli" - "github.com/traefik/traefik/v2/cmd" - "github.com/traefik/traefik/v2/cmd/healthcheck" - cmdVersion "github.com/traefik/traefik/v2/cmd/version" - tcli "github.com/traefik/traefik/v2/pkg/cli" - "github.com/traefik/traefik/v2/pkg/collector" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/metrics" - "github.com/traefik/traefik/v2/pkg/middlewares/accesslog" - "github.com/traefik/traefik/v2/pkg/provider/acme" - "github.com/traefik/traefik/v2/pkg/provider/aggregator" - "github.com/traefik/traefik/v2/pkg/provider/hub" - "github.com/traefik/traefik/v2/pkg/provider/tailscale" - "github.com/traefik/traefik/v2/pkg/provider/traefik" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/server" - "github.com/traefik/traefik/v2/pkg/server/middleware" - "github.com/traefik/traefik/v2/pkg/server/service" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/tracing" - "github.com/traefik/traefik/v2/pkg/tracing/jaeger" - "github.com/traefik/traefik/v2/pkg/types" - "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/cmd" + "github.com/traefik/traefik/v3/cmd/healthcheck" + cmdVersion "github.com/traefik/traefik/v3/cmd/version" + tcli "github.com/traefik/traefik/v3/pkg/cli" + "github.com/traefik/traefik/v3/pkg/collector" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/middlewares/accesslog" + "github.com/traefik/traefik/v3/pkg/provider/acme" + "github.com/traefik/traefik/v3/pkg/provider/aggregator" + "github.com/traefik/traefik/v3/pkg/provider/hub" + "github.com/traefik/traefik/v3/pkg/provider/tailscale" + "github.com/traefik/traefik/v3/pkg/provider/traefik" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/server" + "github.com/traefik/traefik/v3/pkg/server/middleware" + "github.com/traefik/traefik/v3/pkg/server/service" + "github.com/traefik/traefik/v3/pkg/tcp" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/tracing/jaeger" + "github.com/traefik/traefik/v3/pkg/types" + "github.com/traefik/traefik/v3/pkg/version" ) func main() { @@ -192,9 +193,14 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err tsProviders := initTailscaleProviders(staticConfiguration, &providerAggregator) + // Metrics + + metricRegistries := registerMetricClients(staticConfiguration.Metrics) + metricsRegistry := metrics.NewMultiRegistry(metricRegistries) + // Entrypoints - serverEntryPointsTCP, err := server.NewTCPEntryPoints(staticConfiguration.EntryPoints, staticConfiguration.HostResolver) + serverEntryPointsTCP, err := server.NewTCPEntryPoints(staticConfiguration.EntryPoints, staticConfiguration.HostResolver, metricsRegistry) if err != nil { return nil, err } @@ -242,11 +248,6 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err } } - // Metrics - - metricRegistries := registerMetricClients(staticConfiguration.Metrics) - metricsRegistry := metrics.NewMultiRegistry(metricRegistries) - // Service manager factory var spiffeX509Source *workloadapi.X509Source @@ -269,6 +270,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err } roundTripperManager := service.NewRoundTripperManager(spiffeX509Source) + dialerManager := tcp.NewDialerManager(spiffeX509Source) acmeHTTPHandler := getHTTPChallengeHandler(acmeProviders, httpChallengeProvider) managerFactory := service.NewManagerFactory(*staticConfiguration, routinesPool, metricsRegistry, roundTripperManager, acmeHTTPHandler) @@ -278,7 +280,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err tracer := setupTracing(staticConfiguration.Tracing) chainBuilder := middleware.NewChainBuilder(metricsRegistry, accessLog, tracer) - routerFactory := server.NewRouterFactory(*staticConfiguration, managerFactory, tlsManager, chainBuilder, pluginBuilder, metricsRegistry) + routerFactory := server.NewRouterFactory(*staticConfiguration, managerFactory, tlsManager, chainBuilder, pluginBuilder, metricsRegistry, dialerManager) // Watcher @@ -295,7 +297,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err tlsManager.UpdateConfigs(ctx, conf.TLS.Stores, conf.TLS.Options, conf.TLS.Certificates) gauge := metricsRegistry.TLSCertsNotAfterTimestampGauge() - for _, certificate := range tlsManager.GetCertificates() { + for _, certificate := range tlsManager.GetServerCertificates() { appendCertMetric(gauge, certificate) } }) @@ -309,6 +311,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err // Server Transports watcher.AddListener(func(conf dynamic.Configuration) { roundTripperManager.Update(conf.HTTP.ServersTransports) + dialerManager.Update(conf.TCP.ServersTransports) }) // Switch router @@ -520,16 +523,6 @@ func registerMetricClients(metricsConfig *types.Metrics) []metrics.Registry { Msg("Configured StatsD metrics") } - if metricsConfig.InfluxDB != nil { - logger := log.With().Str(logs.MetricsProviderName, "influxdb").Logger() - - registries = append(registries, metrics.RegisterInfluxDB(logger.WithContext(context.Background()), metricsConfig.InfluxDB)) - logger.Debug(). - Str("address", metricsConfig.InfluxDB.Address). - Str("pushInterval", metricsConfig.InfluxDB.PushInterval.String()). - Msg("Configured InfluxDB metrics") - } - if metricsConfig.InfluxDB2 != nil { logger := log.With().Str(logs.MetricsProviderName, "influxdb2").Logger() diff --git a/cmd/traefik/traefik_test.go b/cmd/traefik/traefik_test.go index c1d67705871f11c3b20a72e274fc55e77c007390..6dacb7507f1d706794e8394e7fae17591d3b0501 100644 --- a/cmd/traefik/traefik_test.go +++ b/cmd/traefik/traefik_test.go @@ -9,7 +9,7 @@ import ( "github.com/go-kit/kit/metrics" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/static" ) // FooCert is a PEM-encoded TLS cert. diff --git a/cmd/version/version.go b/cmd/version/version.go index 03557ff58a1fd548418ebbb53a711d84eed56c19..172dfb338aeb3ba2f5e9d489165fca60ffd1bb47 100644 --- a/cmd/version/version.go +++ b/cmd/version/version.go @@ -8,7 +8,7 @@ import ( "text/template" "github.com/traefik/paerser/cli" - "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/pkg/version" ) var versionTemplate = `Version: {{.Version}} diff --git a/contrib/grafana/traefik-kubernetes.json b/contrib/grafana/traefik-kubernetes.json index 75cf074fb092e4a0835dc6e69a79030007d92d8d..4e463b5021d044d83ec1c1055ad8a93f1acc3890 100644 --- a/contrib/grafana/traefik-kubernetes.json +++ b/contrib/grafana/traefik-kubernetes.json @@ -15,7 +15,7 @@ "type": "grafana", "id": "grafana", "name": "Grafana", - "version": "9.2.2" + "version": "9.3.1" }, { "type": "panel", @@ -64,8 +64,10 @@ } ] }, - "editable": true, + "description": "Official dashboard for Traefik on Kubernetes", + "editable": false, "fiscalYearStartMonth": 0, + "gnetId": 17347, "graphTooltip": 0, "id": null, "links": [], @@ -133,7 +135,7 @@ }, "textMode": "auto" }, - "pluginVersion": "9.2.2", + "pluginVersion": "9.3.1", "targets": [ { "datasource": { @@ -470,7 +472,7 @@ } ] }, - "unit": "ms" + "unit": "s" }, "overrides": [] }, @@ -818,7 +820,7 @@ "type": "row" }, { - "collapsed": true, + "collapsed": false, "gridPos": { "h": 1, "w": 24, @@ -826,607 +828,706 @@ "y": 18 }, "id": 16, - "panels": [ + "panels": [], + "title": "HTTP Details", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 8, + "x": 0, + "y": 19 + }, + "id": 17, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "reqps" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 27 + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code=~\"2..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}}[{{code}}] on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "2xx over 5 min", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" }, - "id": 17, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Mean", - "sortDesc": true + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false }, - "tooltip": { - "mode": "multi", - "sort": "desc" + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" } }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null }, - "editorMode": "code", - "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code=~\"2..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", - "legendFormat": "{{method}}[{{code}}] on {{service}}", - "range": true, - "refId": "A" - } + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 8, + "x": 8, + "y": 19 + }, + "id": 18, + "options": { + "legend": { + "calcs": [ + "mean", + "max" ], - "title": "2xx over 5 min", - "type": "timeseries" + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisGridShow": true, - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "reqps" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 27 + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code=~\"5..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}}[{{code}}] on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "5xx over 5 min", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" }, - "id": 18, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Mean", - "sortDesc": true + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false }, - "tooltip": { - "mode": "multi", - "sort": "desc" + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" } }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null }, - "editorMode": "code", - "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code=~\"5..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", - "legendFormat": "{{method}}[{{code}}] on {{service}}", - "range": true, - "refId": "A" - } + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 12, + "w": 8, + "x": 16, + "y": 19 + }, + "id": 19, + "options": { + "legend": { + "calcs": [ + "mean", + "max" ], - "title": "5xx over 5 min", - "type": "timeseries" + "displayMode": "table", + "placement": "bottom", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisGridShow": true, - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "reqps" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 35 + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code!~\"2..|5..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}}[{{code}}] on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "Other codes over 5 min", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" }, - "id": 19, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Mean", - "sortDesc": true + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false }, - "tooltip": { - "mode": "multi", - "sort": "desc" + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" } }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null }, - "editorMode": "code", - "expr": "topk(15,\n label_replace(\n sum by (service,method,code) \n (rate(traefik_service_requests_total{service=~\"$service.*\",code!~\"2..|5..\",protocol=\"http\"}[5m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", - "legendFormat": "{{method}}[{{code}}] on {{service}}", - "range": true, - "refId": "A" - } + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 31 + }, + "id": 20, + "options": { + "legend": { + "calcs": [ + "mean", + "max" ], - "title": "Other codes over 5 min", - "type": "timeseries" + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisGridShow": true, - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "binBps" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 35 + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method) \n (rate(traefik_service_requests_bytes_total{service=~\"$service.*\",protocol=\"http\"}[1m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}} on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "Requests Size", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" }, - "id": 20, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Mean", - "sortDesc": true + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false }, - "tooltip": { - "mode": "multi", - "sort": "desc" + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" } }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null }, - "editorMode": "code", - "expr": "topk(15,\n label_replace(\n sum by (service,method) \n (rate(traefik_service_requests_bytes_total{service=~\"$service.*\",protocol=\"http\"}[1m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", - "legendFormat": "{{method}} on {{service}}", - "range": true, - "refId": "A" - } + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 31 + }, + "id": 24, + "options": { + "legend": { + "calcs": [ + "mean", + "max" ], - "title": "Requests Size", - "type": "timeseries" + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method) \n (rate(traefik_service_responses_bytes_total{service=~\"$service.*\",protocol=\"http\"}[1m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}} on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "Responses Size", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 43 - }, - "id": 2, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Max", - "sortDesc": true + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" }, - "tooltip": { - "mode": "multi", - "sort": "desc" + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" } }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null }, - "editorMode": "code", - "expr": "label_replace(\n sum(traefik_service_open_connections{service=~\"$service.*\"}) by (service),\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")", - "legendFormat": "{{service}}", - "range": true, - "refId": "A" - } + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 39 + }, + "id": 2, + "options": { + "legend": { + "calcs": [ + "mean", + "max" ], - "title": "Connections per Service", - "type": "timeseries" + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Max", + "sortDesc": true }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ { "datasource": { "type": "prometheus", "uid": "${DS_PROMETHEUS}" }, - "description": "", - "fieldConfig": { - "defaults": { - "color": { - "mode": "palette-classic" - }, - "custom": { - "axisCenteredZero": false, - "axisColorMode": "text", - "axisLabel": "", - "axisPlacement": "auto", - "barAlignment": 0, - "drawStyle": "line", - "fillOpacity": 0, - "gradientMode": "none", - "hideFrom": { - "legend": false, - "tooltip": false, - "viz": false - }, - "lineInterpolation": "linear", - "lineWidth": 1, - "pointSize": 5, - "scaleDistribution": { - "type": "linear" - }, - "showPoints": "auto", - "spanNulls": false, - "stacking": { - "group": "A", - "mode": "none" - }, - "thresholdsStyle": { - "mode": "off" - } - }, - "mappings": [], - "thresholds": { - "mode": "absolute", - "steps": [ - { - "color": "green", - "value": null - }, - { - "color": "red", - "value": 80 - } - ] - }, - "unit": "short" - }, - "overrides": [] - }, - "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 43 + "editorMode": "code", + "expr": "label_replace(\n sum(traefik_service_open_connections{service=~\"$service.*\"}) by (service),\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")", + "legendFormat": "{{service}}", + "range": true, + "refId": "A" + } + ], + "title": "Connections per Service", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" }, - "id": 21, - "options": { - "legend": { - "calcs": [ - "mean", - "max" - ], - "displayMode": "table", - "placement": "right", - "showLegend": true, - "sortBy": "Max", - "sortDesc": true + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false }, - "tooltip": { - "mode": "multi", - "sort": "desc" + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" } }, - "targets": [ - { - "datasource": { - "type": "prometheus", - "uid": "${DS_PROMETHEUS}" + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null }, - "editorMode": "code", - "expr": "sum(traefik_entrypoint_open_connections{entrypoint=~\"$entrypoint\"}) by (entrypoint)\n", - "legendFormat": "{{entrypoint}}", - "range": true, - "refId": "A" - } + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 39 + }, + "id": 21, + "options": { + "legend": { + "calcs": [ + "mean", + "max" ], - "title": "Connections per Entrypoint", - "type": "timeseries" + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Max", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "sum(traefik_entrypoint_open_connections{entrypoint=~\"$entrypoint\"}) by (entrypoint)\n", + "legendFormat": "{{entrypoint}}", + "range": true, + "refId": "A" } ], - "title": "HTTP Details", - "type": "row" + "title": "Connections per Entrypoint", + "type": "timeseries" } ], "refresh": false, @@ -1444,7 +1545,8 @@ "hide": 0, "includeAll": false, "multi": false, - "name": "datasource", + "name": "DS_PROMETHEUS", + "label": "datasource", "options": [], "query": "prometheus", "refresh": 1, @@ -1504,8 +1606,8 @@ }, "timepicker": {}, "timezone": "", - "title": "Traefik Official Standalone Dashboard", + "title": "Traefik Official Kubernetes Dashboard", "uid": "n5bu_kv4k", - "version": 3, + "version": 6, "weekStart": "" } diff --git a/contrib/grafana/traefik.json b/contrib/grafana/traefik.json index 75cf074fb092e4a0835dc6e69a79030007d92d8d..5c3d140eef1aacb62b9e7aa1938680f3c0980fb7 100644 --- a/contrib/grafana/traefik.json +++ b/contrib/grafana/traefik.json @@ -15,7 +15,7 @@ "type": "grafana", "id": "grafana", "name": "Grafana", - "version": "9.2.2" + "version": "9.3.1" }, { "type": "panel", @@ -64,8 +64,10 @@ } ] }, - "editable": true, + "description": "Official dashboard for Standalone Traefik", + "editable": false, "fiscalYearStartMonth": 0, + "gnetId": 17346, "graphTooltip": 0, "id": null, "links": [], @@ -133,7 +135,7 @@ }, "textMode": "auto" }, - "pluginVersion": "9.2.2", + "pluginVersion": "9.3.1", "targets": [ { "datasource": { @@ -470,7 +472,7 @@ } ] }, - "unit": "ms" + "unit": "s" }, "overrides": [] }, @@ -669,8 +671,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" } ] }, @@ -764,8 +765,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" } ] }, @@ -873,8 +873,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -887,10 +886,10 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 12, + "h": 12, + "w": 8, "x": 0, - "y": 27 + "y": 19 }, "id": 17, "options": { @@ -900,7 +899,7 @@ "max" ], "displayMode": "table", - "placement": "right", + "placement": "bottom", "showLegend": true, "sortBy": "Mean", "sortDesc": true @@ -973,8 +972,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -987,10 +985,10 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 12, - "x": 12, - "y": 27 + "h": 12, + "w": 8, + "x": 8, + "y": 19 }, "id": 18, "options": { @@ -1000,7 +998,7 @@ "max" ], "displayMode": "table", - "placement": "right", + "placement": "bottom", "showLegend": true, "sortBy": "Mean", "sortDesc": true @@ -1073,8 +1071,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -1087,10 +1084,10 @@ "overrides": [] }, "gridPos": { - "h": 8, - "w": 12, - "x": 0, - "y": 35 + "h": 12, + "w": 8, + "x": 16, + "y": 19 }, "id": 19, "options": { @@ -1100,7 +1097,7 @@ "max" ], "displayMode": "table", - "placement": "right", + "placement": "bottom", "showLegend": true, "sortBy": "Mean", "sortDesc": true @@ -1173,8 +1170,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -1189,8 +1185,8 @@ "gridPos": { "h": 8, "w": 12, - "x": 12, - "y": 35 + "x": 0, + "y": 31 }, "id": 20, "options": { @@ -1226,6 +1222,105 @@ "title": "Requests Size", "type": "timeseries" }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisCenteredZero": false, + "axisColorMode": "text", + "axisGridShow": true, + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green" + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "binBps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 31 + }, + "id": 24, + "options": { + "legend": { + "calcs": [ + "mean", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "sortBy": "Mean", + "sortDesc": true + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "expr": "topk(15,\n label_replace(\n sum by (service,method) \n (rate(traefik_service_responses_bytes_total{service=~\"$service.*\",protocol=\"http\"}[1m])) > 0,\n \"service\", \"$1\", \"service\", \"([^-]+-[^-]+).*\")\n)", + "legendFormat": "{{method}} on {{service}}", + "range": true, + "refId": "A" + } + ], + "title": "Responses Size", + "type": "timeseries" + }, { "datasource": { "type": "prometheus", @@ -1272,8 +1367,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -1289,7 +1383,7 @@ "h": 8, "w": 12, "x": 0, - "y": 43 + "y": 39 }, "id": 2, "options": { @@ -1371,8 +1465,7 @@ "mode": "absolute", "steps": [ { - "color": "green", - "value": null + "color": "green" }, { "color": "red", @@ -1388,7 +1481,7 @@ "h": 8, "w": 12, "x": 12, - "y": 43 + "y": 39 }, "id": 21, "options": { @@ -1444,7 +1537,8 @@ "hide": 0, "includeAll": false, "multi": false, - "name": "datasource", + "name": "DS_PROMETHEUS", + "label": "datasource", "options": [], "query": "prometheus", "refresh": 1, @@ -1491,7 +1585,7 @@ "refId": "StandardVariableQuery" }, "refresh": 2, - "regex": "/([^-]+-[^-]+).*/", + "regex": "", "skipUrlSync": false, "sort": 1, "type": "query" @@ -1505,7 +1599,7 @@ "timepicker": {}, "timezone": "", "title": "Traefik Official Standalone Dashboard", - "uid": "n5bu_kv4k", - "version": 3, + "uid": "n5bu_kv45", + "version": 6, "weekStart": "" } diff --git a/docs/content/contributing/maintainers.md b/docs/content/contributing/maintainers.md index eee5ec69a59dc34123a9036b2c9b906612c67e80..cfad7eb7a9931f5f9aa3b4ce67041278f39ca1a8 100644 --- a/docs/content/contributing/maintainers.md +++ b/docs/content/contributing/maintainers.md @@ -107,7 +107,6 @@ The `status/*` labels represent the desired state in the workflow. * `area/provider/kv`: KV related. * `area/provider/marathon`: Marathon related. * `area/provider/mesos`: Mesos related. -* `area/provider/rancher`: Rancher related. * `area/provider/servicefabric`: Azure service fabric related. * `area/provider/zk`: Zoo Keeper related. * `area/rules`: Rules related. diff --git a/docs/content/contributing/submitting-pull-requests.md b/docs/content/contributing/submitting-pull-requests.md index ec26125f9bbf7f01bbb376b668d4a730ad2ebb2b..855c04cf4570fb2e9518e7a898f6ed0406b2377e 100644 --- a/docs/content/contributing/submitting-pull-requests.md +++ b/docs/content/contributing/submitting-pull-requests.md @@ -56,6 +56,7 @@ Merging a PR requires the following steps to be completed before it is merged au * Do not open the PR from an organization repository. * Keep "allows edit from maintainer" checked. * Use semantic line breaks for documentation. + * Ensure your PR is not a draft. We do not review drafts, but do answer questions and confer with developers on them as needed. * Pass the validation check. * Pass all tests. * Receive 3 approving reviews maintainers. diff --git a/docs/content/deprecation/features.md b/docs/content/deprecation/features.md index 6e8c1f74057014261a43f965b12c9eaa4fd5a470..fa41c56b058e146a093d71a03f78ff9955324190 100644 --- a/docs/content/deprecation/features.md +++ b/docs/content/deprecation/features.md @@ -2,4 +2,12 @@ This page is maintained and updated periodically to reflect our roadmap and any decisions around feature deprecation. -There is no feature deprecation in Traefik v3 for now. +| Feature | Deprecated | End of Support | Removal | +|-----------------------------------------------------------------------------------------------------|------------|----------------|---------| +| [Kubernetes CRDs API Version `traefik.io/v1alpha1`](#kubernetes-crds-api-version-traefikiov1alpha1) | N/A | N/A | 3.0 | + +## Impact + +### Kubernetes CRDs API Version `traefik.io/v1alpha1` + +The newly introduced Kubernetes CRD API Version `traefik.io/v1alpha1` will subsequently be removed in Traefik v3. The following version will be `traefik.io/v1`. diff --git a/docs/content/getting-started/faq.md b/docs/content/getting-started/faq.md index 01b33f6398ac242516b976d07edee89b4cac5260..1ae3def8e5ae44c551e381daa6943d3da225764b 100644 --- a/docs/content/getting-started/faq.md +++ b/docs/content/getting-started/faq.md @@ -181,3 +181,23 @@ and the message should help in figuring out the mistake(s) in the configuration, When using the file provider, one easy way to check if the dynamic configuration is well-formed is to validate it with the [JSON Schema of the dynamic configuration](https://json.schemastore.org/traefik-v2-file-provider.json). + +## Why does Let's Encrypt wildcard certificate renewal/generation with DNS challenge fail? + +If you're trying to renew wildcard certificates, with DNS challenge, +and you're getting errors such as: + +```txt +msg="Error renewing certificate from LE: {example.com [*.example.com]}" +providerName=letsencrypt.acme error="error: one or more domains had a problem: +[example.com] acme: error presenting token: gandiv5: unexpected authZone example.com. for fqdn example.com." +``` + +then it could be due to `CNAME` support. + +In which case, you should make sure your infrastructure is properly set up for a +`DNS` challenge that does not rely on `CNAME`, and you should try disabling `CNAME` support with: + +```bash +LEGO_DISABLE_CNAME_SUPPORT=true +``` diff --git a/docs/content/getting-started/install-traefik.md b/docs/content/getting-started/install-traefik.md index 9e4926fc0fc081b58f3db4a31f69b18d894fef16..a0a5df6ea7caab0f01b82495acc6a742b91b61c5 100644 --- a/docs/content/getting-started/install-traefik.md +++ b/docs/content/getting-started/install-traefik.md @@ -16,8 +16,8 @@ You can install Traefik with the following flavors: Choose one of the [official Docker images](https://hub.docker.com/_/traefik) and run it with one sample configuration file: -* [YAML](https://raw.githubusercontent.com/traefik/traefik/v2.9/traefik.sample.yml) -* [TOML](https://raw.githubusercontent.com/traefik/traefik/v2.9/traefik.sample.toml) +* [YAML](https://raw.githubusercontent.com/traefik/traefik/v3.0/traefik.sample.yml) +* [TOML](https://raw.githubusercontent.com/traefik/traefik/v3.0/traefik.sample.toml) ```bash docker run -d -p 8080:8080 -p 80:80 \ @@ -121,7 +121,7 @@ by defining and applying an IngressRoute CRD (`kubectl apply -f dashboard.yaml`) ```yaml # dashboard.yaml -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: dashboard diff --git a/docs/content/getting-started/quick-start.md b/docs/content/getting-started/quick-start.md index e1883040dab04d785d5ed0efe4220342dc4e1c72..e4007910d7d4a0b25475e148897ae7e4b27b9aa4 100644 --- a/docs/content/getting-started/quick-start.md +++ b/docs/content/getting-started/quick-start.md @@ -1,11 +1,11 @@ --- title: "Traefik Getting Started Quickly" -description: "Looking to get started with Traefik Proxy quickly? Read the technical documentation to learn a simple use case that leverages Docker." +description: "Looking to get started with Traefik Proxy quickly? Read the technical documentation to see a basic use case that leverages Docker." --- # Quick Start -A Simple Use Case Using Docker +A Basic Use Case Using Docker {: .subtitle }  @@ -19,9 +19,9 @@ version: '3' services: reverse-proxy: - # The official v2 Traefik docker image + # The official v3 Traefik Docker image image: traefik:v3.0 - # Enables the web UI and tells Traefik to listen to docker + # Enables the web UI and tells Traefik to listen to Docker command: --api.insecure=true --providers.docker ports: # The HTTP port @@ -63,7 +63,7 @@ services: - "traefik.http.routers.whoami.rule=Host(`whoami.docker.localhost`)" ``` -The above defines `whoami`: a simple web service that outputs information about the machine it is deployed on (its IP address, host, and so on). +The above defines [`whoami`](https://github.com/traefik/whoami "Link to whoami app on GitHub"), a web service that outputs information about the machine it is deployed on (its IP address, host, etc.). Start the `whoami` service with the following command: @@ -71,9 +71,9 @@ Start the `whoami` service with the following command: docker-compose up -d whoami ``` -Go back to your browser (`http://localhost:8080/api/rawdata`) and see that Traefik has automatically detected the new container and updated its own configuration. +Browse `http://localhost:8080/api/rawdata` and see that Traefik has automatically detected the new container and updated its own configuration. -When Traefik detects new services, it creates the corresponding routes so you can call them ... _let's see!_ (Here, we're using curl) +When Traefik detects new services, it creates the corresponding routes, so you can call them ... _let's see!_ (Here, we're using curl) ```shell curl -H Host:whoami.docker.localhost http://127.0.0.1 @@ -95,7 +95,7 @@ Run more instances of your `whoami` service with the following command: docker-compose up -d --scale whoami=2 ``` -Go back to your browser (`http://localhost:8080/api/rawdata`) and see that Traefik has automatically detected the new instance of the container. +Browse to `http://localhost:8080/api/rawdata` and see that Traefik has automatically detected the new instance of the container. Finally, see that Traefik load-balances between the two instances of your service by running the following command twice: @@ -119,6 +119,6 @@ IP: 172.27.0.4 !!! question "Where to Go Next?" - Now that you have a basic understanding of how Traefik can automatically create the routes to your services and load balance them, it is time to dive into [the documentation](/) and let Traefik work for you! + Now that you have a basic understanding of how Traefik can automatically create the routes to your services and load balance them, it is time to dive into [the documentation](/ "Link to the docs landing page") and let Traefik work for you! {!traefik-for-business-applications.md!} diff --git a/docs/content/https/acme.md b/docs/content/https/acme.md index d3fc20997447a5293c7a0cf05c33a3804b3da5ed..640e0098ab6a492299d06da064598e2cebdbea9f 100644 --- a/docs/content/https/acme.md +++ b/docs/content/https/acme.md @@ -11,7 +11,11 @@ Automatic HTTPS You can configure Traefik to use an ACME provider (like Let's Encrypt) for automatic certificate generation. !!! warning "Let's Encrypt and Rate Limiting" - Note that Let's Encrypt API has [rate limiting](https://letsencrypt.org/docs/rate-limits). + Note that Let's Encrypt API has [rate limiting](https://letsencrypt.org/docs/rate-limits). These last up to __one week__, and can not be overridden. + + When running Traefik in a container this file should be persisted across restarts. + If Traefik requests new certificates each time it starts up, a crash-looping container can quickly reach Let's Encrypt's ratelimits. + To configure where certificates are stored, please take a look at the [storage](#storage) configuration. Use Let's Encrypt staging server with the [`caServer`](#caserver) configuration option when experimenting to avoid hitting this limit too fast. @@ -279,8 +283,19 @@ Use the `DNS-01` challenge to generate and renew ACME certificates by provisioni # ... ``` - !!! important - A `provider` is mandatory. +!!! warning "`CNAME` support" + + `CNAME` are supported (and sometimes even [encouraged](https://letsencrypt.org/2019/10/09/onboarding-your-customers-with-lets-encrypt-and-acme.html#the-advantages-of-a-cname)), + but there are a few cases where they can be [problematic](../../getting-started/faq/#why-does-lets-encrypt-wildcard-certificate-renewalgeneration-with-dns-challenge-fail). + + If needed, `CNAME` support can be disabled with the following environment variable: + + ```bash + LEGO_DISABLE_CNAME_SUPPORT=true + ``` + +!!! important + A `provider` is mandatory. #### `providers` @@ -315,6 +330,7 @@ For complete details, refer to your provider's _Additional configuration_ link. | [deSEC](https://desec.io) | `desec` | `DESEC_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/desec) | | [DigitalOcean](https://www.digitalocean.com) | `digitalocean` | `DO_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/digitalocean) | | [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) | +| [dnsHome.de](https://www.dnshome.de) | `dnsHomede` | `DNSHOMEDE_CREDENTIALS` | [Additional configuration](https://go-acme.github.io/lego/dns/dnshomede) | | [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) | | [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dnspod) | | [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/dode) | @@ -350,6 +366,7 @@ For complete details, refer to your provider's _Additional configuration_ link. | [ionos](https://ionos.com/) | `ionos` | `IONOS_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/ionos) | | [iwantmyname](https://iwantmyname.com) | `iwantmyname` | `IWANTMYNAME_USERNAME` , `IWANTMYNAME_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/iwantmyname) | | [Joker.com](https://joker.com) | `joker` | `JOKER_API_MODE` with `JOKER_API_KEY` or `JOKER_USERNAME`, `JOKER_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/joker) | +| [Liara](https://liara.ir) | `liara` | `LIARA_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/liara) | | [Lightsail](https://aws.amazon.com/lightsail/) | `lightsail` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `DNS_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/lightsail) | | [Linode v4](https://www.linode.com) | `linode` | `LINODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/linode) | | [Liquid Web](https://www.liquidweb.com/) | `liquidweb` | `LIQUID_WEB_PASSWORD`, `LIQUID_WEB_USERNAME`, `LIQUID_WEB_ZONE` | [Additional configuration](https://go-acme.github.io/lego/dns/liquidweb) | @@ -388,6 +405,7 @@ For complete details, refer to your provider's _Additional configuration_ link. | [Tencent Cloud DNS](https://cloud.tencent.com/product/cns) | `tencentcloud` | `TENCENTCLOUD_SECRET_ID`, `TENCENTCLOUD_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/tencentcloud) | | [TransIP](https://www.transip.nl/) | `transip` | `TRANSIP_ACCOUNT_NAME`, `TRANSIP_PRIVATE_KEY_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/transip) | | [UKFast SafeDNS](https://www.ans.co.uk/cloud-and-infrastructure/dedicated-servers/dns-management/) | `safedns` | `SAFEDNS_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/safedns) | +| [Ultradns](https://neustarsecurityservices.com/dns-services) | `ultradns` | `ULTRADNS_USERNAME`, `ULTRADNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/ultradns) | | [Variomedia](https://www.variomedia.de/) | `variomedia` | `VARIOMEDIA_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/variomedia) | | [VegaDNS](https://github.com/shupp/VegaDNS-API) | `vegadns` | `SECRET_VEGADNS_KEY`, `SECRET_VEGADNS_SECRET`, `VEGADNS_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/vegadns) | | [Vercel](https://vercel.com) | `vercel` | `VERCEL_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vercel) | @@ -396,6 +414,7 @@ For complete details, refer to your provider's _Additional configuration_ link. | [VK Cloud](https://mcs.mail.ru/) | `vkcloud` | `VK_CLOUD_PASSWORD`, `VK_CLOUD_PROJECT_ID`, `VK_CLOUD_USERNAME` | [Additional configuration](https://go-acme.github.io/lego/dns/vkcloud) | | [Vscale](https://vscale.io/) | `vscale` | `VSCALE_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/vscale) | | [VULTR](https://www.vultr.com) | `vultr` | `VULTR_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/vultr) | +| [Websupport](https://websupport.sk) | `websupport` | `WEBSUPPORT_API_KEY`, `WEBSUPPORT_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/websupport) | | [WEDOS](https://www.wedos.com) | `wedos` | `WEDOS_USERNAME`, `WEDOS_WAPI_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/wedos) | | [Yandex Cloud](https://cloud.yandex.com/en/) | `yandexcloud` | `YANDEX_CLOUD_FOLDER_ID`, `YANDEX_CLOUD_IAM_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandexcloud) | | [Yandex](https://yandex.com) | `yandex` | `YANDEX_PDD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandex) | diff --git a/docs/content/https/include-acme-multiple-domains-example.md b/docs/content/https/include-acme-multiple-domains-example.md index 8107eb24f60e8e0c03492165da4b6f2e50c44ea4..e60d08f1cfa97174e9cb3037898eb0b7a48d6264 100644 --- a/docs/content/https/include-acme-multiple-domains-example.md +++ b/docs/content/https/include-acme-multiple-domains-example.md @@ -22,7 +22,7 @@ deploy: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: blogtls @@ -43,27 +43,6 @@ spec: - '*.example.org' ``` -```json tab="Marathon" -labels: { - "traefik.http.routers.blog.rule": "Host(`example.com`) && Path(`/blog`)", - "traefik.http.routers.blog.tls": "true", - "traefik.http.routers.blog.tls.certresolver": "myresolver", - "traefik.http.routers.blog.tls.domains[0].main": "example.com", - "traefik.http.routers.blog.tls.domains[0].sans": "*.example.com", - "traefik.http.services.blog-svc.loadbalancer.server.port": "8080" -} -``` - -```yaml tab="Rancher" -## Dynamic configuration -labels: - - traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`) - - traefik.http.routers.blog.tls=true - - traefik.http.routers.blog.tls.certresolver=myresolver - - traefik.http.routers.blog.tls.domains[0].main=example.org - - traefik.http.routers.blog.tls.domains[0].sans=*.example.org -``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: diff --git a/docs/content/https/include-acme-multiple-domains-from-rule-example.md b/docs/content/https/include-acme-multiple-domains-from-rule-example.md index 01252360b9a49f8bc6b4c022a2d512338ae2b016..1052228c3f3eeff0926c962e240af10e3ac3697f 100644 --- a/docs/content/https/include-acme-multiple-domains-from-rule-example.md +++ b/docs/content/https/include-acme-multiple-domains-from-rule-example.md @@ -18,7 +18,7 @@ deploy: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: blogtls @@ -35,23 +35,6 @@ spec: certResolver: myresolver ``` -```json tab="Marathon" -labels: { - "traefik.http.routers.blog.rule": "(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`)", - "traefik.http.routers.blog.tls": "true", - "traefik.http.routers.blog.tls.certresolver": "myresolver", - "traefik.http.services.blog-svc.loadbalancer.server.port": "8080" -} -``` - -```yaml tab="Rancher" -## Dynamic configuration -labels: - - traefik.http.routers.blog.rule=(Host(`example.com`) && Path(`/blog`)) || Host(`blog.example.org`) - - traefik.http.routers.blog.tls=true - - traefik.http.routers.blog.tls.certresolver=myresolver -``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: diff --git a/docs/content/https/include-acme-single-domain-example.md b/docs/content/https/include-acme-single-domain-example.md index 30bfa92292ecccff3fc7a740b45eb5aad17ac7c3..f6fad9af9cc4c9f3f2b77f23a8d4305de0c03602 100644 --- a/docs/content/https/include-acme-single-domain-example.md +++ b/docs/content/https/include-acme-single-domain-example.md @@ -18,7 +18,7 @@ deploy: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: blogtls @@ -35,23 +35,6 @@ spec: certResolver: myresolver ``` -```json tab="Marathon" -labels: { - "traefik.http.routers.blog.rule": "Host(`example.com`) && Path(`/blog`)", - "traefik.http.routers.blog.tls": "true", - "traefik.http.routers.blog.tls.certresolver": "myresolver", - "traefik.http.services.blog-svc.loadbalancer.server.port": "8080" -} -``` - -```yaml tab="Rancher" -## Dynamic configuration -labels: - - traefik.http.routers.blog.rule=Host(`example.com`) && Path(`/blog`) - - traefik.http.routers.blog.tls=true - - traefik.http.routers.blog.tls.certresolver=myresolver -``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: diff --git a/docs/content/https/spiffe.md b/docs/content/https/spiffe.md index 9d70e5a2091148d4d92f9fa572f761ffab10c19f..cf7a9cf885fc4a98d891a1efbe2a2df42f984836 100644 --- a/docs/content/https/spiffe.md +++ b/docs/content/https/spiffe.md @@ -28,7 +28,9 @@ The `workloadAPIAddr` configuration defines the address of the SPIFFE [Workload !!! info "Enabling SPIFFE in ServersTransports" Enabling SPIFFE does not imply that backend connections are going to use it automatically. - Each [ServersTransport](../routing/services/index.md#serverstransport_1) that is meant to be secured with SPIFFE must [explicitly](../routing/services/index.md#spiffe) enable it. + Each [ServersTransport](../routing/services/index.md#serverstransport_1) or [TCPServersTransport](../routing/services/index.md#serverstransport_2), + that is meant to be secured with SPIFFE, + must explicitly enable it (see [SPIFFE with ServersTransport](../routing/services/index.md#spiffe) or [SPIFFE with TCPServersTransport](../routing/services/index.md#spiffe_1)). !!! warning "SPIFFE can cause Traefik to stall" When using SPIFFE, diff --git a/docs/content/https/tailscale.md b/docs/content/https/tailscale.md index abc742b83dcecbcc8af5685f7decae4b405cd921..6cb2f3e6c90b152ccbd2fb1c6f08b49ace47be2b 100644 --- a/docs/content/https/tailscale.md +++ b/docs/content/https/tailscale.md @@ -103,7 +103,7 @@ A certificate resolver requests certificates for a set of domain names inferred ``` ```yaml tab="Kubernetes" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: blogtls @@ -120,20 +120,6 @@ A certificate resolver requests certificates for a set of domain names inferred certResolver: myresolver ``` - ```json tab="Marathon" - labels: { - "traefik.http.routers.blog.rule": "Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`)", - "traefik.http.routers.blog.tls.certresolver": "myresolver", - } - ``` - - ```yaml tab="Rancher" - ## Dynamic configuration - labels: - - traefik.http.routers.blog.rule=Host(`monitoring.yak-bebop.ts.net`) && Path(`/metrics`) - - traefik.http.routers.blog.tls.certresolver=myresolver - ``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: @@ -173,7 +159,7 @@ A certificate resolver requests certificates for a set of domain names inferred ``` ```yaml tab="Kubernetes" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: blogtls @@ -192,22 +178,6 @@ A certificate resolver requests certificates for a set of domain names inferred - main: monitoring.yak-bebop.ts.net ``` - ```json tab="Marathon" - labels: { - "traefik.http.routers.blog.rule": "Path(`/metrics`)", - "traefik.http.routers.blog.tls.certresolver": "myresolver", - "traefik.http.routers.blog.tls.domains[0].main": "monitoring.yak-bebop.ts.net", - } - ``` - - ```yaml tab="Rancher" - ## Dynamic configuration - labels: - - traefik.http.routers.blog.rule=Path(`/metrics`) - - traefik.http.routers.blog.tls.certresolver=myresolver - - traefik.http.routers.blog.tls.domains[0].main=monitoring.yak-bebop.ts.net - ``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: diff --git a/docs/content/https/tls.md b/docs/content/https/tls.md index dd756dd44d0081c3d26475457f85943db4f6b2e4..075c562c5df2c919902636c9d748aed22c5cbac9 100644 --- a/docs/content/https/tls.md +++ b/docs/content/https/tls.md @@ -134,7 +134,7 @@ tls: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSStore metadata: name: default @@ -195,7 +195,7 @@ tls: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSStore metadata: name: default @@ -219,14 +219,6 @@ labels: - "traefik.tls.stores.default.defaultgeneratedcert.domain.sans=foo.example.org, bar.example.org" ``` -```json tab="Marathon" -labels: { - "traefik.tls.stores.default.defaultgeneratedcert.resolver": "myresolver", - "traefik.tls.stores.default.defaultgeneratedcert.domain.main": "example.org", - "traefik.tls.stores.default.defaultgeneratedcert.domain.sans": "foo.example.org, bar.example.org", -} -``` - ## TLS Options The TLS options allow one to configure some parameters of the TLS connection. @@ -277,7 +269,7 @@ tls: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: default @@ -287,7 +279,7 @@ spec: minVersion: VersionTLS12 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: mintls13 @@ -328,7 +320,7 @@ tls: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: default @@ -338,7 +330,7 @@ spec: maxVersion: VersionTLS13 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: maxtls12 @@ -373,7 +365,7 @@ tls: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: default @@ -418,7 +410,7 @@ tls: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: default @@ -454,7 +446,7 @@ tls: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: default @@ -493,7 +485,7 @@ tls: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: default @@ -545,7 +537,7 @@ tls: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: default diff --git a/docs/content/index.md b/docs/content/index.md index b882fb1480ba569b0f19af66fbdd94efe4d06046..3ee028a797dbd25b999d63f6580a118c9501856e 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -13,7 +13,7 @@ It receives requests on behalf of your system and finds out which components are What sets Traefik apart, besides its many features, is that it automatically discovers the right configuration for your services. The magic happens when Traefik inspects your infrastructure, where it finds relevant information and discovers which service serves which request. -Traefik is natively compliant with every major cluster technology, such as Kubernetes, Docker, Docker Swarm, AWS, Mesos, Marathon, and [the list goes on](providers/overview.md); and can handle many at the same time. (It even works for legacy software running on bare metal.) +Traefik is natively compliant with every major cluster technology, such as Kubernetes, Docker, Docker Swarm, AWS, and [the list goes on](providers/overview.md); and can handle many at the same time. (It even works for legacy software running on bare metal.) With Traefik, there is no need to maintain and synchronize a separate configuration file: everything happens automatically, in real time (no restarts, no connection interruptions). With Traefik, you spend time developing and deploying new features to your system, not on configuring and maintaining its working state. diff --git a/docs/content/middlewares/http/addprefix.md b/docs/content/middlewares/http/addprefix.md index 9f909aa8f4da5bf58d06575f2e0fc6904a86ae75..e6f458f31c4588e8f4568f01693fc5e63e7d9378 100644 --- a/docs/content/middlewares/http/addprefix.md +++ b/docs/content/middlewares/http/addprefix.md @@ -22,7 +22,7 @@ labels: ```yaml tab="Kubernetes" # Prefixing with /foo -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: add-foo @@ -36,18 +36,6 @@ spec: - "traefik.http.middlewares.add-foo.addprefix.prefix=/foo" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.add-foo.addprefix.prefix": "/foo" -} -``` - -```yaml tab="Rancher" -# Prefixing with /foo -labels: - - "traefik.http.middlewares.add-foo.addprefix.prefix=/foo" -``` - ```yaml tab="File (YAML)" # Prefixing with /foo http: diff --git a/docs/content/middlewares/http/basicauth.md b/docs/content/middlewares/http/basicauth.md index c9ef0e2127ab36a3dd824f0cf92062b8d4e29536..d5118f855d085a1c7cdfc19818fc2efa52fa694c 100644 --- a/docs/content/middlewares/http/basicauth.md +++ b/docs/content/middlewares/http/basicauth.md @@ -28,7 +28,7 @@ labels: ```yaml tab="Kubernetes" # Declaring the user list -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -41,18 +41,6 @@ spec: - "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" -} -``` - -```yaml tab="Rancher" -# Declaring the user list -labels: - - "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" -``` - ```yaml tab="File (YAML)" # Declaring the user list http: @@ -114,7 +102,7 @@ labels: ```yaml tab="Kubernetes" # Declaring the user list -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -157,18 +145,6 @@ data: - "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" -} -``` - -```yaml tab="Rancher" -# Declaring the user list -labels: - - "traefik.http.middlewares.test-auth.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0" -``` - ```yaml tab="File (YAML)" # Declaring the user list http: @@ -207,7 +183,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -232,17 +208,6 @@ data: - "traefik.http.middlewares.test-auth.basicauth.usersfile=/path/to/my/usersfile" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.basicauth.usersfile": "/path/to/my/usersfile" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.basicauth.usersfile=/path/to/my/usersfile" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -274,7 +239,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -287,17 +252,6 @@ spec: - "traefik.http.middlewares.test-auth.basicauth.realm=MyRealm" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.basicauth.realm": "MyRealm" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.basicauth.realm=MyRealm" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -322,7 +276,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: my-auth @@ -336,12 +290,6 @@ spec: - "traefik.http.middlewares.my-auth.basicauth.headerField=X-WebAuth-User" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.my-auth.basicauth.headerField": "X-WebAuth-User" -} -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -367,7 +315,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -380,17 +328,6 @@ spec: - "traefik.http.middlewares.test-auth.basicauth.removeheader=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.basicauth.removeheader": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.basicauth.removeheader=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/buffering.md b/docs/content/middlewares/http/buffering.md index f172faffa5335c5441679b595dea46eaaebb24dc..85c21a62bb18e4716e7af65676d21f3c63bcaf87 100644 --- a/docs/content/middlewares/http/buffering.md +++ b/docs/content/middlewares/http/buffering.md @@ -26,7 +26,7 @@ labels: ```yaml tab="Kubernetes" # Sets the maximum request body to 2MB -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: limit @@ -40,18 +40,6 @@ spec: - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes": "2000000" -} -``` - -```yaml tab="Rancher" -# Sets the maximum request body to 2MB -labels: - - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000" -``` - ```yaml tab="File (YAML)" # Sets the maximum request body to 2MB http: @@ -84,7 +72,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: limit @@ -97,17 +85,6 @@ spec: - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes": "2000000" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.limit.buffering.maxRequestBodyBytes=2000000" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -134,7 +111,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: limit @@ -147,17 +124,6 @@ spec: - "traefik.http.middlewares.limit.buffering.memRequestBodyBytes=2000000" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.limit.buffering.memRequestBodyBytes": "2000000" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.limit.buffering.memRequestBodyBytes=2000000" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -186,7 +152,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: limit @@ -199,17 +165,6 @@ spec: - "traefik.http.middlewares.limit.buffering.maxResponseBodyBytes=2000000" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.limit.buffering.maxResponseBodyBytes": "2000000" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.limit.buffering.maxResponseBodyBytes=2000000" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -236,7 +191,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: limit @@ -249,17 +204,6 @@ spec: - "traefik.http.middlewares.limit.buffering.memResponseBodyBytes=2000000" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.limit.buffering.memResponseBodyBytes": "2000000" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.limit.buffering.memResponseBodyBytes=2000000" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -288,7 +232,7 @@ You can have the Buffering middleware replay the request using `retryExpression` ``` ```yaml tab="Kubernetes" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: limit @@ -301,17 +245,6 @@ You can have the Buffering middleware replay the request using `retryExpression` - "traefik.http.middlewares.limit.buffering.retryExpression=IsNetworkError() && Attempts() < 2" ``` - ```json tab="Marathon" - "labels": { - "traefik.http.middlewares.limit.buffering.retryExpression": "IsNetworkError() && Attempts() < 2" - } - ``` - - ```yaml tab="Rancher" - labels: - - "traefik.http.middlewares.limit.buffering.retryExpression=IsNetworkError() && Attempts() < 2" - ``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/chain.md b/docs/content/middlewares/http/chain.md index f9768adfb2a15b731b21e21c14f33ce8dd262e5c..de00744260048725a56fc17d3c83ee86ede66ea3 100644 --- a/docs/content/middlewares/http/chain.md +++ b/docs/content/middlewares/http/chain.md @@ -30,7 +30,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test @@ -47,7 +47,7 @@ spec: middlewares: - name: secured --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: secured @@ -58,7 +58,7 @@ spec: - name: known-ips - name: auth-users --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: auth-users @@ -67,7 +67,7 @@ spec: users: - test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/ --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: https-only @@ -75,7 +75,7 @@ spec: redirectScheme: scheme: https --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: known-ips @@ -97,31 +97,6 @@ spec: - "traefik.http.services.service1.loadbalancer.server.port=80" ``` -```json tab="Marathon" -"labels": { - "traefik.http.routers.router1.service": "service1", - "traefik.http.routers.router1.middlewares": "secured", - "traefik.http.routers.router1.rule": "Host(`mydomain`)", - "traefik.http.middlewares.secured.chain.middlewares": "https-only,known-ips,auth-users", - "traefik.http.middlewares.auth-users.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "traefik.http.middlewares.https-only.redirectscheme.scheme": "https", - "traefik.http.middlewares.known-ips.ipallowlist.sourceRange": "192.168.1.7,127.0.0.1/32", - "traefik.http.services.service1.loadbalancer.server.port": "80" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.routers.router1.service=service1" - - "traefik.http.routers.router1.middlewares=secured" - - "traefik.http.routers.router1.rule=Host(`mydomain`)" - - "traefik.http.middlewares.secured.chain.middlewares=https-only,known-ips,auth-users" - - "traefik.http.middlewares.auth-users.basicauth.users=test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/" - - "traefik.http.middlewares.https-only.redirectscheme.scheme=https" - - "traefik.http.middlewares.known-ips.ipallowlist.sourceRange=192.168.1.7,127.0.0.1/32" - - "traefik.http.services.service1.loadbalancer.server.port=80" -``` - ```yaml tab="File (YAML)" # ... http: diff --git a/docs/content/middlewares/http/circuitbreaker.md b/docs/content/middlewares/http/circuitbreaker.md index 4399be1e179ed836e3363bbb88e7c033d241a8f5..6edaedbe92bc5fb0ed9984dcc026235e53398c9d 100644 --- a/docs/content/middlewares/http/circuitbreaker.md +++ b/docs/content/middlewares/http/circuitbreaker.md @@ -38,7 +38,7 @@ labels: ```yaml tab="Kubernetes" # Latency Check -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: latency-check @@ -52,18 +52,6 @@ spec: - "traefik.http.middlewares.latency-check.circuitbreaker.expression=LatencyAtQuantileMS(50.0) > 100" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.latency-check.circuitbreaker.expression": "LatencyAtQuantileMS(50.0) > 100" -} -``` - -```yaml tab="Rancher" -# Latency Check -labels: - - "traefik.http.middlewares.latency-check.circuitbreaker.expression=LatencyAtQuantileMS(50.0) > 100" -``` - ```yaml tab="File (YAML)" # Latency Check http: diff --git a/docs/content/middlewares/http/compress.md b/docs/content/middlewares/http/compress.md index 7e4b79613af775935cb425409d928be7c06c3c7e..4618fb24579a0c3519f6372724e1c2b506857322 100644 --- a/docs/content/middlewares/http/compress.md +++ b/docs/content/middlewares/http/compress.md @@ -23,7 +23,7 @@ labels: ```yaml tab="Kubernetes" # Enable compression -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-compress @@ -36,18 +36,6 @@ spec: - "traefik.http.middlewares.test-compress.compress=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-compress.compress": "true" -} -``` - -```yaml tab="Rancher" -# Enable compression -labels: - - "traefik.http.middlewares.test-compress.compress=true" -``` - ```yaml tab="File (YAML)" # Enable compression http: @@ -100,7 +88,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-compress @@ -114,17 +102,6 @@ spec: - "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-compress.compress.excludedcontenttypes": "text/event-stream" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-compress.compress.excludedcontenttypes=text/event-stream" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -154,7 +131,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-compress @@ -167,17 +144,6 @@ spec: - "traefik.http.middlewares.test-compress.compress.minresponsebodybytes=1200" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-compress.compress.minresponsebodybytes": 1200 -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-compress.compress.minresponsebodybytes=1200" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/contenttype.md b/docs/content/middlewares/http/contenttype.md index 38072958a281a870b405b2f2725581ca79eec15d..c4d78a35922cb2f85dc5eee7aaf1fa1189c197e2 100644 --- a/docs/content/middlewares/http/contenttype.md +++ b/docs/content/middlewares/http/contenttype.md @@ -26,7 +26,7 @@ labels: ```yaml tab="Kubernetes" # Enable auto-detection -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: autodetect @@ -39,18 +39,6 @@ spec: - "traefik.http.middlewares.autodetect.contenttype=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.autodetect.contenttype": "true" -} -``` - -```yaml tab="Rancher" -# Enable auto-detection -labels: - - "traefik.http.middlewares.autodetect.contenttype=true" -``` - ```yaml tab="File (YAML)" # Enable auto-detection http: @@ -63,4 +51,4 @@ http: # Enable auto-detection [http.middlewares] [http.middlewares.autodetect.contentType] -``` \ No newline at end of file +``` diff --git a/docs/content/middlewares/http/digestauth.md b/docs/content/middlewares/http/digestauth.md index 14e3982b5ebfbe814c9d407d5781e7f21fd5464e..dcd9ca2840494de165a663018f3e88f0ad598199 100644 --- a/docs/content/middlewares/http/digestauth.md +++ b/docs/content/middlewares/http/digestauth.md @@ -22,7 +22,7 @@ labels: ```yaml tab="Kubernetes" # Declaring the user list -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -36,18 +36,6 @@ spec: - "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.digestauth.users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" -} -``` - -```yaml tab="Rancher" -# Declaring the user list -labels: - - "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" -``` - ```yaml tab="File (YAML)" # Declaring the user list http: @@ -90,7 +78,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -114,17 +102,6 @@ data: - "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.digestauth.users": "test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.digestauth.users=test:traefik:a2688e031edb4be6a3797f3882655c05,test2:traefik:518845800f9e2bfb1f1f740ec24f074e" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -161,7 +138,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -186,17 +163,6 @@ data: - "traefik.http.middlewares.test-auth.digestauth.usersfile=/path/to/my/usersfile" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.digestauth.usersfile": "/path/to/my/usersfile" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.digestauth.usersfile=/path/to/my/usersfile" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -228,7 +194,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -241,17 +207,6 @@ spec: - "traefik.http.middlewares.test-auth.digestauth.realm=MyRealm" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.digestauth.realm": "MyRealm" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.digestauth.realm=MyRealm" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -276,7 +231,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: my-auth @@ -290,17 +245,6 @@ spec: - "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.my-auth.digestauth.headerField": "X-WebAuth-User" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.my-auth.digestauth.headerField=X-WebAuth-User" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -326,7 +270,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -339,17 +283,6 @@ spec: - "traefik.http.middlewares.test-auth.digestauth.removeheader=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.digestauth.removeheader": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.digestauth.removeheader=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/errorpages.md b/docs/content/middlewares/http/errorpages.md index 81986d6675a63fc42ef1deb224b090c3c771ae67..0f8b1798ac79196230874fa59218ac5869bc82c8 100644 --- a/docs/content/middlewares/http/errorpages.md +++ b/docs/content/middlewares/http/errorpages.md @@ -27,7 +27,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-errors @@ -48,22 +48,6 @@ spec: - "traefik.http.middlewares.test-errors.errors.query=/{status}.html" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-errors.errors.status": "500-599", - "traefik.http.middlewares.test-errors.errors.service": "serviceError", - "traefik.http.middlewares.test-errors.errors.query": "/{status}.html" -} -``` - -```yaml tab="Rancher" -# Dynamic Custom Error Page for 5XX Status Code -labels: - - "traefik.http.middlewares.test-errors.errors.status=500-599" - - "traefik.http.middlewares.test-errors.errors.service=serviceError" - - "traefik.http.middlewares.test-errors.errors.query=/{status}.html" -``` - ```yaml tab="File (YAML)" # Custom Error Page for 5XX http: diff --git a/docs/content/middlewares/http/forwardauth.md b/docs/content/middlewares/http/forwardauth.md index fdcff0321a87dfc0728a5a1d396b57ab753f268d..4738747b27f1d1c3c2bdc440a88b5d5ce2b4f8e0 100644 --- a/docs/content/middlewares/http/forwardauth.md +++ b/docs/content/middlewares/http/forwardauth.md @@ -24,7 +24,7 @@ labels: ```yaml tab="Kubernetes" # Forward authentication to example.com -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -38,18 +38,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.address": "https://example.com/auth" -} -``` - -```yaml tab="Rancher" -# Forward authentication to example.com -labels: - - "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth" -``` - ```yaml tab="File (YAML)" # Forward authentication to example.com http: @@ -90,7 +78,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -103,17 +91,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.address": "https://example.com/auth" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.address=https://example.com/auth" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -138,7 +115,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -152,17 +129,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.trustForwardHeader=true" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -190,7 +156,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -206,17 +172,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders": "X-Auth-User,X-Secret" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeaders=X-Auth-User, X-Secret" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -248,7 +203,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -262,17 +217,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex": "^X-" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.authResponseHeadersRegex=^X-" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -307,7 +251,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -323,17 +267,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders=Accept,X-CustomHeader" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders": "Accept,X-CustomHeader" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.authRequestHeaders=Accept,X-CustomHeader" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -371,7 +304,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -397,17 +330,6 @@ data: - "traefik.http.middlewares.test-auth.forwardauth.tls.ca=path/to/local.crt" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.tls.ca": "path/to/local.crt" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.tls.ca=path/to/local.crt" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -440,7 +362,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -467,19 +389,6 @@ data: - "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert", - "traefik.http.middlewares.test-auth.forwardauth.tls.key": "path/to/foo.key" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert" - - "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -518,7 +427,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -545,19 +454,6 @@ data: - "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.tls.cert": "path/to/foo.cert", - "traefik.http.middlewares.test-auth.forwardauth.tls.key": "path/to/foo.key" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.tls.cert=path/to/foo.cert" - - "traefik.http.middlewares.test-auth.forwardauth.tls.key=path/to/foo.key" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -594,7 +490,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-auth @@ -609,17 +505,6 @@ spec: - "traefik.http.middlewares.test-auth.forwardauth.tls.InsecureSkipVerify=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-auth.forwardauth.tls.insecureSkipVerify": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-auth.forwardauth.tls.InsecureSkipVerify=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/grpcweb.md b/docs/content/middlewares/http/grpcweb.md index d6d2c9a6b6033924d468287f16d652c0680e5d45..8b14214a241af57069e4da14686f77dd48c6f11b 100644 --- a/docs/content/middlewares/http/grpcweb.md +++ b/docs/content/middlewares/http/grpcweb.md @@ -23,7 +23,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-grpcweb @@ -37,17 +37,6 @@ spec: - "traefik.http.middlewares.test-grpcweb.grpcWeb.allowOrigins=*" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-grpcweb.grpcweb.alloworigins": "*" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-grpcweb.grpcweb.alloworigins=*" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/headers.md b/docs/content/middlewares/http/headers.md index a8532e6be58ea2bc32ca972a68e4de2d117f9ed7..de39548cb3be6749f6953e467f4625772f1d2ed8 100644 --- a/docs/content/middlewares/http/headers.md +++ b/docs/content/middlewares/http/headers.md @@ -27,7 +27,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-header @@ -44,19 +44,6 @@ spec: - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=value" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test", - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header": "value" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test" - - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=value" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -90,7 +77,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-header @@ -109,21 +96,6 @@ spec: - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name": "test", - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Custom-Request-Header": "", - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header": "", -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Script-Name=test" - - "traefik.http.middlewares.testheader.headers.customrequestheaders.X-Custom-Request-Header=" - - "traefik.http.middlewares.testheader.headers.customresponseheaders.X-Custom-Response-Header=" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -158,7 +130,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-header @@ -173,19 +145,6 @@ spec: - "traefik.http.middlewares.testheader.headers.browserxssfilter=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.testheader.headers.framedeny": "true", - "traefik.http.middlewares.testheader.headers.browserxssfilter": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.testheader.headers.framedeny=true" - - "traefik.http.middlewares.testheader.headers.browserxssfilter=true" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -218,7 +177,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-header @@ -242,23 +201,6 @@ spec: - "traefik.http.middlewares.testheader.headers.addvaryheader=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods": "GET,OPTIONS,PUT", - "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist": "https://foo.bar.org,https://example.org", - "traefik.http.middlewares.testheader.headers.accesscontrolmaxage": "100", - "traefik.http.middlewares.testheader.headers.addvaryheader": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.testheader.headers.accesscontrolallowmethods=GET,OPTIONS,PUT" - - "traefik.http.middlewares.testheader.headers.accesscontrolalloworiginlist=https://foo.bar.org,https://example.org" - - "traefik.http.middlewares.testheader.headers.accesscontrolmaxage=100" - - "traefik.http.middlewares.testheader.headers.addvaryheader=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/inflightreq.md b/docs/content/middlewares/http/inflightreq.md index b3712b148f443d6a2b6bfb643d54d28116a4b687..b7eefd84d01187c482b5ec6d30abed147cb7ade4 100644 --- a/docs/content/middlewares/http/inflightreq.md +++ b/docs/content/middlewares/http/inflightreq.md @@ -20,7 +20,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-inflightreq @@ -34,18 +34,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10" -} -``` - -```yaml tab="Rancher" -# Limiting to 10 simultaneous connections -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10" -``` - ```yaml tab="File (YAML)" # Limiting to 10 simultaneous connections http: @@ -75,7 +63,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-inflightreq @@ -89,18 +77,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.amount": "10" -} -``` - -```yaml tab="Rancher" -# Limiting to 10 simultaneous connections -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.amount=10" -``` - ```yaml tab="File (YAML)" # Limiting to 10 simultaneous connections http: @@ -127,6 +103,8 @@ If none are set, the default is to use the `requestHost`. The `ipStrategy` option defines two parameters that configures how Traefik determines the client IP: `depth`, and `excludedIPs`. +!!! important "As a middleware, InFlightReq happens before the actual proxying to the backend takes place. In addition, the previous network hop only gets appended to `X-Forwarded-For` during the last stages of proxying, i.e. after it has already passed through the middleware. Therefore, during InFlightReq, as the previous network hop is not yet present in `X-Forwarded-For`, it cannot be used and/or relied upon." + ##### `ipStrategy.depth` The `depth` option tells Traefik to use the `X-Forwarded-For` header and select the IP located at the `depth` position (starting from the right). @@ -150,7 +128,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-inflightreq @@ -165,17 +143,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth": "2" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.depth=2" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -215,7 +182,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-inflightreq @@ -232,17 +199,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -272,7 +228,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-inflightreq @@ -286,17 +242,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername": "username" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requestheadername=username" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -323,7 +268,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-inflightreq @@ -337,17 +282,6 @@ spec: - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-inflightreq.inflightreq.sourcecriterion.requesthost=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/ipallowlist.md b/docs/content/middlewares/http/ipallowlist.md index 56450d73683953b83f665fd459eac24d301254bd..8892b4fcd016c41b4a1215506680bcdbfe8bdec7 100644 --- a/docs/content/middlewares/http/ipallowlist.md +++ b/docs/content/middlewares/http/ipallowlist.md @@ -19,7 +19,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ipallowlist @@ -35,18 +35,6 @@ spec: - "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange": "127.0.0.1/32,192.168.1.7" -} -``` - -```yaml tab="Rancher" -# Accepts request from defined IP -labels: - - "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" -``` - ```yaml tab="File (YAML)" # Accepts request from defined IP http: @@ -73,7 +61,10 @@ The `sourceRange` option sets the allowed IPs (or ranges of allowed IPs by using ### `ipStrategy` -The `ipStrategy` option defines two parameters that set how Traefik determines the client IP: `depth`, and `excludedIPs`. +The `ipStrategy` option defines two parameters that set how Traefik determines the client IP: `depth`, and `excludedIPs`. +If no strategy is set, the default behavior is to match `sourceRange` against the Remote address found in the request. + +!!! important "As a middleware, whitelisting happens before the actual proxying to the backend takes place. In addition, the previous network hop only gets appended to `X-Forwarded-For` during the last stages of proxying, i.e. after it has already passed through whitelisting. Therefore, during whitelisting, as the previous network hop is not yet present in `X-Forwarded-For`, it cannot be matched against `sourceRange`." #### `ipStrategy.depth` @@ -101,7 +92,7 @@ labels: ```yaml tab="Kubernetes" # Allowlisting Based on `X-Forwarded-For` with `depth=2` -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ipallowlist @@ -120,20 +111,6 @@ spec: - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth=2" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange": "127.0.0.1/32, 192.168.1.7", - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth": "2" -} -``` - -```yaml tab="Rancher" -# Allowlisting Based on `X-Forwarded-For` with `depth=2` -labels: - - "traefik.http.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" - - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.depth=2" -``` - ```yaml tab="File (YAML)" # Allowlisting Based on `X-Forwarded-For` with `depth=2` http: @@ -180,7 +157,7 @@ labels: ```yaml tab="Kubernetes" # Exclude from `X-Forwarded-For` -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ipallowlist @@ -197,18 +174,6 @@ spec: - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7" -} -``` - -```yaml tab="Rancher" -# Exclude from `X-Forwarded-For` -labels: - - "traefik.http.middlewares.test-ipallowlist.ipallowlist.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" -``` - ```yaml tab="File (YAML)" # Exclude from `X-Forwarded-For` http: diff --git a/docs/content/middlewares/http/overview.md b/docs/content/middlewares/http/overview.md index c4a9f9791be07120c640c4e0e389c5a0b45c5b5e..500e5d38d664a45036a44552207b7b03adf56ade 100644 --- a/docs/content/middlewares/http/overview.md +++ b/docs/content/middlewares/http/overview.md @@ -29,9 +29,9 @@ whoami: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: middlewares.traefik.containo.us + name: middlewares.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: Middleware @@ -40,7 +40,7 @@ spec: scope: Namespaced --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: stripprefix @@ -50,7 +50,7 @@ spec: - /stripit --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroute @@ -69,22 +69,6 @@ spec: - "traefik.http.routers.router1.middlewares=foo-add-prefix@consulcatalog" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix": "/foo", - "traefik.http.routers.router1.middlewares": "foo-add-prefix@marathon" -} -``` - -```yaml tab="Rancher" -# As a Rancher Label -labels: - # Create a middleware named `foo-add-prefix` - - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo" - # Apply the middleware named `foo-add-prefix` to the router named `router1` - - "traefik.http.routers.router1.middlewares=foo-add-prefix@rancher" -``` - ```toml tab="File (TOML)" # As TOML Configuration File [http.routers] diff --git a/docs/content/middlewares/http/passtlsclientcert.md b/docs/content/middlewares/http/passtlsclientcert.md index 28c5f7fffe653cf51fed0221783d1c8524c07a61..92c5cc83b5a3364b41d8158a5f974c582e5665da 100644 --- a/docs/content/middlewares/http/passtlsclientcert.md +++ b/docs/content/middlewares/http/passtlsclientcert.md @@ -25,7 +25,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-passtlsclientcert @@ -39,18 +39,6 @@ spec: - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem": "true" -} -``` - -```yaml tab="Rancher" -# Pass the pem in the `X-Forwarded-Tls-Client-Cert` header. -labels: - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.pem=true" -``` - ```yaml tab="File (YAML)" # Pass the pem in the `X-Forwarded-Tls-Client-Cert` header. http: @@ -95,7 +83,7 @@ http: ```yaml tab="Kubernetes" # Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-passtlsclientcert @@ -146,52 +134,6 @@ http: - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true" ``` - ```json tab="Marathon" - "labels": { - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organizationalunit": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province": "true", - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber": "true" - } - ``` - - ```yaml tab="Rancher" - # Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header - labels: - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notafter=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.notbefore=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.sans=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.commonname=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.country=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.domaincomponent=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.locality=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organization=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.organizationalunit=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.province=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.subject.serialnumber=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.commonname=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.country=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.domaincomponent=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.locality=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.organization=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.province=true" - - "traefik.http.middlewares.test-passtlsclientcert.passtlsclientcert.info.issuer.serialnumber=true" - ``` - ```yaml tab="File (YAML)" # Pass all the available info in the `X-Forwarded-Tls-Client-Cert-Info` header http: diff --git a/docs/content/middlewares/http/ratelimit.md b/docs/content/middlewares/http/ratelimit.md index 8d62afd9c66d566e21219932eeef9923d1c13ce8..9ae94a31a8d6b24121ecccd51e3830234b61a5fe 100644 --- a/docs/content/middlewares/http/ratelimit.md +++ b/docs/content/middlewares/http/ratelimit.md @@ -10,6 +10,8 @@ To Control the Number of Requests Going to a Service The RateLimit middleware ensures that services will receive a _fair_ amount of requests, and allows one to define what fair is. +It is based on a [token bucket](https://en.wikipedia.org/wiki/Token_bucket) implementation. In this analogy, the [average](#average) parameter (defined below) is the rate at which the bucket refills, and the [burst](#burst) is the size (volume) of the bucket. + ## Configuration Example ```yaml tab="Docker" @@ -23,7 +25,7 @@ labels: ```yaml tab="Kubernetes" # Here, an average of 100 requests per second is allowed. # In addition, a burst of 50 requests is allowed. -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ratelimit @@ -40,21 +42,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.burst=50" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.average": "100", - "traefik.http.middlewares.test-ratelimit.ratelimit.burst": "50" -} -``` - -```yaml tab="Rancher" -# Here, an average of 100 requests per second is allowed. -# In addition, a burst of 50 requests is allowed. -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.average=100" - - "traefik.http.middlewares.test-ratelimit.ratelimit.burst=50" -``` - ```yaml tab="File (YAML)" # Here, an average of 100 requests per second is allowed. # In addition, a burst of 50 requests is allowed. @@ -94,7 +81,7 @@ labels: ```yaml tab="Kubernetes" # 100 reqs/s -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ratelimit @@ -108,17 +95,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.average=100" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.average": "100", -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.average=100" -``` - ```yaml tab="File (YAML)" # 100 reqs/s http: @@ -154,7 +130,7 @@ labels: ```yaml tab="Kubernetes" # 6 reqs/minute -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ratelimit @@ -170,20 +146,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.period=1m" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.average": "6", - "traefik.http.middlewares.test-ratelimit.ratelimit.period": "1m", -} -``` - -```yaml tab="Rancher" -# 6 reqs/minute -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.average=6" - - "traefik.http.middlewares.test-ratelimit.ratelimit.period=1m" -``` - ```yaml tab="File (YAML)" # 6 reqs/minute http: @@ -214,7 +176,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ratelimit @@ -227,17 +189,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.burst": "100", -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.burst=100" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -262,6 +213,8 @@ If none are set, the default is to use the request's remote address field (as an The `ipStrategy` option defines two parameters that configures how Traefik determines the client IP: `depth`, and `excludedIPs`. +!!! important "As a middleware, rate-limiting happens before the actual proxying to the backend takes place. In addition, the previous network hop only gets appended to `X-Forwarded-For` during the last stages of proxying, i.e. after it has already passed through rate-limiting. Therefore, during rate-limiting, as the previous network hop is not yet present in `X-Forwarded-For`, it cannot be found and/or relied upon." + ##### `ipStrategy.depth` The `depth` option tells Traefik to use the `X-Forwarded-For` header and select the IP located at the `depth` position (starting from the right). @@ -285,7 +238,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ratelimit @@ -300,17 +253,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.depth=2" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.depth": "2" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.depth=2" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -377,7 +319,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ratelimit @@ -394,17 +336,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips": "127.0.0.1/32, 192.168.1.7" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.ipstrategy.excludedips=127.0.0.1/32, 192.168.1.7" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -434,7 +365,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ratelimit @@ -448,17 +379,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername=username" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername": "username" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requestheadername=username" -``` - ```yaml tab="File (YAML)" http: middlewares: @@ -485,7 +405,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-ratelimit @@ -499,17 +419,6 @@ spec: - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost": "true" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-ratelimit.ratelimit.sourcecriterion.requesthost=true" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/http/redirectregex.md b/docs/content/middlewares/http/redirectregex.md index 97d2d83e65b928ca645737b8e2bbe822bb7fdc68..d2e14667359f062f788329ce43671cbf9c0b484f 100644 --- a/docs/content/middlewares/http/redirectregex.md +++ b/docs/content/middlewares/http/redirectregex.md @@ -26,7 +26,7 @@ labels: ```yaml tab="Kubernetes" # Redirect with domain replacement -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-redirectregex @@ -43,21 +43,6 @@ spec: - "traefik.http.middlewares.test-redirectregex.redirectregex.replacement=http://mydomain/$${1}" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-redirectregex.redirectregex.regex": "^http://localhost/(.*)", - "traefik.http.middlewares.test-redirectregex.redirectregex.replacement": "http://mydomain/${1}" -} -``` - -```yaml tab="Rancher" -# Redirect with domain replacement -# Note: all dollar signs need to be doubled for escaping. -labels: - - "traefik.http.middlewares.test-redirectregex.redirectregex.regex=^http://localhost/(.*)" - - "traefik.http.middlewares.test-redirectregex.redirectregex.replacement=http://mydomain/$${1}" -``` - ```yaml tab="File (YAML)" # Redirect with domain replacement http: diff --git a/docs/content/middlewares/http/redirectscheme.md b/docs/content/middlewares/http/redirectscheme.md index 9c7a67ec1eedbb60d58cb9dfc106e0d34fc261c2..e32fecfbc7db2ec011e108cfc0e3bce6e5a6e29d 100644 --- a/docs/content/middlewares/http/redirectscheme.md +++ b/docs/content/middlewares/http/redirectscheme.md @@ -34,7 +34,7 @@ labels: ```yaml tab="Kubernetes" # Redirect to https -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-redirectscheme @@ -51,20 +51,6 @@ labels: - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme": "https" - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent": "true" -} -``` - -```yaml tab="Rancher" -# Redirect to https -labels: - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https" - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true" -``` - ```yaml tab="File (YAML)" # Redirect to https http: @@ -98,7 +84,7 @@ labels: ```yaml tab="Kubernetes" # Redirect to https -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-redirectscheme @@ -115,20 +101,6 @@ labels: - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true" ``` -```json tab="Marathon" -"labels": { - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent": "true" -} -``` - -```yaml tab="Rancher" -# Redirect to https -labels: - # ... - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.permanent=true" -``` - ```yaml tab="File (YAML)" # Redirect to https http: @@ -159,7 +131,7 @@ labels: ```yaml tab="Kubernetes" # Redirect to https -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-redirectscheme @@ -174,18 +146,6 @@ labels: - "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme": "https" -} -``` - -```yaml tab="Rancher" -# Redirect to https -labels: - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.scheme=https" -``` - ```yaml tab="File (YAML)" # Redirect to https http: @@ -215,7 +175,7 @@ labels: ```yaml tab="Kubernetes" # Redirect to https -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-redirectscheme @@ -232,20 +192,6 @@ labels: - "traefik.http.middlewares.test-redirectscheme.redirectscheme.port=443" ``` -```json tab="Marathon" -"labels": { - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.port": "443" -} -``` - -```yaml tab="Rancher" -# Redirect to https -labels: - # ... - - "traefik.http.middlewares.test-redirectscheme.redirectscheme.port=443" -``` - ```yaml tab="File (YAML)" # Redirect to https http: diff --git a/docs/content/middlewares/http/replacepath.md b/docs/content/middlewares/http/replacepath.md index 0617508e903a09b23a62cfaf895b0a05e7ed31a2..2c44e9f753c2ded74a7b8db380fc81008ef38c91 100644 --- a/docs/content/middlewares/http/replacepath.md +++ b/docs/content/middlewares/http/replacepath.md @@ -24,7 +24,7 @@ labels: ```yaml tab="Kubernetes" # Replace the path with /foo -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-replacepath @@ -38,18 +38,6 @@ spec: - "traefik.http.middlewares.test-replacepath.replacepath.path=/foo" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-replacepath.replacepath.path": "/foo" -} -``` - -```yaml tab="Rancher" -# Replace the path with /foo -labels: - - "traefik.http.middlewares.test-replacepath.replacepath.path=/foo" -``` - ```yaml tab="File (YAML)" # Replace the path with /foo http: diff --git a/docs/content/middlewares/http/replacepathregex.md b/docs/content/middlewares/http/replacepathregex.md index b729a30ab151de844a04e53e9546bba5fa7b7101..562d3d2f39f4b0ee965e80171f9f6eaf3d690e37 100644 --- a/docs/content/middlewares/http/replacepathregex.md +++ b/docs/content/middlewares/http/replacepathregex.md @@ -25,7 +25,7 @@ labels: ```yaml tab="Kubernetes" # Replace path with regex -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-replacepathregex @@ -41,20 +41,6 @@ spec: - "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$1" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex": "^/foo/(.*)", - "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement": "/bar/$1" -} -``` - -```yaml tab="Rancher" -# Replace path with regex -labels: - - "traefik.http.middlewares.test-replacepathregex.replacepathregex.regex=^/foo/(.*)" - - "traefik.http.middlewares.test-replacepathregex.replacepathregex.replacement=/bar/$1" -``` - ```yaml tab="File (YAML)" # Replace path with regex http: diff --git a/docs/content/middlewares/http/retry.md b/docs/content/middlewares/http/retry.md index 956bdc4983996e89c7622e218f8aa914da6b23e8..9706ec69f41cfbeb4225b4a316e8a0e240167a79 100644 --- a/docs/content/middlewares/http/retry.md +++ b/docs/content/middlewares/http/retry.md @@ -27,7 +27,7 @@ labels: ```yaml tab="Kubernetes" # Retry 4 times with exponential backoff -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-retry @@ -43,20 +43,6 @@ spec: - "traefik.http.middlewares.test-retry.retry.initialinterval=100ms" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-retry.retry.attempts": "4", - "traefik.http.middlewares.test-retry.retry.initialinterval": "100ms", -} -``` - -```yaml tab="Rancher" -# Retry 4 times with exponential backoff -labels: - - "traefik.http.middlewares.test-retry.retry.attempts=4" - - "traefik.http.middlewares.test-retry.retry.initialinterval=100ms" -``` - ```yaml tab="File (YAML)" # Retry 4 times with exponential backoff http: diff --git a/docs/content/middlewares/http/stripprefix.md b/docs/content/middlewares/http/stripprefix.md index afc20f2ac80ba922941d00c0ad795defafb88d75..4d0d7d567db0204e0a1271f1d5b65aff25d57f36 100644 --- a/docs/content/middlewares/http/stripprefix.md +++ b/docs/content/middlewares/http/stripprefix.md @@ -24,7 +24,7 @@ labels: ```yaml tab="Kubernetes" # Strip prefix /foobar and /fiibar -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-stripprefix @@ -40,18 +40,6 @@ spec: - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar,/fiibar" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes": "/foobar,/fiibar" -} -``` - -```yaml tab="Rancher" -# Strip prefix /foobar and /fiibar -labels: - - "traefik.http.middlewares.test-stripprefix.stripprefix.prefixes=/foobar,/fiibar" -``` - ```yaml tab="File (YAML)" # Strip prefix /foobar and /fiibar http: diff --git a/docs/content/middlewares/http/stripprefixregex.md b/docs/content/middlewares/http/stripprefixregex.md index d560a5d123873a5fee6c243297c5fdf13ffafa41..ba61de6fca220c5fb9281a9f6721bfe5991d148a 100644 --- a/docs/content/middlewares/http/stripprefixregex.md +++ b/docs/content/middlewares/http/stripprefixregex.md @@ -18,7 +18,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-stripprefixregex @@ -32,17 +32,6 @@ spec: - "traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex=/foo/[a-z0-9]+/[0-9]+/" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex": "/foo/[a-z0-9]+/[0-9]+/" -} -``` - -```yaml tab="Rancher" -labels: - - "traefik.http.middlewares.test-stripprefixregex.stripprefixregex.regex=/foo/[a-z0-9]+/[0-9]+/" -``` - ```yaml tab="File (YAML)" http: middlewares: diff --git a/docs/content/middlewares/overview.md b/docs/content/middlewares/overview.md index 90748ef6c4c0845fc73d17a42d6d9b3cca2960be..c01423123c7b0d0c3e7ee79d1512184443d3af72 100644 --- a/docs/content/middlewares/overview.md +++ b/docs/content/middlewares/overview.md @@ -37,7 +37,7 @@ whoami: ```yaml tab="Kubernetes IngressRoute" --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: stripprefix @@ -47,7 +47,7 @@ spec: - /stripit --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroute @@ -66,22 +66,6 @@ spec: - "traefik.http.routers.router1.middlewares=foo-add-prefix@consulcatalog" ``` -```json tab="Marathon" -"labels": { - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix": "/foo", - "traefik.http.routers.router1.middlewares": "foo-add-prefix@marathon" -} -``` - -```yaml tab="Rancher" -# As a Rancher Label -labels: - # Create a middleware named `foo-add-prefix` - - "traefik.http.middlewares.foo-add-prefix.addprefix.prefix=/foo" - # Apply the middleware named `foo-add-prefix` to the router named `router1` - - "traefik.http.routers.router1.middlewares=foo-add-prefix@rancher" -``` - ```yaml tab="File (YAML)" # As YAML Configuration File http: diff --git a/docs/content/middlewares/tcp/inflightconn.md b/docs/content/middlewares/tcp/inflightconn.md index 036ca74e153326258699755a993f19dd0b6fcfd6..f9993a7f8e32d328b4f7213fc41c1f06270ddd33 100644 --- a/docs/content/middlewares/tcp/inflightconn.md +++ b/docs/content/middlewares/tcp/inflightconn.md @@ -13,7 +13,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: test-inflightconn @@ -27,18 +27,6 @@ spec: - "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10" ``` -```json tab="Marathon" -"labels": { - "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount": "10" -} -``` - -```yaml tab="Rancher" -# Limiting to 10 simultaneous connections. -labels: - - "traefik.tcp.middlewares.test-inflightconn.inflightconn.amount=10" -``` - ```yaml tab="File (YAML)" # Limiting to 10 simultaneous connections. tcp: diff --git a/docs/content/middlewares/tcp/ipallowlist.md b/docs/content/middlewares/tcp/ipallowlist.md index 2cc51fd57c4015e363c1079f920911c3cf37db7b..8aa5be01c1e49f6361d759ff62e903867cbcb15e 100644 --- a/docs/content/middlewares/tcp/ipallowlist.md +++ b/docs/content/middlewares/tcp/ipallowlist.md @@ -19,7 +19,7 @@ labels: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: test-ipallowlist @@ -35,18 +35,6 @@ spec: - "traefik.tcp.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" ``` -```json tab="Marathon" -"labels": { - "traefik.tcp.middlewares.test-ipallowlist.ipallowlist.sourcerange": "127.0.0.1/32,192.168.1.7" -} -``` - -```yaml tab="Rancher" -# Accepts request from defined IP -labels: - - "traefik.tcp.middlewares.test-ipallowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" -``` - ```toml tab="File (TOML)" # Accepts request from defined IP [tcp.middlewares] diff --git a/docs/content/middlewares/tcp/overview.md b/docs/content/middlewares/tcp/overview.md index cc1302530ac08a99616c2a095e537d1cd93fb0f1..ec28af85d48b167f42383a222baf8627ae76f13d 100644 --- a/docs/content/middlewares/tcp/overview.md +++ b/docs/content/middlewares/tcp/overview.md @@ -29,9 +29,9 @@ whoami: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: middlewaretcps.traefik.containo.us + name: middlewaretcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: MiddlewareTCP @@ -40,7 +40,7 @@ spec: scope: Namespaced --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: foo-ip-allowlist @@ -51,7 +51,7 @@ spec: - 192.168.1.7 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: ingressroute @@ -70,22 +70,6 @@ spec: - "traefik.tcp.routers.router1.middlewares=foo-ip-allowlist@consulcatalog" ``` -```json tab="Marathon" -"labels": { - "traefik.tcp.middlewares.foo-ip-allowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7", - "traefik.tcp.routers.router1.middlewares=foo-ip-allowlist@marathon" -} -``` - -```yaml tab="Rancher" -# As a Rancher Label -labels: - # Create a middleware named `foo-ip-allowlist` - - "traefik.tcp.middlewares.foo-ip-allowlist.ipallowlist.sourcerange=127.0.0.1/32, 192.168.1.7" - # Apply the middleware named `foo-ip-allowlist` to the router named `router1` - - "traefik.tcp.routers.router1.middlewares=foo-ip-allowlist@rancher" -``` - ```toml tab="File (TOML)" # As TOML Configuration File [tcp.routers] diff --git a/docs/content/migration/v1-to-v2.md b/docs/content/migration/v1-to-v2.md index c020a9a853f952089b0970283c336dca884a05f5..8d93e48f3dbc7b66fd072f7edfde30cd0c5820d9 100644 --- a/docs/content/migration/v1-to-v2.md +++ b/docs/content/migration/v1-to-v2.md @@ -110,7 +110,7 @@ Then any router can refer to an instance of the wanted middleware. ```yaml tab="K8s IngressRoute" # The definitions below require the definitions for the Middleware and IngressRoute kinds. # https://doc.traefik.io/traefik/reference/dynamic-configuration/kubernetes-crd/#definitions - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: basicauth @@ -123,7 +123,7 @@ Then any router can refer to an instance of the wanted middleware. - test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0 --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutebar @@ -281,7 +281,7 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o ```yaml tab="K8s IngressRoute" # The definitions below require the definitions for the TLSOption and IngressRoute kinds. # https://doc.traefik.io/traefik/reference/dynamic-configuration/kubernetes-crd/#definitions - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: mytlsoption @@ -297,7 +297,7 @@ Then, a [router's TLS field](../routing/routers/index.md#tls) can refer to one o - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutebar @@ -443,7 +443,7 @@ To apply a redirection: ``` ```yaml tab="K8s IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: http-redirect-ingressroute @@ -461,7 +461,7 @@ To apply a redirection: - name: https-redirect --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: https-ingressroute @@ -478,7 +478,7 @@ To apply a redirection: tls: {} --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: https-redirect @@ -597,7 +597,7 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo ```yaml tab="Kubernetes IngressRoute" --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: http-redirect-ingressroute @@ -614,7 +614,7 @@ with the path `/admin` stripped, e.g. to `http://<IP>:<port>/`. In this case, yo middlewares: - name: admin-stripprefix --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: admin-stripprefix diff --git a/docs/content/migration/v2-to-v3.md b/docs/content/migration/v2-to-v3.md index 27d38e953a3546f026c07163c2ddcf64cbe8ac9c..4792467b0ac9ab2db9df20a332450cab816a5323 100644 --- a/docs/content/migration/v2-to-v3.md +++ b/docs/content/migration/v2-to-v3.md @@ -26,20 +26,22 @@ In v3, the reported status code for gRPC requests is now the value of the `Grpc- - The `pilot` option has been removed from the static configuration. - The `tracing.datadog.globaltag` option has been removed. - The `namespace` option of Consul, Consul Catalog and Nomad providers has been removed. -- The `tls.caOptional` option has been removed from the ForwardAuth middleware, as well as from the HTTP, Consul, Etcd, Redis, ZooKeeper, Marathon, Consul Catalog, and Docker providers. +- The `tls.caOptional` option has been removed from the ForwardAuth middleware, as well as from the HTTP, Consul, Etcd, Redis, ZooKeeper, Consul Catalog, and Docker providers. - `sslRedirect`, `sslTemporaryRedirect`, `sslHost`, `sslForceHost` and `featurePolicy` options of the Headers middleware have been removed. - The `forceSlash` option of the StripPrefix middleware has been removed. -- the `preferServerCipherSuites` option has been removed. +- The `preferServerCipherSuites` option has been removed. ## Matchers In v3, the `Headers` and `HeadersRegexp` matchers have been renamed to `Header` and `HeaderRegexp` respectively. +`PathPrefix` no longer uses regular expressions to match path prefixes. + `QueryRegexp` has been introduced to match query values using a regular expression. `HeaderRegexp`, `HostRegexp`, `PathRegexp`, `QueryRegexp`, and `HostSNIRegexp` matchers now uses the [Go regexp syntax](https://golang.org/pkg/regexp/syntax/). -All matchers now take a single value (except `Headers`, `HeaderRegexp`, `Query`, and `QueryRegexp` which take two) +All matchers now take a single value (except `Header`, `HeaderRegexp`, `Query`, and `QueryRegexp` which take two) and should be explicitly combined using logical operators to mimic previous behavior. `Query` can take a single value to match is the query value that has no value (e.g. `/search?mobile`). @@ -55,3 +57,33 @@ One should use the `ContentType` middleware to enable the `Content-Type` header In v3, HTTP/3 is no longer an experimental feature. The `experimental.http3` option has been removed from the static configuration. + +## TCP ServersTransport + +In v3, the support of `TCPServersTransport` has been introduced. +When using the KubernetesCRD provider, it is therefore necessary to update [RBAC](../reference/dynamic-configuration/kubernetes-crd.md#rbac) and [CRD](../reference/dynamic-configuration/kubernetes-crd.md) manifests. + +### TCP LoadBalancer `terminationDelay` option + +The TCP LoadBalancer `terminationDelay` option has been removed. +This option can now be configured directly on the `TCPServersTransport` level, please take a look at this [documentation](../routing/services/index.md#terminationdelay) + +## Rancher v1 + +In v3, the rancher v1 provider has been removed because Rancher v1 is [no longer actively maintaned](https://rancher.com/docs/os/v1.x/en/support/) and v2 is supported as a standard Kubernetes provider. + +Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query. +As such, Rancher 2.x users should utilize the [Kubernetes CRD provider](../providers/kubernetes-crd.md) directly. + +## Marathon provider + +In v3, the Marathon provider has been removed. + +## InfluxDB v1 + +In v3, the InfluxDB v1 metrics provider has been removed because InfluxDB v1.x maintenance [ended in 2021](https://www.influxdata.com/blog/influxdb-oss-and-enterprise-roadmap-update-from-influxdays-emea/). + +### Kubernetes CRDs API Group `traefik.containo.us` + +In v3 the Kubernetes CRDs API Group `traefik.containo.us` has been removed. +Please use the API Group `traefik.io` instead. diff --git a/docs/content/migration/v2.md b/docs/content/migration/v2.md index 85634a0d95b0b76d9a2a4cd4d1565fd4bea6cfe0..60cb2b813443f4e0803ceb484f8a17237ea13199 100644 --- a/docs/content/migration/v2.md +++ b/docs/content/migration/v2.md @@ -65,13 +65,19 @@ rules: verbs: - update - apiGroups: + - traefik.io - traefik.containo.us resources: - middlewares + - middlewaretcps - ingressroutes - traefikservices - ingressroutetcps + - ingressrouteudps - tlsoptions + - tlsstores + - serverstransports + - serverstransporttcps verbs: - get - list @@ -164,20 +170,23 @@ rules: verbs: - update - apiGroups: + - traefik.io - traefik.containo.us resources: - middlewares + - middlewaretcps - ingressroutes - traefikservices - ingressroutetcps - ingressrouteudps - tlsoptions - tlsstores + - serverstransports + - serverstransporttcps verbs: - get - list - watch - ``` After having both resources applied, Traefik will work properly. @@ -496,3 +505,18 @@ In `v2.9`, Traefik Pilot support has been removed. ### Nomad Namespace In `v2.10`, the `namespace` option of the Nomad provider is deprecated, please use the `namespaces` options instead. + +## v2.10 + +### Kubernetes CRDs + +In `v2.10`, the Kubernetes CRDs API Group `traefik.containo.us` is deprecated, and its support will end starting with Traefik v3. Please use the API Group `traefik.io` instead. + +As the Kubernetes CRD provider still works with both API Versions (`traefik.io/v1alpha1` and `traefik.containo.us/v1alpha1`), +it means that for the same kind, namespace and name, the provider will only keep the `traefik.io/v1alpha1` resource. + +In addition, the Kubernetes CRDs API Version `traefik.io/v1alpha1` will not be supported in Traefik v3 itself. + +### Traefik Hub + +In `v2.10`, Traefik Hub is GA and the `experimental.hub` flag is deprecated. diff --git a/docs/content/observability/logs.md b/docs/content/observability/logs.md index 806d37b054c7cae133d35faf0763684ed490c064..5e22aa64da1575c9980925e2732469b13f4256ca 100644 --- a/docs/content/observability/logs.md +++ b/docs/content/observability/logs.md @@ -64,7 +64,9 @@ log: #### `level` -By default, the `level` is set to `ERROR`. Alternative logging levels are `TRACE`, `DEBUG`, `PANIC`, `FATAL`, `ERROR`, `WARN`, and `INFO`. +By default, the `level` is set to `ERROR`. + +Alternative logging levels are `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`, and `PANIC`. ```yaml tab="File (YAML)" log: diff --git a/docs/content/observability/metrics/influxdb.md b/docs/content/observability/metrics/influxdb.md deleted file mode 100644 index 0eb05e23ca0d0391e6dbb39335491db1bc7ca871..0000000000000000000000000000000000000000 --- a/docs/content/observability/metrics/influxdb.md +++ /dev/null @@ -1,268 +0,0 @@ ---- -title: "Traefik InfluxDB Documentation" -description: "Traefik supports several metrics backends, including InfluxDB. Learn how to implement it for observability in Traefik Proxy. Read the technical documentation." ---- - -# InfluxDB - -To enable the InfluxDB: - -```yaml tab="File (YAML)" -metrics: - influxDB: {} -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] -``` - -```bash tab="CLI" ---metrics.influxdb=true -``` - -#### `address` - -_Required, Default="localhost:8089"_ - -Address instructs exporter to send metrics to influxdb at this address. - -```yaml tab="File (YAML)" -metrics: - influxDB: - address: localhost:8089 -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - address = "localhost:8089" -``` - -```bash tab="CLI" ---metrics.influxdb.address=localhost:8089 -``` - -#### `protocol` - -_Required, Default="udp"_ - -InfluxDB's address protocol (udp or http). - -```yaml tab="File (YAML)" -metrics: - influxDB: - protocol: udp -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - protocol = "udp" -``` - -```bash tab="CLI" ---metrics.influxdb.protocol=udp -``` - -#### `database` - -_Optional, Default=""_ - -InfluxDB database used when protocol is http. - -```yaml tab="File (YAML)" -metrics: - influxDB: - database: db -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - database = "db" -``` - -```bash tab="CLI" ---metrics.influxdb.database=db -``` - -#### `retentionPolicy` - -_Optional, Default=""_ - -InfluxDB retention policy used when protocol is http. - -```yaml tab="File (YAML)" -metrics: - influxDB: - retentionPolicy: two_hours -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - retentionPolicy = "two_hours" -``` - -```bash tab="CLI" ---metrics.influxdb.retentionPolicy=two_hours -``` - -#### `username` - -_Optional, Default=""_ - -InfluxDB username (only with http). - -```yaml tab="File (YAML)" -metrics: - influxDB: - username: john -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - username = "john" -``` - -```bash tab="CLI" ---metrics.influxdb.username=john -``` - -#### `password` - -_Optional, Default=""_ - -InfluxDB password (only with http). - -```yaml tab="File (YAML)" -metrics: - influxDB: - password: secret -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - password = "secret" -``` - -```bash tab="CLI" ---metrics.influxdb.password=secret -``` - -#### `addEntryPointsLabels` - -_Optional, Default=true_ - -Enable metrics on entry points. - -```yaml tab="File (YAML)" -metrics: - influxDB: - addEntryPointsLabels: true -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - addEntryPointsLabels = true -``` - -```bash tab="CLI" ---metrics.influxdb.addEntryPointsLabels=true -``` - -#### `addRoutersLabels` - -_Optional, Default=false_ - -Enable metrics on routers. - -```yaml tab="File (YAML)" -metrics: - influxDB: - addRoutersLabels: true -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - addRoutersLabels = true -``` - -```bash tab="CLI" ---metrics.influxdb.addrouterslabels=true -``` - -#### `addServicesLabels` - -_Optional, Default=true_ - -Enable metrics on services. - -```yaml tab="File (YAML)" -metrics: - influxDB: - addServicesLabels: true -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - addServicesLabels = true -``` - -```bash tab="CLI" ---metrics.influxdb.addServicesLabels=true -``` - -#### `pushInterval` - -_Optional, Default=10s_ - -The interval used by the exporter to push metrics to influxdb. - -```yaml tab="File (YAML)" -metrics: - influxDB: - pushInterval: 10s -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - pushInterval = "10s" -``` - -```bash tab="CLI" ---metrics.influxdb.pushInterval=10s -``` - -#### `additionalLabels` - -_Optional, Default={}_ - -Additional labels (influxdb tags) on all metrics. - -```yaml tab="File (YAML)" -metrics: - influxDB: - additionalLabels: - host: example.com - environment: production -``` - -```toml tab="File (TOML)" -[metrics] - [metrics.influxDB] - [metrics.influxDB.additionalLabels] - host = "example.com" - environment = "production" -``` - -```bash tab="CLI" ---metrics.influxdb.additionallabels.host=example.com --metrics.influxdb.additionallabels.environment=production -``` diff --git a/docs/content/observability/metrics/opentelemetry.md b/docs/content/observability/metrics/opentelemetry.md index e3abed40af85096bb1b321cba7a4b4a3b807c26a..af0ba7b200196b2692f4eeace6a75e241c547484 100644 --- a/docs/content/observability/metrics/opentelemetry.md +++ b/docs/content/observability/metrics/opentelemetry.md @@ -208,7 +208,7 @@ metrics: #### `path` -_Required, Default="/v1/traces"_ +_Required, Default="/v1/metrics"_ Allows to override the default URL path used for sending metrics. This option has no effect when using gRPC transport. @@ -216,17 +216,17 @@ This option has no effect when using gRPC transport. ```yaml tab="File (YAML)" metrics: openTelemetry: - path: /foo/v1/traces + path: /foo/v1/metrics ``` ```toml tab="File (TOML)" [metrics] [metrics.openTelemetry] - path = "/foo/v1/traces" + path = "/foo/v1/metrics" ``` ```bash tab="CLI" ---metrics.openTelemetry.path=/foo/v1/traces +--metrics.openTelemetry.path=/foo/v1/metrics ``` #### `tls` diff --git a/docs/content/observability/metrics/overview.md b/docs/content/observability/metrics/overview.md index 0fce7e76c6ebad8350919d6050bdea097f7ccec2..795d1a377d827bc4430f89dd4db75d42bca088d7 100644 --- a/docs/content/observability/metrics/overview.md +++ b/docs/content/observability/metrics/overview.md @@ -1,6 +1,6 @@ --- title: "Traefik Metrics Overview" -description: "Traefik Proxy supports these metrics backend systems: Datadog, InfluxDB, Prometheus, and StatsD. Read the full documentation to get started." +description: "Traefik Proxy supports these metrics backend systems: Datadog, InfluxDB 2.X, Prometheus, and StatsD. Read the full documentation to get started." --- # Metrics @@ -8,7 +8,6 @@ description: "Traefik Proxy supports these metrics backend systems: Datadog, Inf Traefik supports these metrics backends: - [Datadog](./datadog.md) -- [InfluxDB](./influxdb.md) - [InfluxDB2](./influxdb2.md) - [Prometheus](./prometheus.md) - [StatsD](./statsd.md) @@ -17,27 +16,31 @@ Traefik Proxy hosts an official Grafana dashboard for both [on-premises](https:/ ## Global Metrics -| Metric | Type | Description | -|---------------------------------------------|---------|---------------------------------------------------------| -| Config reload total | Count | The total count of configuration reloads. | -| Config reload last success | Gauge | The timestamp of the last configuration reload success. | -| TLS certificates not after | Gauge | The expiration date of certificates. | +| Metric | Type | [Labels](#labels) | Description | +|----------------------------|-------|--------------------------|--------------------------------------------------------------------| +| Config reload total | Count | | The total count of configuration reloads. | +| Config reload last success | Gauge | | The timestamp of the last configuration reload success. | +| Open connections | Gauge | `entrypoint`, `protocol` | The current count of open connections, by entrypoint and protocol. | +| TLS certificates not after | Gauge | | The expiration date of certificates. | ```prom tab="Prometheus" traefik_config_reloads_total traefik_config_last_reload_success +traefik_open_connections traefik_tls_certs_not_after ``` ```dd tab="Datadog" config.reload.total config.reload.lastSuccessTimestamp +open.connections tls.certs.notAfterTimestamp ``` -```influxdb tab="InfluxDB / InfluxDB2" +```influxdb tab="InfluxDB2" traefik.config.reload.total traefik.config.reload.lastSuccessTimestamp +traefik.open.connections traefik.tls.certs.notAfterTimestamp ``` @@ -45,17 +48,35 @@ traefik.tls.certs.notAfterTimestamp # Default prefix: "traefik" {prefix}.config.reload.total {prefix}.config.reload.lastSuccessTimestamp +{prefix}.open.connections {prefix}.tls.certs.notAfterTimestamp ``` -## EntryPoint Metrics +```opentelemetry tab="OpenTelemetry" +traefik_config_reloads_total +traefik_config_last_reload_success +traefik_open_connections +traefik_tls_certs_not_after +``` + +### Labels + +Here is a comprehensive list of labels that are provided by the global metrics: + +| Label | Description | example | +|---------------|----------------------------------------|----------------------| +| `entrypoint` | Entrypoint that handled the connection | "example_entrypoint" | +| `protocol` | Connection protocol | "TCP" | + +## HTTP Metrics + +### EntryPoint Metrics | Metric | Type | [Labels](#labels) | Description | |-----------------------|-----------|--------------------------------------------|---------------------------------------------------------------------| | Requests total | Count | `code`, `method`, `protocol`, `entrypoint` | The total count of HTTP requests received by an entrypoint. | | Requests TLS total | Count | `tls_version`, `tls_cipher`, `entrypoint` | The total count of HTTPS requests received by an entrypoint. | | Request duration | Histogram | `code`, `method`, `protocol`, `entrypoint` | Request processing duration histogram on an entrypoint. | -| Open connections | Count | `method`, `protocol`, `entrypoint` | The current count of open connections on an entrypoint. | | Requests bytes total | Count | `code`, `method`, `protocol`, `entrypoint` | The total size of HTTP requests in bytes handled by an entrypoint. | | Responses bytes total | Count | `code`, `method`, `protocol`, `entrypoint` | The total size of HTTP responses in bytes handled by an entrypoint. | @@ -63,7 +84,6 @@ traefik.tls.certs.notAfterTimestamp traefik_entrypoint_requests_total traefik_entrypoint_requests_tls_total traefik_entrypoint_request_duration_seconds -traefik_entrypoint_open_connections traefik_entrypoint_requests_bytes_total traefik_entrypoint_responses_bytes_total ``` @@ -72,16 +92,14 @@ traefik_entrypoint_responses_bytes_total entrypoint.request.total entrypoint.request.tls.total entrypoint.request.duration -entrypoint.connections.open entrypoint.requests.bytes.total entrypoint.responses.bytes.total ``` -```influxdb tab="InfluxDB / InfluxDB2" +```influxdb tab="InfluxDB2" traefik.entrypoint.requests.total traefik.entrypoint.requests.tls.total traefik.entrypoint.request.duration -traefik.entrypoint.connections.open traefik.entrypoint.requests.bytes.total traefik.entrypoint.responses.bytes.total ``` @@ -91,19 +109,26 @@ traefik.entrypoint.responses.bytes.total {prefix}.entrypoint.request.total {prefix}.entrypoint.request.tls.total {prefix}.entrypoint.request.duration -{prefix}.entrypoint.connections.open {prefix}.entrypoint.requests.bytes.total {prefix}.entrypoint.responses.bytes.total ``` -## Router Metrics +```opentelemetry tab="OpenTelemetry" +traefik_entrypoint_requests_total +traefik_entrypoint_requests_tls_total +traefik_entrypoint_request_duration_seconds +traefik_entrypoint_open_connections +traefik_entrypoint_requests_bytes_total +traefik_entrypoint_responses_bytes_total +``` + +### Router Metrics | Metric | Type | [Labels](#labels) | Description | |-----------------------|-----------|---------------------------------------------------|----------------------------------------------------------------| | Requests total | Count | `code`, `method`, `protocol`, `router`, `service` | The total count of HTTP requests handled by a router. | | Requests TLS total | Count | `tls_version`, `tls_cipher`, `router`, `service` | The total count of HTTPS requests handled by a router. | | Request duration | Histogram | `code`, `method`, `protocol`, `router`, `service` | Request processing duration histogram on a router. | -| Open connections | Count | `method`, `protocol`, `router`, `service` | The current count of open connections on a router. | | Requests bytes total | Count | `code`, `method`, `protocol`, `router`, `service` | The total size of HTTP requests in bytes handled by a router. | | Responses bytes total | Count | `code`, `method`, `protocol`, `router`, `service` | The total size of HTTP responses in bytes handled by a router. | @@ -111,7 +136,6 @@ traefik.entrypoint.responses.bytes.total traefik_router_requests_total traefik_router_requests_tls_total traefik_router_request_duration_seconds -traefik_router_open_connections traefik_router_requests_bytes_total traefik_router_responses_bytes_total ``` @@ -120,16 +144,14 @@ traefik_router_responses_bytes_total router.request.total router.request.tls.total router.request.duration -router.connections.open router.requests.bytes.total router.responses.bytes.total ``` -```influxdb tab="InfluxDB / InfluxDB2" +```influxdb tab="InfluxDB2" traefik.router.requests.total traefik.router.requests.tls.total traefik.router.request.duration -traefik.router.connections.open traefik.router.requests.bytes.total traefik.router.responses.bytes.total ``` @@ -139,19 +161,26 @@ traefik.router.responses.bytes.total {prefix}.router.request.total {prefix}.router.request.tls.total {prefix}.router.request.duration -{prefix}.router.connections.open {prefix}.router.requests.bytes.total {prefix}.router.responses.bytes.total ``` -## Service Metrics +```opentelemetry tab="OpenTelemetry" +traefik_router_requests_total +traefik_router_requests_tls_total +traefik_router_request_duration_seconds +traefik_router_open_connections +traefik_router_requests_bytes_total +traefik_router_responses_bytes_total +``` + +### Service Metrics | Metric | Type | Labels | Description | |-----------------------|-----------|-----------------------------------------|-------------------------------------------------------------| | Requests total | Count | `code`, `method`, `protocol`, `service` | The total count of HTTP requests processed on a service. | | Requests TLS total | Count | `tls_version`, `tls_cipher`, `service` | The total count of HTTPS requests processed on a service. | | Request duration | Histogram | `code`, `method`, `protocol`, `service` | Request processing duration histogram on a service. | -| Open connections | Count | `method`, `protocol`, `service` | The current count of open connections on a service. | | Retries total | Count | `service` | The count of requests retries on a service. | | Server UP | Gauge | `service`, `url` | Current service's server status, 0 for a down or 1 for up. | | Requests bytes total | Count | `code`, `method`, `protocol`, `service` | The total size of requests in bytes received by a service. | @@ -161,7 +190,6 @@ traefik.router.responses.bytes.total traefik_service_requests_total traefik_service_requests_tls_total traefik_service_request_duration_seconds -traefik_service_open_connections traefik_service_retries_total traefik_service_server_up traefik_service_requests_bytes_total @@ -172,18 +200,16 @@ traefik_service_responses_bytes_total service.request.total router.service.tls.total service.request.duration -service.connections.open service.retries.total service.server.up service.requests.bytes.total service.responses.bytes.total ``` -```influxdb tab="InfluxDB / InfluxDB2" +```influxdb tab="InfluxDB2" traefik.service.requests.total traefik.service.requests.tls.total traefik.service.request.duration -traefik.service.connections.open traefik.service.retries.total traefik.service.server.up traefik.service.requests.bytes.total @@ -195,14 +221,24 @@ traefik.service.responses.bytes.total {prefix}.service.request.total {prefix}.service.request.tls.total {prefix}.service.request.duration -{prefix}.service.connections.open {prefix}.service.retries.total {prefix}.service.server.up {prefix}.service.requests.bytes.total {prefix}.service.responses.bytes.total ``` -## Labels +```opentelemetry tab="OpenTelemetry" +traefik_service_requests_total +traefik_service_requests_tls_total +traefik_service_request_duration_seconds +traefik_service_open_connections +traefik_service_retries_total +traefik_service_server_up +traefik_service_requests_bytes_total +traefik_service_responses_bytes_total +``` + +### Labels Here is a comprehensive list of labels that are provided by the metrics: diff --git a/docs/content/observability/metrics/prometheus.md b/docs/content/observability/metrics/prometheus.md index da7f73773926250d1c2e76193b7e06c7b50a66e3..be3e29cb62a21a4f0e6123071b4c86db38b57d47 100644 --- a/docs/content/observability/metrics/prometheus.md +++ b/docs/content/observability/metrics/prometheus.md @@ -165,3 +165,66 @@ metrics: ```bash tab="CLI" --metrics.prometheus.manualrouting=true ``` + +#### `headerLabels` + +_Optional_ + +Defines the extra labels for the `requests_total` metrics, and for each of them, the request header containing the value for this label. +Please note that if the header is not present in the request it will be added nonetheless with an empty value. +In addition, the label should be a valid label name for Prometheus metrics, +otherwise, the Prometheus metrics provider will fail to serve any Traefik-related metric. + +```yaml tab="File (YAML)" +metrics: + prometheus: + headerLabels: + label: headerKey +``` + +```toml tab="File (TOML)" +[metrics] + [metrics.prometheus] + [metrics.prometheus.headerLabels] + label = "headerKey" +``` + +```bash tab="CLI" +--metrics.prometheus.headerlabels.label=headerKey +``` + +##### Example + +Here is an example of the entryPoint `requests_total` metric with an additional "useragent" label. + +When configuring the label in Static Configuration: + +```yaml tab="File (YAML)" +metrics: + prometheus: + headerLabels: + useragent: User-Agent +``` + +```toml tab="File (TOML)" +[metrics] + [metrics.prometheus] + [metrics.prometheus.headerLabels] + useragent = "User-Agent" +``` + +```bash tab="CLI" +--metrics.prometheus.headerlabels.useragent=User-Agent +``` + +And performing a request with a custom User-Agent: + +```bash +curl -H "User-Agent: foobar" http://localhost +``` + +The following metric is produced : + +```bash +traefik_entrypoint_requests_total{code="200",entrypoint="web",method="GET",protocol="http",useragent="foobar"} 1 +``` \ No newline at end of file diff --git a/docs/content/observability/tracing/datadog.md b/docs/content/observability/tracing/datadog.md index a6c93f22a5b163eaaf30d1b5a2df6a0d8e068e38..fe14bc72f6e1eaa2d7b4a79103184f5d0adaf855 100644 --- a/docs/content/observability/tracing/datadog.md +++ b/docs/content/observability/tracing/datadog.md @@ -23,24 +23,46 @@ tracing: #### `localAgentHostPort` -_Required, Default="127.0.0.1:8126"_ +_Optional, Default="localhost:8126"_ Local Agent Host Port instructs the reporter to send spans to the Datadog Agent at this address (host:port). ```yaml tab="File (YAML)" tracing: datadog: - localAgentHostPort: 127.0.0.1:8126 + localAgentHostPort: localhost:8126 ``` ```toml tab="File (TOML)" [tracing] [tracing.datadog] - localAgentHostPort = "127.0.0.1:8126" + localAgentHostPort = "localhost:8126" ``` ```bash tab="CLI" ---tracing.datadog.localAgentHostPort=127.0.0.1:8126 +--tracing.datadog.localAgentHostPort=localhost:8126 +``` + +#### `localAgentSocket` + +_Optional, Default=""_ + +Local Agent Socket instructs the reporter to send spans to the Datadog Agent at this UNIX socket. + +```yaml tab="File (YAML)" +tracing: + datadog: + localAgentSocket: /var/run/datadog/apm.socket +``` + +```toml tab="File (TOML)" +[tracing] + [tracing.datadog] + localAgentSocket = "/var/run/datadog/apm.socket" +``` + +```bash tab="CLI" +--tracing.datadog.localAgentSocket=/var/run/datadog/apm.socket ``` #### `debug` diff --git a/docs/content/observability/tracing/overview.md b/docs/content/observability/tracing/overview.md index 73504a14065b710656deb4e2cb332e2192e57e63..f4126274ad076395719ab091a201cc56d2990cde 100644 --- a/docs/content/observability/tracing/overview.md +++ b/docs/content/observability/tracing/overview.md @@ -12,7 +12,7 @@ The tracing system allows developers to visualize call flows in their infrastruc Traefik uses OpenTracing, an open standard designed for distributed tracing. -Traefik supports six tracing backends: +Traefik supports seven tracing backends: - [Jaeger](./jaeger.md) - [Zipkin](./zipkin.md) @@ -20,6 +20,7 @@ Traefik supports six tracing backends: - [Instana](./instana.md) - [Haystack](./haystack.md) - [Elastic](./elastic.md) +- [OpenTelemetry](./opentelemetry.md) ## Configuration diff --git a/docs/content/operations/include-api-examples.md b/docs/content/operations/include-api-examples.md index 33fc71a090f49a712646d1ade082a000371951c1..d98db97a9bcc2b156951d431cf1dcbc490a58ad0 100644 --- a/docs/content/operations/include-api-examples.md +++ b/docs/content/operations/include-api-examples.md @@ -20,7 +20,7 @@ deploy: ``` ```yaml tab="Kubernetes CRD" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard @@ -34,7 +34,7 @@ spec: middlewares: - name: auth --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: auth @@ -51,24 +51,6 @@ spec: - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" ``` -```json tab="Marathon" -"labels": { - "traefik.http.routers.api.rule": "Host(`traefik.example.com`)", - "traefik.http.routers.api.service": "api@internal", - "traefik.http.routers.api.middlewares": "auth", - "traefik.http.middlewares.auth.basicauth.users": "test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" -} -``` - -```yaml tab="Rancher" -# Dynamic Configuration -labels: - - "traefik.http.routers.api.rule=Host(`traefik.example.com`)" - - "traefik.http.routers.api.service=api@internal" - - "traefik.http.routers.api.middlewares=auth" - - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" -``` - ```yaml tab="File (YAML)" # Dynamic Configuration http: diff --git a/docs/content/operations/include-dashboard-examples.md b/docs/content/operations/include-dashboard-examples.md index eb72d3a0a8c8a5c9aad71215b670f78779607c22..5965d7070898e850d985ec0ae39a444bd8e3f3fe 100644 --- a/docs/content/operations/include-dashboard-examples.md +++ b/docs/content/operations/include-dashboard-examples.md @@ -20,7 +20,7 @@ deploy: ``` ```yaml tab="Kubernetes CRD" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard @@ -34,7 +34,7 @@ spec: middlewares: - name: auth --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: auth @@ -51,24 +51,6 @@ spec: - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" ``` -```json tab="Marathon" -"labels": { - "traefik.http.routers.dashboard.rule": "Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))", - "traefik.http.routers.dashboard.service": "api@internal", - "traefik.http.routers.dashboard.middlewares": "auth", - "traefik.http.middlewares.auth.basicauth.users": "test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" -} -``` - -```yaml tab="Rancher" -# Dynamic Configuration -labels: - - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))" - - "traefik.http.routers.dashboard.service=api@internal" - - "traefik.http.routers.dashboard.middlewares=auth" - - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" -``` - ```yaml tab="File (YAML)" # Dynamic Configuration http: diff --git a/docs/content/providers/docker.md b/docs/content/providers/docker.md index 8fd567356282587fc16ee03dbd994eac60d42761..177a397026688b64679dae7da6e0d675a1e1e8e4 100644 --- a/docs/content/providers/docker.md +++ b/docs/content/providers/docker.md @@ -95,7 +95,7 @@ and [Docker Swarm Mode](https://docs.docker.com/engine/swarm/). ## Routing Configuration When using Docker as a [provider](./overview.md), -Traefik uses [container labels](https://docs.docker.com/engine/reference/commandline/run/#set-metadata-on-container--l---label---label-file) to retrieve its routing configuration. +Traefik uses [container labels](https://docs.docker.com/engine/reference/commandline/run/#label) to retrieve its routing configuration. See the list of labels in the dedicated [routing](../routing/providers/docker.md) section. @@ -440,10 +440,11 @@ _Optional, Default=```Host(`{{ normalize .Name }}`)```_ The `defaultRule` option defines what routing rule to apply to a container if no rule is defined by a label. -It must be a valid [Go template](https://pkg.go.dev/text/template/), and can use -[sprig template functions](https://masterminds.github.io/sprig/). -The container service name can be accessed with the `Name` identifier, -and the template has access to all the labels defined on this container. +It must be a valid [Go template](https://pkg.go.dev/text/template/), +and can use [sprig template functions](https://masterminds.github.io/sprig/). +The container name can be accessed with the `ContainerName` identifier. +The service name can be accessed with the `Name` identifier. +The template has access to all the labels defined on this container with the `Labels` identifier. ```yaml tab="File (YAML)" providers: diff --git a/docs/content/providers/kubernetes-crd.md b/docs/content/providers/kubernetes-crd.md index dccc60eb6dc7c3c651279dceddaea98c53fd5c82..26579d7583213c3677279114ef5cf13da3758ed7 100644 --- a/docs/content/providers/kubernetes-crd.md +++ b/docs/content/providers/kubernetes-crd.md @@ -35,10 +35,10 @@ the Traefik engineering team developed a [Custom Resource Definition](https://ku ```bash # Install Traefik Resource Definitions: - kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.9/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml + kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml # Install RBAC for Traefik: - kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.9/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml + kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml ``` ## Resource Configuration diff --git a/docs/content/providers/kubernetes-ingress.md b/docs/content/providers/kubernetes-ingress.md index a35017cc5d7a26bbc959edea6aedc650e47b9a65..d6eb1b4e9e3f9beaddb258109d238eee296ce807 100644 --- a/docs/content/providers/kubernetes-ingress.md +++ b/docs/content/providers/kubernetes-ingress.md @@ -344,6 +344,35 @@ providers: --providers.kubernetesingress.ingressclass=traefik-internal ``` +### `disableIngressClassLookup` + +_Optional, Default: false_ + +If the parameter is set to `true`, +Traefik will not discover IngressClasses in the cluster. +By doing so, it alleviates the requirement of giving Traefik the rights to look IngressClasses up. +Furthermore, when this option is set to `true`, +Traefik is not able to handle Ingresses with IngressClass references, +therefore such Ingresses will be ignored. +Please note that annotations are not affected by this option. + +```yaml tab="File (YAML)" +providers: + kubernetesIngress: + disableIngressClassLookup: true + # ... +``` + +```toml tab="File (TOML)" +[providers.kubernetesIngress] + disableIngressClassLookup = true + # ... +``` + +```bash tab="CLI" +--providers.kubernetesingress.disableingressclasslookup=true +``` + ### `ingressEndpoint` #### `hostname` @@ -502,6 +531,6 @@ providers: ### Further To learn more about the various aspects of the Ingress specification that Traefik supports, -many examples of Ingresses definitions are located in the test [examples](https://github.com/traefik/traefik/tree/v2.9/pkg/provider/kubernetes/ingress/fixtures) of the Traefik repository. +many examples of Ingresses definitions are located in the test [examples](https://github.com/traefik/traefik/tree/v3.0/pkg/provider/kubernetes/ingress/fixtures) of the Traefik repository. {!traefik-for-business-applications.md!} diff --git a/docs/content/providers/marathon.md b/docs/content/providers/marathon.md deleted file mode 100644 index a0ab85ccb9d19662f212b9538bfb5bd253992bd3..0000000000000000000000000000000000000000 --- a/docs/content/providers/marathon.md +++ /dev/null @@ -1,583 +0,0 @@ ---- -title: "Traefik Configuration for Marathon" -description: "Traefik Proxy can be configured to use Marathon as a provider. Read the technical documentation to learn how." ---- - -# Traefik & Marathon - -Traefik can be configured to use Marathon as a provider. -{: .subtitle } - -For additional information, refer to [Marathon user guide](../user-guides/marathon.md). - -## Configuration Examples - -??? example "Configuring Marathon & Deploying / Exposing Applications" - - Enabling the Marathon provider - - ```yaml tab="File (YAML)" - providers: - marathon: {} - ``` - - ```toml tab="File (TOML)" - [providers.marathon] - ``` - - ```bash tab="CLI" - --providers.marathon=true - ``` - - Attaching labels to Marathon applications - - ```json - { - "id": "/whoami", - "container": { - "type": "DOCKER", - "docker": { - "image": "traefik/whoami", - "network": "BRIDGE", - "portMappings": [ - { - "containerPort": 80, - "hostPort": 0, - "protocol": "tcp" - } - ] - } - }, - "labels": { - "traefik.http.Routers.app.Rule": "PathPrefix(`/app`)" - } - } - ``` - -## Routing Configuration - -See the dedicated section in [routing](../routing/providers/marathon.md). - -## Provider Configuration - -### `basic` - -_Optional_ - -Enables Marathon basic authentication. - -```yaml tab="File (YAML)" -providers: - marathon: - basic: - httpBasicAuthUser: foo - httpBasicPassword: bar -``` - -```toml tab="File (TOML)" -[providers.marathon.basic] - httpBasicAuthUser = "foo" - httpBasicPassword = "bar" -``` - -```bash tab="CLI" ---providers.marathon.basic.httpbasicauthuser=foo ---providers.marathon.basic.httpbasicpassword=bar -``` - -### `dcosToken` - -_Optional_ - -Datacenter Operating System (DCOS) Token for DCOS environment. - -If set, it overrides the Authorization header. - -```toml tab="File (YAML)" -providers: - marathon: - dcosToken: "xxxxxx" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - dcosToken = "xxxxxx" - # ... -``` - -```bash tab="CLI" ---providers.marathon.dcosToken=xxxxxx -``` - -### `defaultRule` - -_Optional, Default=```Host(`{{ normalize .Name }}`)```_ - -The default host rule for all services. - -For a given application, if no routing rule was defined by a label, it is defined by this `defaultRule` instead. - -It must be a valid [Go template](https://pkg.go.dev/text/template/), -and can include [sprig template functions](https://masterminds.github.io/sprig/). - -The app ID can be accessed with the `Name` identifier, -and the template has access to all the labels defined on this Marathon application. - -```yaml tab="File (YAML)" -providers: - marathon: - defaultRule: "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" - # ... -``` - -```bash tab="CLI" ---providers.marathon.defaultRule=Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`) -# ... -``` - -### `dialerTimeout` - -_Optional, Default=5s_ - -Amount of time the Marathon provider should wait before timing out, -when trying to open a TCP connection to a Marathon master. - -The value of `dialerTimeout` should be provided in seconds or as a valid duration format, -see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration). - -```yaml tab="File (YAML)" -providers: - marathon: - dialerTimeout: "10s" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - dialerTimeout = "10s" - # ... -``` - -```bash tab="CLI" ---providers.marathon.dialerTimeout=10s -``` - -### `endpoint` - -_Optional, Default=http://127.0.0.1:8080_ - -Marathon server endpoint. - -You can optionally specify multiple endpoints. - -```yaml tab="File (YAML)" -providers: - marathon: - endpoint: "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - endpoint = "http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080" - # ... -``` - -```bash tab="CLI" ---providers.marathon.endpoint=http://10.241.1.71:8080,10.241.1.72:8080,10.241.1.73:8080 -``` - -### `exposedByDefault` - -_Optional, Default=true_ - -Exposes Marathon applications by default through Traefik. - -If set to `false`, applications that do not have a `traefik.enable=true` label are ignored from the resulting routing configuration. - -For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). - -```yaml tab="File (YAML)" -providers: - marathon: - exposedByDefault: false - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - exposedByDefault = false - # ... -``` - -```bash tab="CLI" ---providers.marathon.exposedByDefault=false -# ... -``` - -### `constraints` - -_Optional, Default=""_ - -The `constraints` option can be set to an expression that Traefik matches against the application labels to determine whether -to create any route for that application. If none of the application labels match the expression, no route for that application is -created. In addition, the expression is also matched against the application constraints, such as described -in [Marathon constraints](https://mesosphere.github.io/marathon/docs/constraints.html). -If the expression is empty, all detected applications are included. - -The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions, as well as the usual boolean logic. -In addition, to match against Marathon constraints, the function `MarathonConstraint("field:operator:value")` can be used, where the field, operator, and value parts are concatenated in a single string using the `:` separator. - -??? example "Constraints Expression Examples" - - ```toml - # Includes only applications having a label with key `a.label.name` and value `foo` - constraints = "Label(`a.label.name`, `foo`)" - ``` - - ```toml - # Excludes applications having any label with key `a.label.name` and value `foo` - constraints = "!Label(`a.label.name`, `value`)" - ``` - - ```toml - # With logical AND. - constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)" - ``` - - ```toml - # With logical OR. - constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)" - ``` - - ```toml - # With logical AND and OR, with precedence set by parentheses. - constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))" - ``` - - ```toml - # Includes only applications having a label with key `a.label.name` and a value matching the `a.+` regular expression. - constraints = "LabelRegex(`a.label.name`, `a.+`)" - ``` - - ```toml - # Includes only applications having a Marathon constraint with field `A`, operator `B`, and value `C`. - constraints = "MarathonConstraint(`A:B:C`)" - ``` - - ```toml - # Uses both Marathon constraint and application label with logical operator. - constraints = "MarathonConstraint(`A:B:C`) && Label(`a.label.name`, `value`)" - ``` - -For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). - -```yaml tab="File (YAML)" -providers: - marathon: - constraints: "Label(`a.label.name`,`foo`)" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - constraints = "Label(`a.label.name`,`foo`)" - # ... -``` - -```bash tab="CLI" ---providers.marathon.constraints=Label(`a.label.name`,`foo`) -# ... -``` - -### `forceTaskHostname` - -_Optional, Default=false_ - -By default, the task IP address (as returned by the Marathon API) is used as backend server if an IP-per-task configuration can be found; -otherwise, the name of the host running the task is used. -The latter behavior can be enforced by setting this option to `true`. - -```yaml tab="File (YAML)" -providers: - marathon: - forceTaskHostname: true - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - forceTaskHostname = true - # ... -``` - -```bash tab="CLI" ---providers.marathon.forceTaskHostname=true -# ... -``` - -### `keepAlive` - -_Optional, Default=10s_ - -Set the TCP Keep Alive duration for the Marathon HTTP Client. -The value of `keepAlive` should be provided in seconds or as a valid duration format, -see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration). - -```yaml tab="File (YAML)" -providers: - marathon: - keepAlive: "30s" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - keepAlive = "30s" - # ... -``` - -```bash tab="CLI" ---providers.marathon.keepAlive=30s -# ... -``` - -### `respectReadinessChecks` - -_Optional, Default=false_ - -Applications may define readiness checks which are probed by Marathon during deployments periodically, and these check results are exposed via the API. -Enabling `respectReadinessChecks` causes Traefik to filter out tasks whose readiness checks have not succeeded. -Note that the checks are only valid during deployments. - -See the Marathon guide for details. - -```yaml tab="File (YAML)" -providers: - marathon: - respectReadinessChecks: true - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - respectReadinessChecks = true - # ... -``` - -```bash tab="CLI" ---providers.marathon.respectReadinessChecks=true -# ... -``` - -### `responseHeaderTimeout` - -_Optional, Default=60s_ - -Amount of time the Marathon provider should wait before timing out when waiting for the first response header -from a Marathon master. - -The value of `responseHeaderTimeout` should be provided in seconds or as a valid duration format, -see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration). - -```yaml tab="File (YAML)" -providers: - marathon: - responseHeaderTimeout: "66s" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - responseHeaderTimeout = "66s" - # ... -``` - -```bash tab="CLI" ---providers.marathon.responseHeaderTimeout=66s -# ... -``` - -### `tls` - -_Optional_ - -Defines the TLS configuration used for the secure connection to Marathon. - -#### `ca` - -`ca` is the path to the certificate authority used for the secure connection to Marathon, -it defaults to the system bundle. - -```yaml tab="File (YAML)" -providers: - marathon: - tls: - ca: path/to/ca.crt -``` - -```toml tab="File (TOML)" -[providers.marathon.tls] - ca = "path/to/ca.crt" -``` - -```bash tab="CLI" ---providers.marathon.tls.ca=path/to/ca.crt -``` - -#### `cert` - -_Optional_ - -`cert` is the path to the public certificate used for the secure connection to Marathon. -When using this option, setting the `key` option is required. - -```yaml tab="File (YAML)" -providers: - marathon: - tls: - cert: path/to/foo.cert - key: path/to/foo.key -``` - -```toml tab="File (TOML)" -[providers.marathon.tls] - cert = "path/to/foo.cert" - key = "path/to/foo.key" -``` - -```bash tab="CLI" ---providers.marathon.tls.cert=path/to/foo.cert ---providers.marathon.tls.key=path/to/foo.key -``` - -#### `key` - -_Optional_ - -`key` is the path to the private key used for the secure connection to Marathon. -When using this option, setting the `cert` option is required. - -```yaml tab="File (YAML)" -providers: - marathon: - tls: - cert: path/to/foo.cert - key: path/to/foo.key -``` - -```toml tab="File (TOML)" -[providers.marathon.tls] - cert = "path/to/foo.cert" - key = "path/to/foo.key" -``` - -```bash tab="CLI" ---providers.marathon.tls.cert=path/to/foo.cert ---providers.marathon.tls.key=path/to/foo.key -``` - -#### `insecureSkipVerify` - -_Optional, Default=false_ - -If `insecureSkipVerify` is `true`, the TLS connection to Marathon accepts any certificate presented by the server regardless of the hostnames it covers. - -```yaml tab="File (YAML)" -providers: - marathon: - tls: - insecureSkipVerify: true -``` - -```toml tab="File (TOML)" -[providers.marathon.tls] - insecureSkipVerify = true -``` - -```bash tab="CLI" ---providers.marathon.tls.insecureSkipVerify=true -``` - -### `tlsHandshakeTimeout` - -_Optional, Default=5s_ - -Amount of time the Marathon provider should wait before timing out, -when waiting for the TLS handshake to complete. - -The value of `tlsHandshakeTimeout` should be provided in seconds or as a valid duration format, -see [time.ParseDuration](https://golang.org/pkg/time/#ParseDuration). - -```yaml tab="File (YAML)" -providers: - marathon: - tlsHandshakeTimeout: "10s" - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - tlsHandshakeTimeout = "10s" - # ... -``` - -```bash tab="CLI" ---providers.marathon.tlsHandshakeTimeout=10s -# ... -``` - -### `trace` - -_Optional, Default=false_ - -Displays additional provider logs when available. - -```yaml tab="File (YAML)" -providers: - marathon: - trace: true - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - trace = true - # ... -``` - -```bash tab="CLI" ---providers.marathon.trace=true -# ... -``` - -### `watch` - -_Optional, Default=true_ - -When set to `true`, watches for Marathon changes. - -```yaml tab="File (YAML)" -providers: - marathon: - watch: false - # ... -``` - -```toml tab="File (TOML)" -[providers.marathon] - watch = false - # ... -``` - -```bash tab="CLI" ---providers.marathon.watch=false -# ... -``` diff --git a/docs/content/providers/nomad.md b/docs/content/providers/nomad.md index 3bc27d3b2fb33d55d296234bae71a6d5ed23545d..90b3eeb4defefc451e50566c71117cb25cdd1c94 100644 --- a/docs/content/providers/nomad.md +++ b/docs/content/providers/nomad.md @@ -442,6 +442,36 @@ For additional information, refer to [Restrict the Scope of Service Discovery](. ### `namespaces` +??? warning "Deprecated in favor of the [`namespaces`](#namespaces) option." + + _Optional, Default=""_ + + The `namespace` option defines the namespace in which the Nomad services will be discovered. + + !!! warning + + One should only define either the `namespaces` option or the `namespace` option. + + ```yaml tab="File (YAML)" + providers: + nomad: + namespace: "production" + # ... + ``` + + ```toml tab="File (TOML)" + [providers.nomad] + namespace = "production" + # ... + ``` + + ```bash tab="CLI" + --providers.nomad.namespace=production + # ... + ``` + +### `namespaces` + _Optional, Default=""_ The `namespaces` option defines the namespaces in which the nomad services will be discovered. diff --git a/docs/content/providers/overview.md b/docs/content/providers/overview.md index de0af45fe32e2bead22bfb2d10023410ad53ecd1..fbb1335895846538d73091b8c21fcfa9a9d9b261 100644 --- a/docs/content/providers/overview.md +++ b/docs/content/providers/overview.md @@ -82,7 +82,7 @@ For the list of the providers names, see the [supported providers](#supported-pr ``` ```yaml tab="Kubernetes Ingress Route" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutestripprefix @@ -104,7 +104,7 @@ For the list of the providers names, see the [supported providers](#supported-pr ``` ```yaml tab="Kubernetes Ingress" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: stripprefix @@ -141,8 +141,6 @@ Below is the list of the currently supported providers in Traefik. | [Consul Catalog](./consul-catalog.md) | Orchestrator | Label | `consulcatalog` | | [Nomad](./nomad.md) | Orchestrator | Label | `nomad` | | [ECS](./ecs.md) | Orchestrator | Label | `ecs` | -| [Marathon](./marathon.md) | Orchestrator | Label | `marathon` | -| [Rancher](./rancher.md) | Orchestrator | Label | `rancher` | | [File](./file.md) | Manual | YAML/TOML format | `file` | | [Consul](./consul.md) | KV | KV | `consul` | | [Etcd](./etcd.md) | KV | KV | `etcd` | @@ -216,8 +214,6 @@ List of providers that support these features: - [ECS](./ecs.md#exposedbydefault) - [Consul Catalog](./consul-catalog.md#exposedbydefault) - [Nomad](./nomad.md#exposedbydefault) -- [Rancher](./rancher.md#exposedbydefault) -- [Marathon](./marathon.md#exposedbydefault) ### Constraints @@ -227,8 +223,6 @@ List of providers that support constraints: - [ECS](./ecs.md#constraints) - [Consul Catalog](./consul-catalog.md#constraints) - [Nomad](./nomad.md#constraints) -- [Rancher](./rancher.md#constraints) -- [Marathon](./marathon.md#constraints) - [Kubernetes CRD](./kubernetes-crd.md#labelselector) - [Kubernetes Ingress](./kubernetes-ingress.md#labelselector) - [Kubernetes Gateway](./kubernetes-gateway.md#labelselector) diff --git a/docs/content/providers/rancher.md b/docs/content/providers/rancher.md deleted file mode 100644 index b709a53291556d73710b008a31fb1bbf29d32b97..0000000000000000000000000000000000000000 --- a/docs/content/providers/rancher.md +++ /dev/null @@ -1,286 +0,0 @@ ---- -title: ""Traefik Configuration Discovery: Rancher"" -description: "Read the official Traefik documentation to learn how to expose Rancher services by default in Traefik Proxy." ---- - -# Traefik & Rancher - -A Story of Labels, Services & Containers -{: .subtitle } - - - -Attach labels to your services and let Traefik do the rest! - -!!! important "This provider is specific to Rancher 1.x." - - Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query. - As such, Rancher 2.x users should utilize the [Kubernetes CRD provider](./kubernetes-crd.md) directly. - -## Configuration Examples - -??? example "Configuring Rancher & Deploying / Exposing Services" - - Enabling the Rancher provider - - ```yaml tab="File (YAML)" - providers: - rancher: {} - ``` - - ```toml tab="File (TOML)" - [providers.rancher] - ``` - - ```bash tab="CLI" - --providers.rancher=true - ``` - - Attaching labels to services - - ```yaml - labels: - - traefik.http.services.my-service.rule=Host(`example.com`) - ``` - -## Routing Configuration - -See the dedicated section in [routing](../routing/providers/rancher.md). - -## Provider Configuration - -??? tip "Browse the Reference" - - For an overview of all the options that can be set with the Rancher provider, see the following snippets: - - ```yaml tab="File (YAML)" - --8<-- "content/providers/rancher.yml" - ``` - - ```toml tab="File (TOML)" - --8<-- "content/providers/rancher.toml" - ``` - - ```bash tab="CLI" - --8<-- "content/providers/rancher.txt" - ``` - -### `exposedByDefault` - -_Optional, Default=true_ - -Expose Rancher services by default in Traefik. -If set to `false`, services that do not have a `traefik.enable=true` label are ignored from the resulting routing configuration. - -For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). - -```yaml tab="File (YAML)" -providers: - rancher: - exposedByDefault: false - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - exposedByDefault = false - # ... -``` - -```bash tab="CLI" ---providers.rancher.exposedByDefault=false -# ... -``` - -### `defaultRule` - -_Optional, Default=```Host(`{{ normalize .Name }}`)```_ - -The default host rule for all services. - -The `defaultRule` option defines what routing rule to apply to a container if no rule is defined by a label. - -It must be a valid [Go template](https://pkg.go.dev/text/template/), and can use -[sprig template functions](https://masterminds.github.io/sprig/). -The service name can be accessed with the `Name` identifier, -and the template has access to all the labels defined on this container. - -This option can be overridden on a container basis with the `traefik.http.routers.Router1.rule` label. - -```yaml tab="File (YAML)" -providers: - rancher: - defaultRule: "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - defaultRule = "Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`)" - # ... -``` - -```bash tab="CLI" ---providers.rancher.defaultRule=Host(`{{ .Name }}.{{ index .Labels \"customLabel\"}}`) -# ... -``` - -### `enableServiceHealthFilter` - -_Optional, Default=true_ - -Filter out services with unhealthy states and inactive states. - -```yaml tab="File (YAML)" -providers: - rancher: - enableServiceHealthFilter: false - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - enableServiceHealthFilter = false - # ... -``` - -```bash tab="CLI" ---providers.rancher.enableServiceHealthFilter=false -# ... -``` - -### `refreshSeconds` - -_Optional, Default=15_ - -Defines the polling interval (in seconds). - -```yaml tab="File (YAML)" -providers: - rancher: - refreshSeconds: 30 - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - refreshSeconds = 30 - # ... -``` - -```bash tab="CLI" ---providers.rancher.refreshSeconds=30 -# ... -``` - -### `intervalPoll` - -_Optional, Default=false_ - -Poll the Rancher metadata service for changes every `rancher.refreshSeconds`, -which is less accurate than the default long polling technique which provides near instantaneous updates to Traefik. - -```yaml tab="File (YAML)" -providers: - rancher: - intervalPoll: true - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - intervalPoll = true - # ... -``` - -```bash tab="CLI" ---providers.rancher.intervalPoll=true -# ... -``` - -### `prefix` - -_Optional, Default="/latest"_ - -Prefix used for accessing the Rancher metadata service. - -```yaml tab="File (YAML)" -providers: - rancher: - prefix: "/test" - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - prefix = "/test" - # ... -``` - -```bash tab="CLI" ---providers.rancher.prefix=/test -# ... -``` - -### `constraints` - -_Optional, Default=""_ - -The `constraints` option can be set to an expression that Traefik matches against the container labels to determine whether -to create any route for that container. If none of the container tags match the expression, no route for that container is -created. If the expression is empty, all detected containers are included. - -The expression syntax is based on the `Label("key", "value")`, and `LabelRegex("key", "value")` functions, as well as -the usual boolean logic, as shown in examples below. - -??? example "Constraints Expression Examples" - - ```toml - # Includes only containers having a label with key `a.label.name` and value `foo` - constraints = "Label(`a.label.name`, `foo`)" - ``` - - ```toml - # Excludes containers having any label with key `a.label.name` and value `foo` - constraints = "!Label(`a.label.name`, `value`)" - ``` - - ```toml - # With logical AND. - constraints = "Label(`a.label.name`, `valueA`) && Label(`another.label.name`, `valueB`)" - ``` - - ```toml - # With logical OR. - constraints = "Label(`a.label.name`, `valueA`) || Label(`another.label.name`, `valueB`)" - ``` - - ```toml - # With logical AND and OR, with precedence set by parentheses. - constraints = "Label(`a.label.name`, `valueA`) && (Label(`another.label.name`, `valueB`) || Label(`yet.another.label.name`, `valueC`))" - ``` - - ```toml - # Includes only containers having a label with key `a.label.name` and a value matching the `a.+` regular expression. - constraints = "LabelRegex(`a.label.name`, `a.+`)" - ``` - -For additional information, refer to [Restrict the Scope of Service Discovery](./overview.md#restrict-the-scope-of-service-discovery). - -```yaml tab="File (YAML)" -providers: - rancher: - constraints: "Label(`a.label.name`,`foo`)" - # ... -``` - -```toml tab="File (TOML)" -[providers.rancher] - constraints = "Label(`a.label.name`,`foo`)" - # ... -``` - -```bash tab="CLI" ---providers.rancher.constraints=Label(`a.label.name`,`foo`) -# ... -``` diff --git a/docs/content/providers/rancher.toml b/docs/content/providers/rancher.toml deleted file mode 100644 index e809d737dec33f18e57c134749af5b27debbd0a6..0000000000000000000000000000000000000000 --- a/docs/content/providers/rancher.toml +++ /dev/null @@ -1,20 +0,0 @@ -# Enable Rancher Provider. -[providers.rancher] - - # Expose Rancher services by default in Traefik. - exposedByDefault = true - - # Enable watch Rancher changes. - watch = true - - # Filter services with unhealthy states and inactive states. - enableServiceHealthFilter = true - - # Defines the polling interval (in seconds). - refreshSeconds = 15 - - # Poll the Rancher metadata service for changes every `rancher.refreshSeconds`, which is less accurate - intervalPoll = false - - # Prefix used for accessing the Rancher metadata service - prefix = "/latest" diff --git a/docs/content/providers/rancher.txt b/docs/content/providers/rancher.txt deleted file mode 100644 index 158826cda047d15fe612273f428888606c2fe166..0000000000000000000000000000000000000000 --- a/docs/content/providers/rancher.txt +++ /dev/null @@ -1,20 +0,0 @@ -# Enable Rancher Provider. ---providers.rancher=true - -# Expose Rancher services by default in Traefik. ---providers.rancher.exposedByDefault=true - -# Enable watch Rancher changes. ---providers.rancher.watch=true - -# Filter services with unhealthy states and inactive states. ---providers.rancher.enableServiceHealthFilter=true - -# Defines the polling interval (in seconds). ---providers.rancher.refreshSeconds=15 - -# Poll the Rancher metadata service for changes every `rancher.refreshSeconds`, which is less accurate ---providers.rancher.intervalPoll=false - -# Prefix used for accessing the Rancher metadata service ---providers.rancher.prefix=/latest diff --git a/docs/content/providers/rancher.yml b/docs/content/providers/rancher.yml deleted file mode 100644 index 227b352c3240f1ae59294bd381ec45bfe7e3b9ec..0000000000000000000000000000000000000000 --- a/docs/content/providers/rancher.yml +++ /dev/null @@ -1,21 +0,0 @@ -# Enable Rancher Provider. -providers: - rancher: - - # Expose Rancher services by default in Traefik. - exposedByDefault: true - - # Enable watch Rancher changes. - watch: true - - # Filter services with unhealthy states and inactive states. - enableServiceHealthFilter: true - - # Defines the polling interval (in seconds). - refreshSeconds: 15 - - # Poll the Rancher metadata service for changes every `rancher.refreshSeconds`, which is less accurate - intervalPoll: false - - # Prefix used for accessing the Rancher metadata service - prefix: /latest diff --git a/docs/content/reference/dynamic-configuration/docker-labels.yml b/docs/content/reference/dynamic-configuration/docker-labels.yml index e58a1d46a0dd4f147938897be71178e000154d26..fb497fe41ae2e9405241719ccd80eafac6bd3d12 100644 --- a/docs/content/reference/dynamic-configuration/docker-labels.yml +++ b/docs/content/reference/dynamic-configuration/docker-labels.yml @@ -190,8 +190,9 @@ - "traefik.tcp.routers.tcprouter1.tls.options=foobar" - "traefik.tcp.routers.tcprouter1.tls.passthrough=true" - "traefik.tcp.services.tcpservice01.loadbalancer.proxyprotocol.version=42" -- "traefik.tcp.services.tcpservice01.loadbalancer.terminationdelay=42" - "traefik.tcp.services.tcpservice01.loadbalancer.server.port=foobar" +- "traefik.tcp.services.tcpservice01.loadbalancer.server.tls=true" +- "traefik.tcp.services.tcpservice01.loadbalancer.serverstransport=foobar" - "traefik.udp.routers.udprouter0.entrypoints=foobar, foobar" - "traefik.udp.routers.udprouter0.service=foobar" - "traefik.udp.routers.udprouter1.entrypoints=foobar, foobar" diff --git a/docs/content/reference/dynamic-configuration/file.toml b/docs/content/reference/dynamic-configuration/file.toml index 41994814d695900b4f974daa3810dcb9cbc79c28..2e72be2aa917f095e7d0061206e3368a045cacac 100644 --- a/docs/content/reference/dynamic-configuration/file.toml +++ b/docs/content/reference/dynamic-configuration/file.toml @@ -377,15 +377,17 @@ [tcp.services] [tcp.services.TCPService01] [tcp.services.TCPService01.loadBalancer] - terminationDelay = 42 + serversTransport = "foobar" [tcp.services.TCPService01.loadBalancer.proxyProtocol] version = 42 [[tcp.services.TCPService01.loadBalancer.servers]] address = "foobar" + tls = true [[tcp.services.TCPService01.loadBalancer.servers]] address = "foobar" + tls = true [tcp.services.TCPService02] [tcp.services.TCPService02.weighted] @@ -396,6 +398,7 @@ [[tcp.services.TCPService02.weighted.services]] name = "foobar" weight = 42 + [tcp.middlewares] [tcp.middlewares.TCPMiddleware00] [tcp.middlewares.TCPMiddleware00.ipAllowList] @@ -404,6 +407,53 @@ [tcp.middlewares.TCPMiddleware01.inFlightConn] amount = 42 + [tcp.serversTransports] + [tcp.serversTransports.TCPServersTransport0] + dialTimeout = "42s" + dialKeepAlive = "42s" + terminationDelay = "42s" + + [tcp.serversTransports.TCPServersTransport0.tls] + serverName = "foobar" + insecureSkipVerify = true + rootCAs = ["foobar", "foobar"] + peerCertURI = "foobar" + + [[tcp.serversTransports.TCPServersTransport0.tls.certificates]] + certFile = "foobar" + keyFile = "foobar" + + [[tcp.serversTransports.TCPServersTransport0.tls.certificates]] + certFile = "foobar" + keyFile = "foobar" + + [tcp.serversTransports.TCPServersTransport0.spiffe] + ids = ["foobar", "foobar"] + trustDomain = "foobar" + + [tcp.serversTransports.TCPServersTransport1] + dialTimeout = "42s" + dialKeepAlive = "42s" + terminationDelay = "42s" + + [tcp.serversTransports.TCPServersTransport1.tls] + serverName = "foobar" + insecureSkipVerify = true + rootCAs = ["foobar", "foobar"] + peerCertURI = "foobar" + + [[tcp.serversTransports.TCPServersTransport1.tls.certificates]] + certFile = "foobar" + keyFile = "foobar" + + [[tcp.serversTransports.TCPServersTransport1.tls.certificates]] + certFile = "foobar" + keyFile = "foobar" + + [tcp.serversTransports.TCPServersTransport1.spiffe] + ids = ["foobar", "foobar"] + trustDomain = "foobar" + [udp] [udp.routers] [udp.routers.UDPRouter0] diff --git a/docs/content/reference/dynamic-configuration/file.yaml b/docs/content/reference/dynamic-configuration/file.yaml index bfecd9fd281c66ac6373090098e08c2a58cf2663..e760e19eca0e91663e567e5e71bd2e5c0bc48cff 100644 --- a/docs/content/reference/dynamic-configuration/file.yaml +++ b/docs/content/reference/dynamic-configuration/file.yaml @@ -426,12 +426,14 @@ tcp: services: TCPService01: loadBalancer: - terminationDelay: 42 + serversTransport: foobar proxyProtocol: version: 42 servers: - address: foobar + tls: true - address: foobar + tls: true TCPService02: weighted: services: @@ -448,6 +450,49 @@ tcp: TCPMiddleware01: inFlightConn: amount: 42 + serversTransports: + TCPServersTransport0: + dialTimeout: 42s + dialKeepAlive: 42s + terminationDelay: 42s + tls: + serverName: foobar + insecureSkipVerify: true + rootCAs: + - foobar + - foobar + certificates: + - certFile: foobar + keyFile: foobar + - certFile: foobar + keyFile: foobar + peerCertURI: foobar + spiffe: + ids: + - foobar + - foobar + trustDomain: foobar + TCPServersTransport1: + dialTimeout: 42s + dialKeepAlive: 42s + terminationDelay: 42s + tls: + serverName: foobar + insecureSkipVerify: true + rootCAs: + - foobar + - foobar + certificates: + - certFile: foobar + keyFile: foobar + - certFile: foobar + keyFile: foobar + peerCertURI: foobar + spiffe: + ids: + - foobar + - foobar + trustDomain: foobar udp: routers: UDPRouter0: diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml index 4a7f19a662c199de5184d0b942fab96b3f6e50bb..37849dedc6f7291d86569326348804565a13bfb6 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: ingressroutes.traefik.containo.us + name: ingressroutes.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: IngressRoute listKind: IngressRouteList @@ -104,6 +104,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs + or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes @@ -274,9 +281,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: ingressroutetcps.traefik.containo.us + name: ingressroutetcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: IngressRouteTCP listKind: IngressRouteTCPList @@ -357,6 +364,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs + or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean port: anyOf: - type: integer @@ -373,15 +387,16 @@ spec: to use. type: integer type: object - terminationDelay: - description: TerminationDelay defines the deadline that - the proxy sets, after one of its connected peers indicates - it has closed the writing capability of its connection, - to close the reading capability as well, hence fully - terminating the connection. It is a duration in milliseconds, - defaulting to 100. A negative value means an infinite - deadline (i.e. the reading capability is never closed). - type: integer + serversTransport: + description: ServersTransport defines the name of ServersTransportTCP + resource to use. It allows to configure the transport + between Traefik and your servers. Can only be used on + a Kubernetes Service. + type: string + tls: + description: TLS determines whether to use TLS when dialing + with the backend. + type: boolean weight: description: Weight defines the weight used when balancing requests between multiple Kubernetes Service. @@ -485,9 +500,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: ingressrouteudps.traefik.containo.us + name: ingressrouteudps.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: IngressRouteUDP listKind: IngressRouteUDPList @@ -542,6 +557,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs + or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean port: anyOf: - type: integer @@ -583,9 +605,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: middlewares.traefik.containo.us + name: middlewares.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: Middleware listKind: MiddlewareList @@ -818,6 +840,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if + the only child is the Kubernetes Service clusterIP. The + Kubernetes Service itself does load-balance to the pods. + By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. @@ -1478,9 +1507,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: middlewaretcps.traefik.containo.us + name: middlewaretcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: MiddlewareTCP listKind: MiddlewareTCPList @@ -1550,9 +1579,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: serverstransports.traefik.containo.us + name: serverstransports.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: ServersTransport listKind: ServersTransportList @@ -1691,9 +1720,131 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: tlsoptions.traefik.containo.us + name: serverstransporttcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io + names: + kind: ServersTransportTCP + listKind: ServersTransportTCPList + plural: serverstransporttcps + singular: serverstransporttcp + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: 'ServersTransportTCP is the CRD implementation of a TCPServersTransport. + If no tcpServersTransport is specified, a default one named default@internal + will be used. The default@internal tcpServersTransport can be configured + in the static configuration. More info: https://doc.traefik.io/traefik/v3.0/routing/services/#serverstransport_3' + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ServersTransportTCPSpec defines the desired state of a ServersTransportTCP. + properties: + dialKeepAlive: + anyOf: + - type: integer + - type: string + description: DialKeepAlive is the interval between keep-alive probes + for an active network connection. If zero, keep-alive probes are + sent with a default value (currently 15 seconds), if supported by + the protocol and operating system. Network protocols or operating + systems that do not support keep-alives ignore this field. If negative, + keep-alive probes are disabled. + x-kubernetes-int-or-string: true + dialTimeout: + anyOf: + - type: integer + - type: string + description: DialTimeout is the amount of time to wait until a connection + to a backend server can be established. + x-kubernetes-int-or-string: true + terminationDelay: + anyOf: + - type: integer + - type: string + description: TerminationDelay defines the delay to wait before fully + terminating the connection, after one connected peer has closed + its writing capability. + x-kubernetes-int-or-string: true + tls: + description: TLS defines the TLS configuration + properties: + certificatesSecrets: + description: CertificatesSecrets defines a list of secret storing + client certificates for mTLS. + items: + type: string + type: array + insecureSkipVerify: + description: InsecureSkipVerify disables TLS certificate verification. + type: boolean + peerCertURI: + description: MaxIdleConnsPerHost controls the maximum idle (keep-alive) + to keep per-host. PeerCertURI defines the peer cert URI used + to match against SAN URI during the peer certificate verification. + type: string + rootCAsSecrets: + description: RootCAsSecrets defines a list of CA secret used to + validate self-signed certificates. + items: + type: string + type: array + serverName: + description: ServerName defines the server name used to contact + the server. + type: string + spiffe: + description: Spiffe defines the SPIFFE configuration. + properties: + ids: + description: IDs defines the allowed SPIFFE IDs (takes precedence + over the SPIFFE TrustDomain). + items: + type: string + type: array + trustDomain: + description: TrustDomain defines the allowed SPIFFE trust + domain. + type: string + type: object + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: tlsoptions.traefik.io +spec: + group: traefik.io names: kind: TLSOption listKind: TLSOptionList @@ -1798,9 +1949,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: tlsstores.traefik.containo.us + name: tlsstores.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: TLSStore listKind: TLSStoreList @@ -1897,9 +2048,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: traefikservices.traefik.containo.us + name: traefikservices.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: TraefikService listKind: TraefikServiceList @@ -1966,6 +2117,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or + if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. @@ -2057,6 +2215,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if the + only child is the Kubernetes Service clusterIP. The Kubernetes + Service itself does load-balance to the pods. By default, NativeLB + is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. By default, @@ -2154,6 +2319,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or + if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1beta1.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1beta1.yml index 8319e66aab4fa91fd0b5eda14fa76c2e2306f596..4fb320d42946f779fc74d4fa744f9a138457e045 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1beta1.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1beta1.yml @@ -1,10 +1,10 @@ apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: ingressroutes.traefik.containo.us + name: ingressroutes.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: IngressRoute @@ -16,10 +16,10 @@ spec: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: middlewares.traefik.containo.us + name: middlewares.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: Middleware @@ -31,10 +31,10 @@ spec: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: middlewaretcps.traefik.containo.us + name: middlewaretcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: MiddlewareTCP @@ -46,10 +46,10 @@ spec: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: ingressroutetcps.traefik.containo.us + name: ingressroutetcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: IngressRouteTCP @@ -61,10 +61,10 @@ spec: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: ingressrouteudps.traefik.containo.us + name: ingressrouteudps.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: IngressRouteUDP @@ -76,10 +76,10 @@ spec: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: tlsoptions.traefik.containo.us + name: tlsoptions.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: TLSOption @@ -91,10 +91,10 @@ spec: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: tlsstores.traefik.containo.us + name: tlsstores.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: TLSStore @@ -106,10 +106,10 @@ spec: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: traefikservices.traefik.containo.us + name: traefikservices.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: TraefikService @@ -121,10 +121,10 @@ spec: apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: - name: serverstransports.traefik.containo.us + name: serverstransports.traefik.io spec: - group: traefik.containo.us + group: traefik.io version: v1alpha1 names: kind: ServersTransport diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml index 6237031f0b26789be3189d15dff545410cfc6e8d..301ec516620133a95c7d300e8fcb76b5c9f6cef0 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml @@ -32,7 +32,7 @@ rules: verbs: - update - apiGroups: - - traefik.containo.us + - traefik.io resources: - middlewares - middlewaretcps @@ -43,6 +43,7 @@ rules: - tlsoptions - tlsstores - serverstransports + - serverstransporttcps verbs: - get - list diff --git a/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml b/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml index abe361b9a2ea3f6f6bacc997701dd1dde321be67..93f1a95ff6a69b8d151469aefc464ed307d8e4b2 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-crd-resource.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr2 @@ -17,7 +17,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 @@ -34,7 +34,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror1 @@ -53,7 +53,7 @@ spec: percent: 20 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror2 @@ -73,7 +73,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroute @@ -133,7 +133,7 @@ spec: namespace: default --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: ingressroutetcp.crd @@ -147,6 +147,7 @@ spec: services: - name: whoamitcp port: 8080 + serversTransport: mytransporttcp middlewares: - name: ipallowlist tls: @@ -157,7 +158,7 @@ spec: namespace: default --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: ingressrouteudp.crd @@ -172,7 +173,7 @@ spec: port: 8080 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: tlsoption @@ -198,7 +199,7 @@ spec: - foobar --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport @@ -213,9 +214,30 @@ spec: certificatesSecrets: - foobar - foobar + peerCertURI: foobar maxIdleConnsPerHost: 1 forwardingTimeouts: dialTimeout: 42s responseHeaderTimeout: 42s idleConnTimeout: 42s disableHTTP2: true + +--- +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransporttcp + namespace: default + +spec: + serverName: foobar + insecureSkipVerify: true + rootCAsSecrets: + - foobar + - foobar + certificatesSecrets: + - foobar + - foobar + peerCertURI: foobar + dialTimeout: 42s + dialKeepAlive: 42s diff --git a/docs/content/reference/dynamic-configuration/kubernetes-gateway-resource.yml b/docs/content/reference/dynamic-configuration/kubernetes-gateway-resource.yml index 55c394456ad2ee59b11ed51fa6858bb18fbae654..a22858a69b018ec8b8421cdd7b77b2ab2e2acf92 100644 --- a/docs/content/reference/dynamic-configuration/kubernetes-gateway-resource.yml +++ b/docs/content/reference/dynamic-configuration/kubernetes-gateway-resource.yml @@ -74,7 +74,7 @@ spec: value: /foo backendRefs: - - group: traefik.containo.us + - group: traefik.io kind: TraefikService name: myservice@file weight: 1 diff --git a/docs/content/reference/dynamic-configuration/kv-ref.md b/docs/content/reference/dynamic-configuration/kv-ref.md index ca40ac8a485986e5c00f00701ba69a47d45da1f3..ce15fb1f27de9720b02969066127e1ce3f7d8e46 100644 --- a/docs/content/reference/dynamic-configuration/kv-ref.md +++ b/docs/content/reference/dynamic-configuration/kv-ref.md @@ -278,10 +278,42 @@ | `traefik/tcp/routers/TCPRouter1/tls/domains/1/sans/1` | `foobar` | | `traefik/tcp/routers/TCPRouter1/tls/options` | `foobar` | | `traefik/tcp/routers/TCPRouter1/tls/passthrough` | `true` | +| `traefik/tcp/serversTransports/TCPServersTransport0/dialKeepAlive` | `42s` | +| `traefik/tcp/serversTransports/TCPServersTransport0/dialTimeout` | `42s` | +| `traefik/tcp/serversTransports/TCPServersTransport0/spiffe/ids/0` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport0/spiffe/ids/1` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport0/spiffe/trustDomain` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport0/terminationDelay` | `42s` | +| `traefik/tcp/serversTransports/TCPServersTransport0/tls/certificates/0/certFile` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport0/tls/certificates/0/keyFile` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport0/tls/certificates/1/certFile` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport0/tls/certificates/1/keyFile` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport0/tls/insecureSkipVerify` | `true` | +| `traefik/tcp/serversTransports/TCPServersTransport0/tls/peerCertURI` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport0/tls/rootCAs/0` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport0/tls/rootCAs/1` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport0/tls/serverName` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/dialKeepAlive` | `42s` | +| `traefik/tcp/serversTransports/TCPServersTransport1/dialTimeout` | `42s` | +| `traefik/tcp/serversTransports/TCPServersTransport1/spiffe/ids/0` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/spiffe/ids/1` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/spiffe/trustDomain` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/terminationDelay` | `42s` | +| `traefik/tcp/serversTransports/TCPServersTransport1/tls/certificates/0/certFile` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/tls/certificates/0/keyFile` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/tls/certificates/1/certFile` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/tls/certificates/1/keyFile` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/tls/insecureSkipVerify` | `true` | +| `traefik/tcp/serversTransports/TCPServersTransport1/tls/peerCertURI` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/tls/rootCAs/0` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/tls/rootCAs/1` | `foobar` | +| `traefik/tcp/serversTransports/TCPServersTransport1/tls/serverName` | `foobar` | | `traefik/tcp/services/TCPService01/loadBalancer/proxyProtocol/version` | `42` | | `traefik/tcp/services/TCPService01/loadBalancer/servers/0/address` | `foobar` | +| `traefik/tcp/services/TCPService01/loadBalancer/servers/0/tls` | `true` | | `traefik/tcp/services/TCPService01/loadBalancer/servers/1/address` | `foobar` | -| `traefik/tcp/services/TCPService01/loadBalancer/terminationDelay` | `42` | +| `traefik/tcp/services/TCPService01/loadBalancer/servers/1/tls` | `true` | +| `traefik/tcp/services/TCPService01/loadBalancer/serversTransport` | `foobar` | | `traefik/tcp/services/TCPService02/weighted/services/0/name` | `foobar` | | `traefik/tcp/services/TCPService02/weighted/services/0/weight` | `42` | | `traefik/tcp/services/TCPService02/weighted/services/1/name` | `foobar` | diff --git a/docs/content/reference/dynamic-configuration/marathon-labels.json b/docs/content/reference/dynamic-configuration/marathon-labels.json deleted file mode 100644 index 99cfaefb976ac9aa9e4949c00db2ae42a9a5de06..0000000000000000000000000000000000000000 --- a/docs/content/reference/dynamic-configuration/marathon-labels.json +++ /dev/null @@ -1,209 +0,0 @@ -"traefik.http.middlewares.middleware00.addprefix.prefix": "foobar", -"traefik.http.middlewares.middleware01.basicauth.headerfield": "foobar", -"traefik.http.middlewares.middleware01.basicauth.realm": "foobar", -"traefik.http.middlewares.middleware01.basicauth.removeheader": "true", -"traefik.http.middlewares.middleware01.basicauth.users": "foobar, foobar", -"traefik.http.middlewares.middleware01.basicauth.usersfile": "foobar", -"traefik.http.middlewares.middleware02.buffering.maxrequestbodybytes": "42", -"traefik.http.middlewares.middleware02.buffering.maxresponsebodybytes": "42", -"traefik.http.middlewares.middleware02.buffering.memrequestbodybytes": "42", -"traefik.http.middlewares.middleware02.buffering.memresponsebodybytes": "42", -"traefik.http.middlewares.middleware02.buffering.retryexpression": "foobar", -"traefik.http.middlewares.middleware03.chain.middlewares": "foobar, foobar", -"traefik.http.middlewares.middleware04.circuitbreaker.expression": "foobar", -"traefik.http.middlewares.middleware04.circuitbreaker.checkperiod": "42s", -"traefik.http.middlewares.middleware04.circuitbreaker.fallbackduration": "42s", -"traefik.http.middlewares.middleware04.circuitbreaker.recoveryduration": "42s", -"traefik.http.middlewares.middleware05.compress": "true", -"traefik.http.middlewares.middleware05.compress.excludedcontenttypes": "foobar, foobar", -"traefik.http.middlewares.middleware05.compress.minresponsebodybytes": "42", -"traefik.http.middlewares.middleware06.contenttype": "true", -"traefik.http.middlewares.middleware07.digestauth.headerfield": "foobar", -"traefik.http.middlewares.middleware07.digestauth.realm": "foobar", -"traefik.http.middlewares.middleware07.digestauth.removeheader": "true", -"traefik.http.middlewares.middleware07.digestauth.users": "foobar, foobar", -"traefik.http.middlewares.middleware07.digestauth.usersfile": "foobar", -"traefik.http.middlewares.middleware08.errors.query": "foobar", -"traefik.http.middlewares.middleware08.errors.service": "foobar", -"traefik.http.middlewares.middleware08.errors.status": "foobar, foobar", -"traefik.http.middlewares.middleware09.forwardauth.address": "foobar", -"traefik.http.middlewares.middleware09.forwardauth.authrequestheaders": "foobar, foobar", -"traefik.http.middlewares.middleware09.forwardauth.authresponseheaders": "foobar, foobar", -"traefik.http.middlewares.middleware09.forwardauth.authresponseheadersregex": "foobar", -"traefik.http.middlewares.middleware09.forwardauth.tls.ca": "foobar", -"traefik.http.middlewares.middleware09.forwardauth.tls.cert": "foobar", -"traefik.http.middlewares.middleware09.forwardauth.tls.insecureskipverify": "true", -"traefik.http.middlewares.middleware09.forwardauth.tls.key": "foobar", -"traefik.http.middlewares.middleware09.forwardauth.trustforwardheader": "true", -"traefik.http.middlewares.middleware10.headers.accesscontrolallowcredentials": "true", -"traefik.http.middlewares.middleware10.headers.accesscontrolallowheaders": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.accesscontrolallowmethods": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.accesscontrolalloworiginlist": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.accesscontrolalloworiginlistregex": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.accesscontrolexposeheaders": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.accesscontrolmaxage": "42", -"traefik.http.middlewares.middleware10.headers.addvaryheader": "true", -"traefik.http.middlewares.middleware10.headers.allowedhosts": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.browserxssfilter": "true", -"traefik.http.middlewares.middleware10.headers.contentsecuritypolicy": "foobar", -"traefik.http.middlewares.middleware10.headers.contenttypenosniff": "true", -"traefik.http.middlewares.middleware10.headers.custombrowserxssvalue": "foobar", -"traefik.http.middlewares.middleware10.headers.customframeoptionsvalue": "foobar", -"traefik.http.middlewares.middleware10.headers.customrequestheaders.name0": "foobar", -"traefik.http.middlewares.middleware10.headers.customrequestheaders.name1": "foobar", -"traefik.http.middlewares.middleware10.headers.customresponseheaders.name0": "foobar", -"traefik.http.middlewares.middleware10.headers.customresponseheaders.name1": "foobar", -"traefik.http.middlewares.middleware10.headers.forcestsheader": "true", -"traefik.http.middlewares.middleware10.headers.framedeny": "true", -"traefik.http.middlewares.middleware10.headers.hostsproxyheaders": "foobar, foobar", -"traefik.http.middlewares.middleware10.headers.isdevelopment": "true", -"traefik.http.middlewares.middleware10.headers.permissionspolicy": "foobar", -"traefik.http.middlewares.middleware10.headers.publickey": "foobar", -"traefik.http.middlewares.middleware10.headers.referrerpolicy": "foobar", -"traefik.http.middlewares.middleware10.headers.sslproxyheaders.name0": "foobar", -"traefik.http.middlewares.middleware10.headers.sslproxyheaders.name1": "foobar", -"traefik.http.middlewares.middleware10.headers.stsincludesubdomains": "true", -"traefik.http.middlewares.middleware10.headers.stspreload": "true", -"traefik.http.middlewares.middleware10.headers.stsseconds": "42", -"traefik.http.middlewares.middleware11.ipallowlist.ipstrategy.depth": "42", -"traefik.http.middlewares.middleware11.ipallowlist.ipstrategy.excludedips": "foobar, foobar", -"traefik.http.middlewares.middleware11.ipallowlist.sourcerange": "foobar, foobar", -"traefik.http.middlewares.middleware12.inflightreq.amount": "42", -"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.depth": "42", -"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.ipstrategy.excludedips": "foobar, foobar", -"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requestheadername": "foobar", -"traefik.http.middlewares.middleware12.inflightreq.sourcecriterion.requesthost": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.commonname": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.country": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.domaincomponent": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.locality": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.organization": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.province": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.issuer.serialnumber": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.notafter": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.notbefore": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.sans": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.serialnumber": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.commonname": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.country": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.domaincomponent": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.locality": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.organization": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.organizationalunit": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.province": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.info.subject.serialnumber": "true", -"traefik.http.middlewares.middleware13.passtlsclientcert.pem": "true", -"traefik.http.middlewares.middleware14.plugin.foobar.foo": "bar", -"traefik.http.middlewares.middleware15.ratelimit.average": "42", -"traefik.http.middlewares.middleware15.ratelimit.burst": "42", -"traefik.http.middlewares.middleware15.ratelimit.period": "42", -"traefik.http.middlewares.middleware15.ratelimit.sourcecriterion.ipstrategy.depth": "42", -"traefik.http.middlewares.middleware15.ratelimit.sourcecriterion.ipstrategy.excludedips": "foobar, foobar", -"traefik.http.middlewares.middleware15.ratelimit.sourcecriterion.requestheadername": "foobar", -"traefik.http.middlewares.middleware15.ratelimit.sourcecriterion.requesthost": "true", -"traefik.http.middlewares.middleware16.redirectregex.permanent": "true", -"traefik.http.middlewares.middleware16.redirectregex.regex": "foobar", -"traefik.http.middlewares.middleware16.redirectregex.replacement": "foobar", -"traefik.http.middlewares.middleware17.redirectscheme.permanent": "true", -"traefik.http.middlewares.middleware17.redirectscheme.port": "foobar", -"traefik.http.middlewares.middleware17.redirectscheme.scheme": "foobar", -"traefik.http.middlewares.middleware18.replacepath.path": "foobar", -"traefik.http.middlewares.middleware19.replacepathregex.regex": "foobar", -"traefik.http.middlewares.middleware19.replacepathregex.replacement": "foobar", -"traefik.http.middlewares.middleware20.retry.attempts": "42", -"traefik.http.middlewares.middleware20.retry.initialinterval": "42", -"traefik.http.middlewares.middleware21.stripprefix.prefixes": "foobar, foobar", -"traefik.http.middlewares.middleware22.stripprefixregex.regex": "foobar, foobar", -"traefik.http.middlewares.middleware23.grpcweb.alloworigins": "foobar, foobar", -"traefik.http.routers.router0.entrypoints": "foobar, foobar", -"traefik.http.routers.router0.middlewares": "foobar, foobar", -"traefik.http.routers.router0.priority": "42", -"traefik.http.routers.router0.rule": "foobar", -"traefik.http.routers.router0.service": "foobar", -"traefik.http.routers.router0.tls": "true", -"traefik.http.routers.router0.tls.certresolver": "foobar", -"traefik.http.routers.router0.tls.domains[0].main": "foobar", -"traefik.http.routers.router0.tls.domains[0].sans": "foobar, foobar", -"traefik.http.routers.router0.tls.domains[1].main": "foobar", -"traefik.http.routers.router0.tls.domains[1].sans": "foobar, foobar", -"traefik.http.routers.router0.tls.options": "foobar", -"traefik.http.routers.router1.entrypoints": "foobar, foobar", -"traefik.http.routers.router1.middlewares": "foobar, foobar", -"traefik.http.routers.router1.priority": "42", -"traefik.http.routers.router1.rule": "foobar", -"traefik.http.routers.router1.service": "foobar", -"traefik.http.routers.router1.tls": "true", -"traefik.http.routers.router1.tls.certresolver": "foobar", -"traefik.http.routers.router1.tls.domains[0].main": "foobar", -"traefik.http.routers.router1.tls.domains[0].sans": "foobar, foobar", -"traefik.http.routers.router1.tls.domains[1].main": "foobar", -"traefik.http.routers.router1.tls.domains[1].sans": "foobar, foobar", -"traefik.http.routers.router1.tls.options": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.followredirects": "true", -"traefik.http.services.service01.loadbalancer.healthcheck.headers.name0": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.headers.name1": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.hostname": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.interval": "42s", -"traefik.http.services.service01.loadbalancer.healthcheck.path": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.method": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.status": "42", -"traefik.http.services.service01.loadbalancer.healthcheck.port": "42", -"traefik.http.services.service01.loadbalancer.healthcheck.scheme": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.mode": "foobar", -"traefik.http.services.service01.loadbalancer.healthcheck.timeout": "42s", -"traefik.http.services.service01.loadbalancer.passhostheader": "true", -"traefik.http.services.service01.loadbalancer.responseforwarding.flushinterval": "42s", -"traefik.http.services.service01.loadbalancer.serverstransport": "foobar", -"traefik.http.services.service01.loadbalancer.sticky.cookie": "true", -"traefik.http.services.service01.loadbalancer.sticky.cookie.httponly": "true", -"traefik.http.services.service01.loadbalancer.sticky.cookie.name": "foobar", -"traefik.http.services.service01.loadbalancer.sticky.cookie.samesite": "foobar", -"traefik.http.services.service01.loadbalancer.sticky.cookie.secure": "true", -"traefik.http.services.service01.loadbalancer.server.port": "foobar", -"traefik.http.services.service01.loadbalancer.server.scheme": "foobar", -"traefik.tcp.middlewares.tcpmiddleware00.ipallowlist.sourcerange": "foobar, foobar", -"traefik.tcp.middlewares.tcpmiddleware01.inflightconn.amount": "42", -"traefik.tcp.routers.tcprouter0.entrypoints": "foobar, foobar", -"traefik.tcp.routers.tcprouter0.middlewares": "foobar, foobar", -"traefik.tcp.routers.tcprouter0.rule": "foobar", -"traefik.tcp.routers.tcprouter0.priority": "42", -"traefik.tcp.routers.tcprouter0.service": "foobar", -"traefik.tcp.routers.tcprouter0.tls": "true", -"traefik.tcp.routers.tcprouter0.tls.certresolver": "foobar", -"traefik.tcp.routers.tcprouter0.tls.domains[0].main": "foobar", -"traefik.tcp.routers.tcprouter0.tls.domains[0].sans": "foobar, foobar", -"traefik.tcp.routers.tcprouter0.tls.domains[1].main": "foobar", -"traefik.tcp.routers.tcprouter0.tls.domains[1].sans": "foobar, foobar", -"traefik.tcp.routers.tcprouter0.tls.options": "foobar", -"traefik.tcp.routers.tcprouter0.tls.passthrough": "true", -"traefik.tcp.routers.tcprouter1.entrypoints": "foobar, foobar", -"traefik.tcp.routers.tcprouter1.middlewares": "foobar, foobar", -"traefik.tcp.routers.tcprouter1.rule": "foobar", -"traefik.tcp.routers.tcprouter1.priority": "42", -"traefik.tcp.routers.tcprouter1.service": "foobar", -"traefik.tcp.routers.tcprouter1.tls": "true", -"traefik.tcp.routers.tcprouter1.tls.certresolver": "foobar", -"traefik.tcp.routers.tcprouter1.tls.domains[0].main": "foobar", -"traefik.tcp.routers.tcprouter1.tls.domains[0].sans": "foobar, foobar", -"traefik.tcp.routers.tcprouter1.tls.domains[1].main": "foobar", -"traefik.tcp.routers.tcprouter1.tls.domains[1].sans": "foobar, foobar", -"traefik.tcp.routers.tcprouter1.tls.options": "foobar", -"traefik.tcp.routers.tcprouter1.tls.passthrough": "true", -"traefik.tcp.services.tcpservice01.loadbalancer.proxyprotocol.version": "42", -"traefik.tcp.services.tcpservice01.loadbalancer.terminationdelay": "42", -"traefik.tcp.services.tcpservice01.loadbalancer.server.port": "foobar", -"traefik.udp.routers.udprouter0.entrypoints": "foobar, foobar", -"traefik.udp.routers.udprouter0.service": "foobar", -"traefik.udp.routers.udprouter1.entrypoints": "foobar, foobar", -"traefik.udp.routers.udprouter1.service": "foobar", -"traefik.udp.services.udpservice01.loadbalancer.server.port": "foobar", -"traefik.tls.stores.Store0.defaultcertificate.certfile": "foobar", -"traefik.tls.stores.Store0.defaultcertificate.keyfile": "foobar", -"traefik.tls.stores.Store0.defaultgeneratedcert.domain.main": "foobar", -"traefik.tls.stores.Store0.defaultgeneratedcert.domain.sans": "foobar, foobar", -"traefik.tls.stores.Store0.defaultgeneratedcert.resolver": "foobar", -"traefik.tls.stores.Store1.defaultcertificate.certfile": "foobar", -"traefik.tls.stores.Store1.defaultcertificate.keyfile": "foobar", -"traefik.tls.stores.Store1.defaultgeneratedcert.domain.main": "foobar", -"traefik.tls.stores.Store1.defaultgeneratedcert.domain.sans": "foobar, foobar", -"traefik.tls.stores.Store1.defaultgeneratedcert.resolver": "foobar", diff --git a/docs/content/reference/dynamic-configuration/marathon.json b/docs/content/reference/dynamic-configuration/marathon.json deleted file mode 100644 index 131344a7e15a44a35bbaa4351c7f64643cc750a8..0000000000000000000000000000000000000000 --- a/docs/content/reference/dynamic-configuration/marathon.json +++ /dev/null @@ -1,2 +0,0 @@ -"traefik.enable": "true", -"traefik.marathon.ipaddressidx": "42", diff --git a/docs/content/reference/dynamic-configuration/marathon.md b/docs/content/reference/dynamic-configuration/marathon.md deleted file mode 100644 index 0e20679f82dc9ab5d320375eaa2b31c175401431..0000000000000000000000000000000000000000 --- a/docs/content/reference/dynamic-configuration/marathon.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: "Dynamic Configuration with Marathon Labels" -description: "Traefik Proxy can be configured to use Marathon as a provider. Read the technical documentation on the Traefik dynamic configuration with Marathon Labels." ---- - -# Marathon Configuration Reference - -Dynamic configuration with Marathon Labels -{: .subtitle } - -```json -"labels": { - --8<-- "content/reference/dynamic-configuration/marathon.json" - --8<-- "content/reference/dynamic-configuration/marathon-labels.json" -} -``` diff --git a/docs/content/reference/dynamic-configuration/rancher.md b/docs/content/reference/dynamic-configuration/rancher.md deleted file mode 100644 index c2762999db553dcc1a76f969c502282758714065..0000000000000000000000000000000000000000 --- a/docs/content/reference/dynamic-configuration/rancher.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: "Traefik Dynamic Configuration with Rancher" -description: "Read the official Traefik documentation to learn more on dynamic configuration in Traefik Proxy with Rancher Labels." ---- - -# Rancher Configuration Reference - -Dynamic configuration with Rancher Labels -{: .subtitle } - -The labels are case insensitive. - -```yaml -labels: - --8<-- "content/reference/dynamic-configuration/rancher.yml" - --8<-- "content/reference/dynamic-configuration/docker-labels.yml" -``` diff --git a/docs/content/reference/dynamic-configuration/rancher.yml b/docs/content/reference/dynamic-configuration/rancher.yml deleted file mode 100644 index 23efc00c61e4ffbd0576603ddb3470ec2e72969c..0000000000000000000000000000000000000000 --- a/docs/content/reference/dynamic-configuration/rancher.yml +++ /dev/null @@ -1 +0,0 @@ -- "traefik.enable=true" diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutes.yaml b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml similarity index 96% rename from docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutes.yaml rename to docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml index b6c0eff294fa6e1bbb2981fda046172247f2e2c7..8ea5b28c25f4d421a295601098c5153cea4c7c1a 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutes.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutes.yaml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: ingressroutes.traefik.containo.us + name: ingressroutes.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: IngressRoute listKind: IngressRouteList @@ -104,6 +104,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs + or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutetcps.yaml b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutetcps.yaml similarity index 88% rename from docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutetcps.yaml rename to docs/content/reference/dynamic-configuration/traefik.io_ingressroutetcps.yaml index a73fde9651ae59ae2a28f10607603b5e78b8a62b..7acb7cd5f83d232aa97610e3253abe2a141b31f8 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressroutetcps.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_ingressroutetcps.yaml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: ingressroutetcps.traefik.containo.us + name: ingressroutetcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: IngressRouteTCP listKind: IngressRouteTCPList @@ -89,6 +89,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs + or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean port: anyOf: - type: integer @@ -105,15 +112,16 @@ spec: to use. type: integer type: object - terminationDelay: - description: TerminationDelay defines the deadline that - the proxy sets, after one of its connected peers indicates - it has closed the writing capability of its connection, - to close the reading capability as well, hence fully - terminating the connection. It is a duration in milliseconds, - defaulting to 100. A negative value means an infinite - deadline (i.e. the reading capability is never closed). - type: integer + serversTransport: + description: ServersTransport defines the name of ServersTransportTCP + resource to use. It allows to configure the transport + between Traefik and your servers. Can only be used on + a Kubernetes Service. + type: string + tls: + description: TLS determines whether to use TLS when dialing + with the backend. + type: boolean weight: description: Weight defines the weight used when balancing requests between multiple Kubernetes Service. diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressrouteudps.yaml b/docs/content/reference/dynamic-configuration/traefik.io_ingressrouteudps.yaml similarity index 87% rename from docs/content/reference/dynamic-configuration/traefik.containo.us_ingressrouteudps.yaml rename to docs/content/reference/dynamic-configuration/traefik.io_ingressrouteudps.yaml index 50a7e62989846d6407a45fa6ee862261adc8bb92..59585a453830c8d1b9055ab14720d3027da3b1ab 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_ingressrouteudps.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_ingressrouteudps.yaml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: ingressrouteudps.traefik.containo.us + name: ingressrouteudps.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: IngressRouteUDP listKind: IngressRouteUDPList @@ -63,6 +63,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs + or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean port: anyOf: - type: integer diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml b/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml similarity index 98% rename from docs/content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml rename to docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml index 9994d3469a3c7921eafb78666f1ce7897454d937..67b9e0b5d891707ef92e4fd3d4d8c36d5a2f73e6 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewares.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_middlewares.yaml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: middlewares.traefik.containo.us + name: middlewares.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: Middleware listKind: MiddlewareList @@ -241,6 +241,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if + the only child is the Kubernetes Service clusterIP. The + Kubernetes Service itself does load-balance to the pods. + By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewaretcps.yaml b/docs/content/reference/dynamic-configuration/traefik.io_middlewaretcps.yaml similarity index 97% rename from docs/content/reference/dynamic-configuration/traefik.containo.us_middlewaretcps.yaml rename to docs/content/reference/dynamic-configuration/traefik.io_middlewaretcps.yaml index 071b49cf89e6ff6787ff2d3a883900cd25c182f3..ec5ee7e6829f3f50b39b1f5b58cf6154cbd58b9d 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_middlewaretcps.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_middlewaretcps.yaml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: middlewaretcps.traefik.containo.us + name: middlewaretcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: MiddlewareTCP listKind: MiddlewareTCPList diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_serverstransports.yaml b/docs/content/reference/dynamic-configuration/traefik.io_serverstransports.yaml similarity index 98% rename from docs/content/reference/dynamic-configuration/traefik.containo.us_serverstransports.yaml rename to docs/content/reference/dynamic-configuration/traefik.io_serverstransports.yaml index 362db4f49418b09d013c9c82192cc8575544c874..fff9f7006386c03a36270bfcd56d64ebdb762a5a 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_serverstransports.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_serverstransports.yaml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: serverstransports.traefik.containo.us + name: serverstransports.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: ServersTransport listKind: ServersTransportList diff --git a/docs/content/reference/dynamic-configuration/traefik.io_serverstransporttcps.yaml b/docs/content/reference/dynamic-configuration/traefik.io_serverstransporttcps.yaml new file mode 100644 index 0000000000000000000000000000000000000000..10e0a3f0e79ad756024b802daf08c86a46080a84 --- /dev/null +++ b/docs/content/reference/dynamic-configuration/traefik.io_serverstransporttcps.yaml @@ -0,0 +1,122 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: serverstransporttcps.traefik.io +spec: + group: traefik.io + names: + kind: ServersTransportTCP + listKind: ServersTransportTCPList + plural: serverstransporttcps + singular: serverstransporttcp + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: 'ServersTransportTCP is the CRD implementation of a TCPServersTransport. + If no tcpServersTransport is specified, a default one named default@internal + will be used. The default@internal tcpServersTransport can be configured + in the static configuration. More info: https://doc.traefik.io/traefik/v3.0/routing/services/#serverstransport_3' + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ServersTransportTCPSpec defines the desired state of a ServersTransportTCP. + properties: + dialKeepAlive: + anyOf: + - type: integer + - type: string + description: DialKeepAlive is the interval between keep-alive probes + for an active network connection. If zero, keep-alive probes are + sent with a default value (currently 15 seconds), if supported by + the protocol and operating system. Network protocols or operating + systems that do not support keep-alives ignore this field. If negative, + keep-alive probes are disabled. + x-kubernetes-int-or-string: true + dialTimeout: + anyOf: + - type: integer + - type: string + description: DialTimeout is the amount of time to wait until a connection + to a backend server can be established. + x-kubernetes-int-or-string: true + terminationDelay: + anyOf: + - type: integer + - type: string + description: TerminationDelay defines the delay to wait before fully + terminating the connection, after one connected peer has closed + its writing capability. + x-kubernetes-int-or-string: true + tls: + description: TLS defines the TLS configuration + properties: + certificatesSecrets: + description: CertificatesSecrets defines a list of secret storing + client certificates for mTLS. + items: + type: string + type: array + insecureSkipVerify: + description: InsecureSkipVerify disables TLS certificate verification. + type: boolean + peerCertURI: + description: MaxIdleConnsPerHost controls the maximum idle (keep-alive) + to keep per-host. PeerCertURI defines the peer cert URI used + to match against SAN URI during the peer certificate verification. + type: string + rootCAsSecrets: + description: RootCAsSecrets defines a list of CA secret used to + validate self-signed certificates. + items: + type: string + type: array + serverName: + description: ServerName defines the server name used to contact + the server. + type: string + spiffe: + description: Spiffe defines the SPIFFE configuration. + properties: + ids: + description: IDs defines the allowed SPIFFE IDs (takes precedence + over the SPIFFE TrustDomain). + items: + type: string + type: array + trustDomain: + description: TrustDomain defines the allowed SPIFFE trust + domain. + type: string + type: object + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml b/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml similarity index 98% rename from docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml rename to docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml index ffbd86ec14347f41e433fc57fc6f25c6b95a5e7a..ddf525ceb4efd94eda2f612c9ab73e94b8036573 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsoptions.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_tlsoptions.yaml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: tlsoptions.traefik.containo.us + name: tlsoptions.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: TLSOption listKind: TLSOptionList diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsstores.yaml b/docs/content/reference/dynamic-configuration/traefik.io_tlsstores.yaml similarity index 98% rename from docs/content/reference/dynamic-configuration/traefik.containo.us_tlsstores.yaml rename to docs/content/reference/dynamic-configuration/traefik.io_tlsstores.yaml index 9e35d689794c3ab98e58c80dfc0d334cc20175a7..61d7063c008a2b7be818f82d1c90f981a8aaa786 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_tlsstores.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_tlsstores.yaml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: tlsstores.traefik.containo.us + name: tlsstores.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: TLSStore listKind: TLSStoreList diff --git a/docs/content/reference/dynamic-configuration/traefik.containo.us_traefikservices.yaml b/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml similarity index 93% rename from docs/content/reference/dynamic-configuration/traefik.containo.us_traefikservices.yaml rename to docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml index 3289806f9c77b801cd0747265a860996b3aac4df..870dfdf53b422c5d658ca4b33e4fafc4dc3148eb 100644 --- a/docs/content/reference/dynamic-configuration/traefik.containo.us_traefikservices.yaml +++ b/docs/content/reference/dynamic-configuration/traefik.io_traefikservices.yaml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: traefikservices.traefik.containo.us + name: traefikservices.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: TraefikService listKind: TraefikServiceList @@ -75,6 +75,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or + if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. @@ -166,6 +173,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if the + only child is the Kubernetes Service clusterIP. The Kubernetes + Service itself does load-balance to the pods. By default, NativeLB + is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. By default, @@ -263,6 +277,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or + if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. diff --git a/docs/content/reference/static-configuration/cli-ref.md b/docs/content/reference/static-configuration/cli-ref.md index 39cb5d102178f2d6fb1fb7f52d9cc37bb858ece0..ac90226ce8de82f7b858d066933dd5431d0e2d77 100644 --- a/docs/content/reference/static-configuration/cli-ref.md +++ b/docs/content/reference/static-configuration/cli-ref.md @@ -189,9 +189,6 @@ WriteTimeout is the maximum duration before timing out writes of the response. I `--entrypoints.<name>.udp.timeout`: Timeout defines how long to wait on an idle session before releasing the related resources. (Default: ```3```) -`--experimental.hub`: -Enable the Traefik Hub provider. (Default: ```false```) - `--experimental.kubernetesgateway`: Allow the Kubernetes gateway api provider usage. (Default: ```false```) @@ -288,42 +285,6 @@ Prefix to use for metrics collection. (Default: ```traefik```) `--metrics.datadog.pushinterval`: Datadog push interval. (Default: ```10```) -`--metrics.influxdb`: -InfluxDB metrics exporter type. (Default: ```false```) - -`--metrics.influxdb.addentrypointslabels`: -Enable metrics on entry points. (Default: ```true```) - -`--metrics.influxdb.additionallabels.<name>`: -Additional labels (influxdb tags) on all metrics - -`--metrics.influxdb.address`: -InfluxDB address. (Default: ```localhost:8089```) - -`--metrics.influxdb.addrouterslabels`: -Enable metrics on routers. (Default: ```false```) - -`--metrics.influxdb.addserviceslabels`: -Enable metrics on services. (Default: ```true```) - -`--metrics.influxdb.database`: -InfluxDB database used when protocol is http. - -`--metrics.influxdb.password`: -InfluxDB password (only with http). - -`--metrics.influxdb.protocol`: -InfluxDB address protocol (udp or http). (Default: ```udp```) - -`--metrics.influxdb.pushinterval`: -InfluxDB push interval. (Default: ```10```) - -`--metrics.influxdb.retentionpolicy`: -InfluxDB retention policy used when protocol is http. - -`--metrics.influxdb.username`: -InfluxDB username (only with http). - `--metrics.influxdb2`: InfluxDB v2 metrics exporter type. (Default: ```false```) @@ -417,6 +378,9 @@ Buckets for latency metrics. (Default: ```0.100000, 0.300000, 1.200000, 5.000000 `--metrics.prometheus.entrypoint`: EntryPoint (Default: ```traefik```) +`--metrics.prometheus.headerlabels.<name>`: +Defines the extra labels for the requests_total metrics, and for each of them, the request header containing the value for this label. + `--metrics.prometheus.manualrouting`: Manual routing (Default: ```false```) @@ -771,6 +735,9 @@ Allow ExternalName services. (Default: ```false```) `--providers.kubernetesingress.certauthfilepath`: Kubernetes certificate authority file path (not needed for in-cluster client). +`--providers.kubernetesingress.disableingressclasslookup`: +Disables the lookup of IngressClasses. (Default: ```false```) + `--providers.kubernetesingress.endpoint`: Kubernetes server endpoint (required for external cluster client). @@ -798,66 +765,6 @@ Ingress refresh throttle duration (Default: ```0```) `--providers.kubernetesingress.token`: Kubernetes bearer token (not needed for in-cluster client). -`--providers.marathon`: -Enable Marathon backend with default settings. (Default: ```false```) - -`--providers.marathon.basic.httpbasicauthuser`: -Basic authentication User. - -`--providers.marathon.basic.httpbasicpassword`: -Basic authentication Password. - -`--providers.marathon.constraints`: -Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application. - -`--providers.marathon.dcostoken`: -DCOSToken for DCOS environment, This will override the Authorization header. - -`--providers.marathon.defaultrule`: -Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) - -`--providers.marathon.dialertimeout`: -Set a dialer timeout for Marathon. (Default: ```5```) - -`--providers.marathon.endpoint`: -Marathon server endpoint. You can also specify multiple endpoint for Marathon. (Default: ```http://127.0.0.1:8080```) - -`--providers.marathon.exposedbydefault`: -Expose Marathon apps by default. (Default: ```true```) - -`--providers.marathon.forcetaskhostname`: -Force to use the task's hostname. (Default: ```false```) - -`--providers.marathon.keepalive`: -Set a TCP Keep Alive time. (Default: ```10```) - -`--providers.marathon.respectreadinesschecks`: -Filter out tasks with non-successful readiness checks during deployments. (Default: ```false```) - -`--providers.marathon.responseheadertimeout`: -Set a response header timeout for Marathon. (Default: ```60```) - -`--providers.marathon.tls.ca`: -TLS CA - -`--providers.marathon.tls.cert`: -TLS cert - -`--providers.marathon.tls.insecureskipverify`: -TLS insecure skip verify (Default: ```false```) - -`--providers.marathon.tls.key`: -TLS key - -`--providers.marathon.tlshandshaketimeout`: -Set a TLS handshake timeout for Marathon. (Default: ```5```) - -`--providers.marathon.trace`: -Display additional provider logs. (Default: ```false```) - -`--providers.marathon.watch`: -Watch provider. (Default: ```true```) - `--providers.nomad`: Enable Nomad backend with default settings. (Default: ```false```) @@ -868,7 +775,7 @@ Constraints is an expression that Traefik matches against the Nomad service's ta Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) `--providers.nomad.endpoint.address`: -The address of the Nomad server, including scheme and port. +The address of the Nomad server, including scheme and port. (Default: ```http://127.0.0.1:4646```) `--providers.nomad.endpoint.endpointwaittime`: WaitTime limits how long a Watch will block. If not provided, the agent default values will be used (Default: ```0```) @@ -912,33 +819,6 @@ Plugins configuration. `--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: ```2```) -`--providers.rancher`: -Enable Rancher backend with default settings. (Default: ```false```) - -`--providers.rancher.constraints`: -Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container. - -`--providers.rancher.defaultrule`: -Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) - -`--providers.rancher.enableservicehealthfilter`: -Filter services with unhealthy states and inactive states. (Default: ```true```) - -`--providers.rancher.exposedbydefault`: -Expose containers by default. (Default: ```true```) - -`--providers.rancher.intervalpoll`: -Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate). (Default: ```false```) - -`--providers.rancher.prefix`: -Prefix used for accessing the Rancher metadata service. (Default: ```latest```) - -`--providers.rancher.refreshseconds`: -Defines the polling interval in seconds. (Default: ```15```) - -`--providers.rancher.watch`: -Watch provider. (Default: ```true```) - `--providers.redis`: Enable Redis backend with default settings. (Default: ```false```) @@ -1020,6 +900,33 @@ Defines the allowed SPIFFE trust domain. `--spiffe.workloadapiaddr`: Defines the workload API address. +`--tcpserverstransport.dialkeepalive`: +Defines the interval between keep-alive probes for an active network connection. If zero, keep-alive probes are sent with a default value (currently 15 seconds), if supported by the protocol and operating system. Network protocols or operating systems that do not support keep-alives ignore this field. If negative, keep-alive probes are disabled (Default: ```15```) + +`--tcpserverstransport.dialtimeout`: +Defines the amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists. (Default: ```30```) + +`--tcpserverstransport.terminationdelay`: +Defines the delay to wait before fully terminating the connection, after one connected peer has closed its writing capability. (Default: ```0```) + +`--tcpserverstransport.tls`: +Defines the TLS configuration. (Default: ```false```) + +`--tcpserverstransport.tls.insecureskipverify`: +Disables SSL certificate verification. (Default: ```false```) + +`--tcpserverstransport.tls.rootcas`: +Defines a list of CA secret used to validate self-signed certificate + +`--tcpserverstransport.tls.spiffe`: +Defines the SPIFFE TLS configuration. (Default: ```false```) + +`--tcpserverstransport.tls.spiffe.ids`: +Defines the allowed SPIFFE IDs (takes precedence over the SPIFFE TrustDomain). + +`--tcpserverstransport.tls.spiffe.trustdomain`: +Defines the allowed SPIFFE trust domain. + `--tracing`: OpenTracing configuration. (Default: ```false```) @@ -1038,6 +945,9 @@ Sets a list of key:value tags on all spans. `--tracing.datadog.localagenthostport`: Sets the Datadog Agent host:port. (Default: ```localhost:8126```) +`--tracing.datadog.localagentsocket`: +Sets the socket for the Datadog Agent. + `--tracing.datadog.parentidheadername`: Sets the header name used to store the parent ID. diff --git a/docs/content/reference/static-configuration/env-ref.md b/docs/content/reference/static-configuration/env-ref.md index 08fb6bd7d9c0a6ac98455d38e5274c83ff7b4599..31748c91cf711b7737e26ac94b4be2f27a113466 100644 --- a/docs/content/reference/static-configuration/env-ref.md +++ b/docs/content/reference/static-configuration/env-ref.md @@ -189,9 +189,6 @@ WriteTimeout is the maximum duration before timing out writes of the response. I `TRAEFIK_ENTRYPOINTS_<NAME>_UDP_TIMEOUT`: Timeout defines how long to wait on an idle session before releasing the related resources. (Default: ```3```) -`TRAEFIK_EXPERIMENTAL_HUB`: -Enable the Traefik Hub provider. (Default: ```false```) - `TRAEFIK_EXPERIMENTAL_KUBERNETESGATEWAY`: Allow the Kubernetes gateway api provider usage. (Default: ```false```) @@ -288,9 +285,6 @@ Prefix to use for metrics collection. (Default: ```traefik```) `TRAEFIK_METRICS_DATADOG_PUSHINTERVAL`: Datadog push interval. (Default: ```10```) -`TRAEFIK_METRICS_INFLUXDB`: -InfluxDB metrics exporter type. (Default: ```false```) - `TRAEFIK_METRICS_INFLUXDB2`: InfluxDB v2 metrics exporter type. (Default: ```false```) @@ -321,39 +315,6 @@ InfluxDB v2 push interval. (Default: ```10```) `TRAEFIK_METRICS_INFLUXDB2_TOKEN`: InfluxDB v2 access token. -`TRAEFIK_METRICS_INFLUXDB_ADDENTRYPOINTSLABELS`: -Enable metrics on entry points. (Default: ```true```) - -`TRAEFIK_METRICS_INFLUXDB_ADDITIONALLABELS_<NAME>`: -Additional labels (influxdb tags) on all metrics - -`TRAEFIK_METRICS_INFLUXDB_ADDRESS`: -InfluxDB address. (Default: ```localhost:8089```) - -`TRAEFIK_METRICS_INFLUXDB_ADDROUTERSLABELS`: -Enable metrics on routers. (Default: ```false```) - -`TRAEFIK_METRICS_INFLUXDB_ADDSERVICESLABELS`: -Enable metrics on services. (Default: ```true```) - -`TRAEFIK_METRICS_INFLUXDB_DATABASE`: -InfluxDB database used when protocol is http. - -`TRAEFIK_METRICS_INFLUXDB_PASSWORD`: -InfluxDB password (only with http). - -`TRAEFIK_METRICS_INFLUXDB_PROTOCOL`: -InfluxDB address protocol (udp or http). (Default: ```udp```) - -`TRAEFIK_METRICS_INFLUXDB_PUSHINTERVAL`: -InfluxDB push interval. (Default: ```10```) - -`TRAEFIK_METRICS_INFLUXDB_RETENTIONPOLICY`: -InfluxDB retention policy used when protocol is http. - -`TRAEFIK_METRICS_INFLUXDB_USERNAME`: -InfluxDB username (only with http). - `TRAEFIK_METRICS_OPENTELEMETRY`: OpenTelemetry metrics exporter type. (Default: ```false```) @@ -417,6 +378,9 @@ Buckets for latency metrics. (Default: ```0.100000, 0.300000, 1.200000, 5.000000 `TRAEFIK_METRICS_PROMETHEUS_ENTRYPOINT`: EntryPoint (Default: ```traefik```) +`TRAEFIK_METRICS_PROMETHEUS_HEADERLABELS_<NAME>`: +Defines the extra labels for the requests_total metrics, and for each of them, the request header containing the value for this label. + `TRAEFIK_METRICS_PROMETHEUS_MANUALROUTING`: Manual routing (Default: ```false```) @@ -771,6 +735,9 @@ Allow ExternalName services. (Default: ```false```) `TRAEFIK_PROVIDERS_KUBERNETESINGRESS_CERTAUTHFILEPATH`: Kubernetes certificate authority file path (not needed for in-cluster client). +`TRAEFIK_PROVIDERS_KUBERNETESINGRESS_DISABLEINGRESSCLASSLOOKUP`: +Disables the lookup of IngressClasses. (Default: ```false```) + `TRAEFIK_PROVIDERS_KUBERNETESINGRESS_ENDPOINT`: Kubernetes server endpoint (required for external cluster client). @@ -798,66 +765,6 @@ Ingress refresh throttle duration (Default: ```0```) `TRAEFIK_PROVIDERS_KUBERNETESINGRESS_TOKEN`: Kubernetes bearer token (not needed for in-cluster client). -`TRAEFIK_PROVIDERS_MARATHON`: -Enable Marathon backend with default settings. (Default: ```false```) - -`TRAEFIK_PROVIDERS_MARATHON_BASIC_HTTPBASICAUTHUSER`: -Basic authentication User. - -`TRAEFIK_PROVIDERS_MARATHON_BASIC_HTTPBASICPASSWORD`: -Basic authentication Password. - -`TRAEFIK_PROVIDERS_MARATHON_CONSTRAINTS`: -Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application. - -`TRAEFIK_PROVIDERS_MARATHON_DCOSTOKEN`: -DCOSToken for DCOS environment, This will override the Authorization header. - -`TRAEFIK_PROVIDERS_MARATHON_DEFAULTRULE`: -Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) - -`TRAEFIK_PROVIDERS_MARATHON_DIALERTIMEOUT`: -Set a dialer timeout for Marathon. (Default: ```5```) - -`TRAEFIK_PROVIDERS_MARATHON_ENDPOINT`: -Marathon server endpoint. You can also specify multiple endpoint for Marathon. (Default: ```http://127.0.0.1:8080```) - -`TRAEFIK_PROVIDERS_MARATHON_EXPOSEDBYDEFAULT`: -Expose Marathon apps by default. (Default: ```true```) - -`TRAEFIK_PROVIDERS_MARATHON_FORCETASKHOSTNAME`: -Force to use the task's hostname. (Default: ```false```) - -`TRAEFIK_PROVIDERS_MARATHON_KEEPALIVE`: -Set a TCP Keep Alive time. (Default: ```10```) - -`TRAEFIK_PROVIDERS_MARATHON_RESPECTREADINESSCHECKS`: -Filter out tasks with non-successful readiness checks during deployments. (Default: ```false```) - -`TRAEFIK_PROVIDERS_MARATHON_RESPONSEHEADERTIMEOUT`: -Set a response header timeout for Marathon. (Default: ```60```) - -`TRAEFIK_PROVIDERS_MARATHON_TLSHANDSHAKETIMEOUT`: -Set a TLS handshake timeout for Marathon. (Default: ```5```) - -`TRAEFIK_PROVIDERS_MARATHON_TLS_CA`: -TLS CA - -`TRAEFIK_PROVIDERS_MARATHON_TLS_CERT`: -TLS cert - -`TRAEFIK_PROVIDERS_MARATHON_TLS_INSECURESKIPVERIFY`: -TLS insecure skip verify (Default: ```false```) - -`TRAEFIK_PROVIDERS_MARATHON_TLS_KEY`: -TLS key - -`TRAEFIK_PROVIDERS_MARATHON_TRACE`: -Display additional provider logs. (Default: ```false```) - -`TRAEFIK_PROVIDERS_MARATHON_WATCH`: -Watch provider. (Default: ```true```) - `TRAEFIK_PROVIDERS_NOMAD`: Enable Nomad backend with default settings. (Default: ```false```) @@ -868,7 +775,7 @@ Constraints is an expression that Traefik matches against the Nomad service's ta Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) `TRAEFIK_PROVIDERS_NOMAD_ENDPOINT_ADDRESS`: -The address of the Nomad server, including scheme and port. +The address of the Nomad server, including scheme and port. (Default: ```http://127.0.0.1:4646```) `TRAEFIK_PROVIDERS_NOMAD_ENDPOINT_ENDPOINTWAITTIME`: WaitTime limits how long a Watch will block. If not provided, the agent default values will be used (Default: ```0```) @@ -912,33 +819,6 @@ Plugins configuration. `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: ```2```) -`TRAEFIK_PROVIDERS_RANCHER`: -Enable Rancher backend with default settings. (Default: ```false```) - -`TRAEFIK_PROVIDERS_RANCHER_CONSTRAINTS`: -Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container. - -`TRAEFIK_PROVIDERS_RANCHER_DEFAULTRULE`: -Default rule. (Default: ```Host(`{{ normalize .Name }}`)```) - -`TRAEFIK_PROVIDERS_RANCHER_ENABLESERVICEHEALTHFILTER`: -Filter services with unhealthy states and inactive states. (Default: ```true```) - -`TRAEFIK_PROVIDERS_RANCHER_EXPOSEDBYDEFAULT`: -Expose containers by default. (Default: ```true```) - -`TRAEFIK_PROVIDERS_RANCHER_INTERVALPOLL`: -Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate). (Default: ```false```) - -`TRAEFIK_PROVIDERS_RANCHER_PREFIX`: -Prefix used for accessing the Rancher metadata service. (Default: ```latest```) - -`TRAEFIK_PROVIDERS_RANCHER_REFRESHSECONDS`: -Defines the polling interval in seconds. (Default: ```15```) - -`TRAEFIK_PROVIDERS_RANCHER_WATCH`: -Watch provider. (Default: ```true```) - `TRAEFIK_PROVIDERS_REDIS`: Enable Redis backend with default settings. (Default: ```false```) @@ -1020,6 +900,33 @@ Defines the allowed SPIFFE trust domain. `TRAEFIK_SPIFFE_WORKLOADAPIADDR`: Defines the workload API address. +`TRAEFIK_TCPSERVERSTRANSPORT_DIALKEEPALIVE`: +Defines the interval between keep-alive probes for an active network connection. If zero, keep-alive probes are sent with a default value (currently 15 seconds), if supported by the protocol and operating system. Network protocols or operating systems that do not support keep-alives ignore this field. If negative, keep-alive probes are disabled (Default: ```15```) + +`TRAEFIK_TCPSERVERSTRANSPORT_DIALTIMEOUT`: +Defines the amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists. (Default: ```30```) + +`TRAEFIK_TCPSERVERSTRANSPORT_TERMINATIONDELAY`: +Defines the delay to wait before fully terminating the connection, after one connected peer has closed its writing capability. (Default: ```0```) + +`TRAEFIK_TCPSERVERSTRANSPORT_TLS`: +Defines the TLS configuration. (Default: ```false```) + +`TRAEFIK_TCPSERVERSTRANSPORT_TLS_INSECURESKIPVERIFY`: +Disables SSL certificate verification. (Default: ```false```) + +`TRAEFIK_TCPSERVERSTRANSPORT_TLS_ROOTCAS`: +Defines a list of CA secret used to validate self-signed certificate + +`TRAEFIK_TCPSERVERSTRANSPORT_TLS_SPIFFE`: +Defines the SPIFFE TLS configuration. (Default: ```false```) + +`TRAEFIK_TCPSERVERSTRANSPORT_TLS_SPIFFE_IDS`: +Defines the allowed SPIFFE IDs (takes precedence over the SPIFFE TrustDomain). + +`TRAEFIK_TCPSERVERSTRANSPORT_TLS_SPIFFE_TRUSTDOMAIN`: +Defines the allowed SPIFFE trust domain. + `TRAEFIK_TRACING`: OpenTracing configuration. (Default: ```false```) @@ -1038,6 +945,9 @@ Sets a list of key:value tags on all spans. `TRAEFIK_TRACING_DATADOG_LOCALAGENTHOSTPORT`: Sets the Datadog Agent host:port. (Default: ```localhost:8126```) +`TRAEFIK_TRACING_DATADOG_LOCALAGENTSOCKET`: +Sets the socket for the Datadog Agent. + `TRAEFIK_TRACING_DATADOG_PARENTIDHEADERNAME`: Sets the header name used to store the parent ID. diff --git a/docs/content/reference/static-configuration/file.toml b/docs/content/reference/static-configuration/file.toml index 22420a8067c20b1cc80001130fe1b1ef4f805b86..b08074bb6028a8ad7ec3194475830d0d981da551 100644 --- a/docs/content/reference/static-configuration/file.toml +++ b/docs/content/reference/static-configuration/file.toml @@ -6,10 +6,29 @@ insecureSkipVerify = true rootCAs = ["foobar", "foobar"] maxIdleConnsPerHost = 42 + [serversTransport.forwardingTimeouts] dialTimeout = "42s" responseHeaderTimeout = "42s" idleConnTimeout = "42s" + readIdleTimeout = "42s" + pingTimeout = "42s" + + [serversTransport.spiffe] + ids = ["foobar", "foobar"] + trustDomain = "foobar" + +[tcpServersTransport] + dialTimeout = "42s" + dialKeepAlive = "42s" + + [tcpServersTransport.tls] + insecureSkipVerify = true + rootCAs = ["foobar", "foobar"] + + [tcpServersTransport.tls.spiffe] + ids = ["foobar", "foobar"] + trustDomain = "foobar" [entryPoints] [entryPoints.EntryPoint0] @@ -79,28 +98,6 @@ watch = true filename = "foobar" debugLogGeneratedTemplate = true - [providers.marathon] - constraints = "foobar" - trace = true - watch = true - endpoint = "foobar" - defaultRule = "foobar" - exposedByDefault = true - dcosToken = "foobar" - dialerTimeout = "42s" - responseHeaderTimeout = "42s" - tlsHandshakeTimeout = "42s" - keepAlive = "42s" - forceTaskHostname = true - respectReadinessChecks = true - [providers.marathon.tls] - ca = "foobar" - cert = "foobar" - key = "foobar" - insecureSkipVerify = true - [providers.marathon.basic] - httpBasicAuthUser = "foobar" - httpBasicPassword = "foobar" [providers.kubernetesIngress] endpoint = "foobar" token = "foobar" @@ -111,6 +108,7 @@ throttleDuration = "42s" allowEmptyServices = true allowExternalNameServices = true + disableIngressClassLookup = true [providers.kubernetesIngress.ingressEndpoint] ip = "foobar" hostname = "foobar" @@ -135,15 +133,6 @@ throttleDuration = "42s" [providers.rest] insecure = true - [providers.rancher] - constraints = "foobar" - watch = true - defaultRule = "foobar" - exposedByDefault = true - enableServiceHealthFilter = true - refreshSeconds = 42 - intervalPoll = true - prefix = "foobar" [providers.consulCatalog] constraints = "foobar" prefix = "foobar" @@ -267,6 +256,9 @@ addServicesLabels = true entryPoint = "foobar" manualRouting = true + [metrics.prometheus.headerLabels] + label1 = "foobar" + label2 = "foobar" [metrics.datadog] address = "foobar" pushInterval = "42s" @@ -281,20 +273,6 @@ addRoutersLabels = true addServicesLabels = true prefix = "foobar" - [metrics.influxDB] - address = "foobar" - protocol = "foobar" - pushInterval = "42s" - database = "foobar" - retentionPolicy = "foobar" - username = "foobar" - password = "foobar" - addEntryPointsLabels = true - addRoutersLabels = true - addServicesLabels = true - [metrics.influxDB.additionalLabels] - name0 = "foobar" - name1 = "foobar" [metrics.influxDB2] address = "foobar" token = "foobar" @@ -384,6 +362,7 @@ sampleRate = 42.0 [tracing.datadog] localAgentHostPort = "foobar" + localAgentSocket = "foobar" [tracing.datadog.globalTags] tag1 = "foobar" tag2 = "foobar" @@ -461,7 +440,7 @@ [experimental] kubernetesGateway = true - hub = true + http3 = true [experimental.plugins] [experimental.plugins.Descriptor0] moduleName = "foobar" diff --git a/docs/content/reference/static-configuration/file.yaml b/docs/content/reference/static-configuration/file.yaml index 596f5ab4d2bc85ddf74b1b19d9966dbfe614eeb8..cb6f3c257b79d7016fc039a4f4e289afb071c797 100644 --- a/docs/content/reference/static-configuration/file.yaml +++ b/docs/content/reference/static-configuration/file.yaml @@ -1,7 +1,7 @@ global: checkNewVersion: true sendAnonymousUsage: true -serversTransport: +serversTransports: insecureSkipVerify: true rootCAs: - foobar @@ -11,6 +11,26 @@ serversTransport: dialTimeout: 42s responseHeaderTimeout: 42s idleConnTimeout: 42s + readIdleTimeout: 42s + pingTimeout: 42s + spiffe: + ids: + - foobar + - foobar + trustDomain: foobar +tcpServersTransport: + dialTimeout: 42s + dialKeepAlive: 42s + tls: + insecureSkipVerify: true + rootCAs: + - foobar + - foobar + spiffe: + ids: + - foobar + - foobar + trustDomain: foobar entryPoints: EntryPoint0: address: foobar @@ -85,28 +105,6 @@ providers: watch: true filename: foobar debugLogGeneratedTemplate: true - marathon: - constraints: foobar - trace: true - watch: true - endpoint: foobar - defaultRule: foobar - exposedByDefault: true - dcosToken: foobar - tls: - ca: foobar - cert: foobar - key: foobar - insecureSkipVerify: true - dialerTimeout: 42s - responseHeaderTimeout: 42s - tlsHandshakeTimeout: 42s - keepAlive: 42s - forceTaskHostname: true - basic: - httpBasicAuthUser: foobar - httpBasicPassword: foobar - respectReadinessChecks: true kubernetesIngress: endpoint: foobar token: foobar @@ -119,6 +117,7 @@ providers: throttleDuration: 42s allowEmptyServices: true allowExternalNameServices: true + disableIngressClassLookup: true ingressEndpoint: ip: foobar hostname: foobar @@ -147,15 +146,6 @@ providers: throttleDuration: 42s rest: insecure: true - rancher: - constraints: foobar - watch: true - defaultRule: foobar - exposedByDefault: true - enableServiceHealthFilter: true - refreshSeconds: 42 - intervalPoll: true - prefix: foobar consulCatalog: constraints: foobar prefix: foobar @@ -295,6 +285,9 @@ metrics: addServicesLabels: true entryPoint: foobar manualRouting: true + headerLabels: + label1: foobar + label2: foobar datadog: address: foobar pushInterval: 42s @@ -309,20 +302,6 @@ metrics: addRoutersLabels: true addServicesLabels: true prefix: foobar - influxDB: - address: foobar - protocol: foobar - pushInterval: 42s - database: foobar - retentionPolicy: foobar - username: foobar - password: foobar - addEntryPointsLabels: true - addRoutersLabels: true - addServicesLabels: true - additionalLabels: - name0: foobar - name1: foobar influxDB2: address: foobar token: foobar @@ -413,6 +392,7 @@ tracing: sampleRate: 42 datadog: localAgentHostPort: foobar + localAgentSocket: foobar globalTags: tag1: foobar tag2: foobar @@ -489,7 +469,7 @@ hub: key: foobar experimental: kubernetesGateway: true - hub: true + http3: true plugins: Descriptor0: moduleName: foobar diff --git a/docs/content/routing/entrypoints.md b/docs/content/routing/entrypoints.md index ece0f2c0b638f8b32d7219aba518bd1e8840496a..bc7ff18e9493f57b5c44d756201005f21ea11042 100644 --- a/docs/content/routing/entrypoints.md +++ b/docs/content/routing/entrypoints.md @@ -320,7 +320,7 @@ this entryPoint is the same as the one used for TLS traffic. ```yaml tab="File (YAML)" entryPoints: name: - http3: {} + http3: {} ``` ```toml tab="File (TOML)" diff --git a/docs/content/routing/overview.md b/docs/content/routing/overview.md index 3816c1e7033fcabfa208e65370ed703c4e7e32c1..650a729292e277a52afd986661621f97ab196d47 100644 --- a/docs/content/routing/overview.md +++ b/docs/content/routing/overview.md @@ -250,10 +250,12 @@ and then between Traefik and the backend servers, is configured through the In addition, a few parameters are dedicated to configuring globally what happens with the connections between Traefik and the backends. -This is done through the `serversTransport` section of the configuration, -which features these options: +This is done through the [`serversTransport`](#http-servers-transports) and [`tcpServersTransport`](#tcp-servers-transports) +sections of the configuration, which features these options: -### `insecureSkipVerify` +### HTTP Servers Transports + +#### `insecureSkipVerify` _Optional, Default=false_ @@ -276,7 +278,7 @@ serversTransport: --serversTransport.insecureSkipVerify=true ``` -### `rootCAs` +#### `rootCAs` _Optional_ @@ -302,7 +304,7 @@ serversTransport: --serversTransport.rootCAs=foo.crt,bar.crt ``` -### `maxIdleConnsPerHost` +#### `maxIdleConnsPerHost` _Optional, Default=2_ @@ -325,7 +327,7 @@ serversTransport: --serversTransport.maxIdleConnsPerHost=7 ``` -### `spiffe` +#### `spiffe` Please note that [SPIFFE](../https/spiffe.md) must be enabled in the static configuration before using it to secure the connection between Traefik and the backends. @@ -380,7 +382,7 @@ serversTransport: --serversTransport.spiffe.trustDomain=spiffe://trust-domain ``` -### `forwardingTimeouts` +#### `forwardingTimeouts` `forwardingTimeouts` is about a number of timeouts relevant to when forwarding requests to the backend servers. @@ -462,4 +464,186 @@ serversTransport: --serversTransport.forwardingTimeouts.idleConnTimeout=1s ``` +### TCP Servers Transports + +#### `dialTimeout` + +_Optional, Default="30s"_ + +`dialTimeout` is the maximum duration allowed for a connection to a backend server to be established. +Zero means no timeout. + +```yaml tab="File (YAML)" +## Static configuration +tcpServersTransport: + dialTimeout: 30s +``` + +```toml tab="File (TOML)" +## Static configuration +[tcpServersTransport] + dialTimeout = "30s" +``` + +```bash tab="CLI" +## Static configuration +--tcpServersTransport.dialTimeout=30s +``` + +#### `dialKeepAlive` + +_Optional, Default="15s"_ + +`dialKeepAlive` defines the interval between keep-alive probes sent on an active network connection. +If zero, keep-alive probes are sent with a default value (currently 15 seconds), if supported by the protocol and +operating system. Network protocols or operating systems that do not support keep-alives ignore this field. If negative, +keep-alive probes are disabled. + +```yaml tab="File (YAML)" +## Static configuration +tcpServersTransport: + dialKeepAlive: 30s +``` + +```toml tab="File (TOML)" +## Static configuration +[tcpServersTransport] + dialKeepAlive = "30s" +``` + +```bash tab="CLI" +## Static configuration +--tcpServersTransport.dialKeepAlive=30s +``` + +#### `tls` + +`tls` defines the TLS configuration to connect with TCP backends. + +_Optional_ + +An empty `tls` section enables TLS. + +```yaml tab="File (YAML)" +## Static configuration +tcpServersTransport: + tls: {} +``` + +```toml tab="File (TOML)" +## Static configuration +[tcpServersTransport.tls] +``` + +```bash tab="CLI" +## Static configuration +--tcpServersTransport.tls=true +``` + +#### `tls.insecureSkipVerify` + +_Optional_ + +`insecureSkipVerify` disables the server's certificate chain and host name verification. + +```yaml tab="File (YAML)" +## Static configuration +tcpServersTransport: + tls: + insecureSkipVerify: true +``` + +```toml tab="File (TOML)" +## Static configuration +[tcpServersTransport.tls] + insecureSkipVerify = true +``` + +```bash tab="CLI" +## Static configuration +--tcpServersTransport.tls.insecureSkipVerify=true +``` + +#### `tls.rootCAs` + +_Optional_ + +`rootCAs` defines the set of Root Certificate Authorities (as file paths, or data bytes) +to use when verifying self-signed TLS server certificates. + +```yaml tab="File (YAML)" +## Static configuration +tcpServersTransport: + tls: + rootCAs: + - foo.crt + - bar.crt +``` + +```toml tab="File (TOML)" +## Static configuration +[tcpServersTransport.tls] + rootCAs = ["foo.crt", "bar.crt"] +``` + +```bash tab="CLI" +## Static configuration +--tcpServersTransport.tls.rootCAs=foo.crt,bar.crt +``` + +#### `spiffe` + +Please note that [SPIFFE](../https/spiffe.md) must be enabled in the static configuration +before using it to secure the connection between Traefik and the backends. + +#### `spiffe.ids` + +_Optional_ + +`ids` defines the allowed SPIFFE IDs. +This takes precedence over the SPIFFE TrustDomain. + +```yaml tab="File (YAML)" +## Static configuration +tcpServersTransport: + spiffe: + ids: + - spiffe://trust-domain/id1 + - spiffe://trust-domain/id2 +``` + +```toml tab="File (TOML)" +## Static configuration +[tcpServersTransport.spiffe] + ids = ["spiffe://trust-domain/id1", "spiffe://trust-domain/id2"] +``` + +```bash tab="CLI" +## Static configuration +--tcpServersTransport.spiffe.ids=spiffe://trust-domain/id1,spiffe://trust-domain/id2 +``` + +#### `spiffe.trustDomain` + +_Optional_ + +`trustDomain` defines the allowed SPIFFE trust domain. + +```yaml tab="File (YAML)" +## Static configuration +tcpServersTransport: + trustDomain: spiffe://trust-domain +``` + +```toml tab="File (TOML)" +## Static configuration +[tcpServersTransport.spiffe] + trustDomain = "spiffe://trust-domain" +``` + +```bash tab="CLI" +## Static configuration +--tcpServersTransport.spiffe.trustDomain=spiffe://trust-domain +``` + {!traefik-for-business-applications.md!} diff --git a/docs/content/routing/providers/consul-catalog.md b/docs/content/routing/providers/consul-catalog.md index 6d2ddb8a27382abd1124600e6b9ad9d8cb1b9445..8eb985043da2800aa13dc4d2b0433078b8676cd1 100644 --- a/docs/content/routing/providers/consul-catalog.md +++ b/docs/content/routing/providers/consul-catalog.md @@ -404,12 +404,12 @@ You can declare TCP Routers and/or Services using tags. traefik.tcp.services.mytcpservice.loadbalancer.server.port=423 ``` -??? info "`traefik.tcp.services.<service_name>.loadbalancer.terminationdelay`" - - See [termination delay](../services/index.md#termination-delay) for more information. +??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.tls`" + + Determines whether to use TLS when dialing with the backend. ```yaml - traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100 + traefik.tcp.services.mytcpservice.loadbalancer.server.tls=true ``` ??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`" @@ -420,6 +420,15 @@ You can declare TCP Routers and/or Services using tags. traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version=1 ``` +??? info "`traefik.tcp.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_2) for more information. + + ```yaml + traefik.tcp.services.myservice.loadbalancer.serverstransport=foobar@file + ``` + ### UDP You can declare UDP Routers and/or Services using tags. diff --git a/docs/content/routing/providers/docker.md b/docs/content/routing/providers/docker.md index eacf78956a68e7032dd78feadba695be09bd96db..08e8e43adae3b93bd6915b370ab8e34cb837d418 100644 --- a/docs/content/routing/providers/docker.md +++ b/docs/content/routing/providers/docker.md @@ -577,12 +577,12 @@ You can declare TCP Routers and/or Services using labels. - "traefik.tcp.services.mytcpservice.loadbalancer.server.port=423" ``` -??? info "`traefik.tcp.services.<service_name>.loadbalancer.terminationdelay`" +??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.tls`" - See [termination delay](../services/index.md#termination-delay) for more information. + Determines whether to use TLS when dialing with the backend. ```yaml - - "traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100" + - "traefik.tcp.services.mytcpservice.loadbalancer.server.tls=true" ``` ??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`" @@ -593,6 +593,15 @@ You can declare TCP Routers and/or Services using labels. - "traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version=1" ``` +??? info "`traefik.tcp.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_2) for more information. + + ```yaml + - "traefik.tcp.services.<service_name>.loadbalancer.serverstransport=foobar@file" + ``` + ### UDP You can declare UDP Routers and/or Services using labels. diff --git a/docs/content/routing/providers/ecs.md b/docs/content/routing/providers/ecs.md index 9cd1806416cb06f0c80eb2ac15603e82651072a3..718303c0ba840bab7dbfe16a3a411bd3f2aa2308 100644 --- a/docs/content/routing/providers/ecs.md +++ b/docs/content/routing/providers/ecs.md @@ -418,12 +418,12 @@ You can declare TCP Routers and/or Services using labels. traefik.tcp.services.mytcpservice.loadbalancer.server.port=423 ``` -??? info "`traefik.tcp.services.<service_name>.loadbalancer.terminationdelay`" - - See [termination delay](../services/index.md#termination-delay) for more information. +??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.tls`" + + Determines whether to use TLS when dialing with the backend. ```yaml - traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100 + traefik.tcp.services.mytcpservice.loadbalancer.server.tls=true ``` ??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`" @@ -434,6 +434,15 @@ You can declare TCP Routers and/or Services using labels. traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version=1 ``` +??? info "`traefik.tcp.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_2) for more information. + + ```yaml + traefik.tcp.services.<service_name>.loadbalancer.serverstransport=foobar@file + ``` + ### UDP You can declare UDP Routers and/or Services using tags. diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index f39ef599ef7f57a350cb868dddd6e021d185eb9a..c25070808ebed68e1c8db63e5dccb0b051867f55 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -107,7 +107,7 @@ The Kubernetes Ingress Controller, The Custom Resource Way. ``` ```yaml tab="IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: myingressroute @@ -125,7 +125,7 @@ The Kubernetes Ingress Controller, The Custom Resource Way. port: 80 --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: ingressroute.tcp @@ -141,7 +141,7 @@ The Kubernetes Ingress Controller, The Custom Resource Way. port: 8080 --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: ingressroute.udp @@ -295,17 +295,18 @@ The Kubernetes Ingress Controller, The Custom Resource Way. You can find an excerpt of the available custom resources in the table below: -| Kind | Purpose | Concept Behind | -|--------------------------------------------|--------------------------------------------------------------------|----------------------------------------------------------------| -| [IngressRoute](#kind-ingressroute) | HTTP Routing | [HTTP router](../routers/index.md#configuring-http-routers) | -| [Middleware](#kind-middleware) | Tweaks the HTTP requests before they are sent to your service | [HTTP Middlewares](../../middlewares/http/overview.md) | -| [TraefikService](#kind-traefikservice) | Abstraction for HTTP loadbalancing/mirroring | [HTTP service](../services/index.md#configuring-http-services) | -| [IngressRouteTCP](#kind-ingressroutetcp) | TCP Routing | [TCP router](../routers/index.md#configuring-tcp-routers) | -| [MiddlewareTCP](#kind-middlewaretcp) | Tweaks the TCP requests before they are sent to your service | [TCP Middlewares](../../middlewares/tcp/overview.md) | -| [IngressRouteUDP](#kind-ingressrouteudp) | UDP Routing | [UDP router](../routers/index.md#configuring-udp-routers) | -| [TLSOptions](#kind-tlsoption) | Allows to configure some parameters of the TLS connection | [TLSOptions](../../https/tls.md#tls-options) | -| [TLSStores](#kind-tlsstore) | Allows to configure the default TLS store | [TLSStores](../../https/tls.md#certificates-stores) | -| [ServersTransport](#kind-serverstransport) | Allows to configure the transport between Traefik and the backends | [ServersTransport](../../services/#serverstransport_1) | +| Kind | Purpose | Concept Behind | +|--------------------------------------------------|--------------------------------------------------------------------|----------------------------------------------------------------| +| [IngressRoute](#kind-ingressroute) | HTTP Routing | [HTTP router](../routers/index.md#configuring-http-routers) | +| [Middleware](#kind-middleware) | Tweaks the HTTP requests before they are sent to your service | [HTTP Middlewares](../../middlewares/http/overview.md) | +| [TraefikService](#kind-traefikservice) | Abstraction for HTTP loadbalancing/mirroring | [HTTP service](../services/index.md#configuring-http-services) | +| [IngressRouteTCP](#kind-ingressroutetcp) | TCP Routing | [TCP router](../routers/index.md#configuring-tcp-routers) | +| [MiddlewareTCP](#kind-middlewaretcp) | Tweaks the TCP requests before they are sent to your service | [TCP Middlewares](../../middlewares/tcp/overview.md) | +| [IngressRouteUDP](#kind-ingressrouteudp) | UDP Routing | [UDP router](../routers/index.md#configuring-udp-routers) | +| [TLSOptions](#kind-tlsoption) | Allows to configure some parameters of the TLS connection | [TLSOptions](../../https/tls.md#tls-options) | +| [TLSStores](#kind-tlsstore) | Allows to configure the default TLS store | [TLSStores](../../https/tls.md#certificates-stores) | +| [ServersTransport](#kind-serverstransport) | Allows to configure the transport between Traefik and the backends | [ServersTransport](../../services/#serverstransport_1) | +| [ServersTransportTCP](#kind-serverstransporttcp) | Allows to configure the transport between Traefik and the backends | [TCP ServersTransport](../../services/#serverstransport_3) | ### Kind: `IngressRoute` @@ -316,7 +317,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne !!! info "IngressRoute Attributes" ```yaml - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: foo @@ -349,15 +350,16 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne sameSite: none strategy: RoundRobin weight: 10 - tls: # [11] - secretName: supersecret # [12] - options: # [13] - name: opt # [14] - namespace: default # [15] - certResolver: foo # [16] - domains: # [17] - - main: example.net # [18] - sans: # [19] + nativeLB: true # [11] + tls: # [12] + secretName: supersecret # [13] + options: # [14] + name: opt # [15] + namespace: default # [16] + certResolver: foo # [17] + domains: # [18] + - main: example.net # [19] + sans: # [20] - a.example.net - b.example.net ``` @@ -374,21 +376,22 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne | [8] | `routes[n].services` | List of any combination of [TraefikService](#kind-traefikservice) and reference to a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) (See below for `ExternalName Service` setup) | | [9] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. | | [10] | `services[n].serversTransport` | Defines the reference to a [ServersTransport](#kind-serverstransport). The ServersTransport namespace is assumed to be the [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) namespace (see [ServersTransport reference](#serverstransport-reference)). | -| [11] | `tls` | Defines [TLS](../routers/index.md#tls) certificate configuration | -| [12] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) | -| [13] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) | -| [14] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name | -| [15] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace | -| [16] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver) | -| [17] | `tls.domains` | List of [domains](../routers/index.md#domains) | -| [18] | `domains[n].main` | Defines the main domain name | -| [19] | `domains[n].sans` | List of SANs (alternative domains) | +| [11] | `services[n].nativeLB` | Controls, when creating the load-balancer, whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. | +| [12] | `tls` | Defines [TLS](../routers/index.md#tls) certificate configuration | +| [13] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) | +| [14] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) | +| [15] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name | +| [16] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace | +| [17] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver) | +| [18] | `tls.domains` | List of [domains](../routers/index.md#domains) | +| [19] | `domains[n].main` | Defines the main domain name | +| [20] | `domains[n].sans` | List of SANs (alternative domains) | ??? example "Declaring an IngressRoute" ```yaml tab="IngressRoute" # All resources definition must be declared - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test-name @@ -435,7 +438,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne ```yaml tab="Middlewares" # All resources definition must be declared # Prefixing with /foo - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: middleware1 @@ -446,7 +449,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne ``` ```yaml tab="TLSOption" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: opt @@ -492,7 +495,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne ```yaml tab="IngressRoute" --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route @@ -522,7 +525,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne ```yaml tab="ExternalName Service" --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route @@ -553,7 +556,7 @@ Register the `IngressRoute` [kind](../../reference/dynamic-configuration/kuberne ```yaml tab="Both sides" --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route @@ -590,7 +593,7 @@ More information in the dedicated server [load balancing](../services/index.md#l !!! info "Declaring and using Kubernetes Service Load Balancing" ```yaml tab="IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutebar @@ -639,6 +642,47 @@ More information in the dedicated server [load balancing](../services/index.md#l task: app2 ``` +!!! important "Kubernetes Service Native Load-Balancing" + + To avoid creating the server load-balancer with the pods IPs and use Kubernetes Service clusterIP directly, + one should set the service `NativeLB` option to true. + Please note that, by default, Traefik reuses the established connections to the backends for performance purposes. This can prevent the requests load balancing between the replicas from behaving as one would expect when the option is set. + By default, `NativeLB` is false. + + ??? example "Example" + + ```yaml + --- + apiVersion: traefik.io/v1alpha1 + kind: IngressRoute + metadata: + name: test.route + namespace: default + + spec: + entryPoints: + - foo + + routes: + - match: Host(`example.net`) + kind: Rule + services: + - name: svc + port: 80 + # Here, nativeLB instructs to build the servers load balancer with the Kubernetes Service clusterIP only. + nativeLB: true + + --- + apiVersion: v1 + kind: Service + metadata: + name: svc + namespace: default + spec: + type: ClusterIP + ... + ``` + ### Kind: `Middleware` `Middleware` is the CRD implementation of a [Traefik middleware](../../middlewares/http/overview.md). @@ -648,7 +692,7 @@ Register the `Middleware` [kind](../../reference/dynamic-configuration/kubernete ??? "Declaring and Referencing a Middleware" ```yaml tab="Middleware" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: stripprefix @@ -661,7 +705,7 @@ Register the `Middleware` [kind](../../reference/dynamic-configuration/kubernete ``` ```yaml tab="IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutebar @@ -719,7 +763,7 @@ More information in the dedicated [Weighted Round Robin](../services/index.md#we ??? "Declaring and Using Weighted Round Robin" ```yaml tab="IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutebar @@ -738,7 +782,7 @@ More information in the dedicated [Weighted Round Robin](../services/index.md#we ``` ```yaml tab="Weighted Round Robin" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 @@ -758,7 +802,7 @@ More information in the dedicated [Weighted Round Robin](../services/index.md#we weight: 1 --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr2 @@ -826,7 +870,7 @@ More information in the dedicated [mirroring](../services/index.md#mirroring-ser ??? "Declaring and Using Mirroring" ```yaml tab="IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutebar @@ -846,7 +890,7 @@ More information in the dedicated [mirroring](../services/index.md#mirroring-ser ```yaml tab="Mirroring k8s Service" # Mirroring from a k8s Service - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror1 @@ -867,7 +911,7 @@ More information in the dedicated [mirroring](../services/index.md#mirroring-ser ```yaml tab="Mirroring Traefik Service" # Mirroring from a Traefik Service - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror1 @@ -936,7 +980,7 @@ and there is a second level because each whoami service is a `replicaset` and is ??? "Stickiness on two load-balancing levels" ```yaml tab="IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutebar @@ -955,7 +999,7 @@ and there is a second level because each whoami service is a `replicaset` and is ``` ```yaml tab="Weighted Round Robin" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 @@ -1082,71 +1126,73 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube !!! info "IngressRouteTCP Attributes" ```yaml - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: ingressroutetcpfoo spec: - entryPoints: # [1] + entryPoints: # [1] - footcp - routes: # [2] - - match: HostSNI(`*`) # [3] - priority: 10 # [4] + routes: # [2] + - match: HostSNI(`*`) # [3] + priority: 10 # [4] middlewares: - - name: middleware1 # [5] - namespace: default # [6] - services: # [7] - - name: foo # [8] - port: 8080 # [9] - weight: 10 # [10] - terminationDelay: 400 # [11] - proxyProtocol: # [12] - version: 1 # [13] - tls: # [14] - secretName: supersecret # [15] - options: # [16] - name: opt # [17] - namespace: default # [18] - certResolver: foo # [19] - domains: # [20] - - main: example.net # [21] - sans: # [22] + - name: middleware1 # [5] + namespace: default # [6] + services: # [7] + - name: foo # [8] + port: 8080 # [9] + weight: 10 # [10] + proxyProtocol: # [11] + version: 1 # [12] + serversTransport: transport # [13] + nativeLB: true # [14] + tls: # [15] + secretName: supersecret # [16] + options: # [17] + name: opt # [18] + namespace: default # [19] + certResolver: foo # [20] + domains: # [21] + - main: example.net # [22] + sans: # [23] - a.example.net - b.example.net - passthrough: false # [23] + passthrough: false # [24] ``` -| Ref | Attribute | Purpose | -|------|--------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [1] | `entryPoints` | List of [entrypoints](../routers/index.md#entrypoints_1) names | -| [2] | `routes` | List of routes | -| [3] | `routes[n].match` | Defines the [rule](../routers/index.md#rule_1) of the underlying router | -| [4] | `routes[n].priority` | Defines the [priority](../routers/index.md#priority_1) to disambiguate rules of the same length, for route matching | -| [5] | `middlewares[n].name` | Defines the [MiddlewareTCP](#kind-middlewaretcp) name | -| [6] | `middlewares[n].namespace` | Defines the [MiddlewareTCP](#kind-middlewaretcp) namespace | -| [7] | `routes[n].services` | List of [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) definitions (See below for `ExternalName Service` setup) | -| [8] | `services[n].name` | Defines the name of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) | -| [9] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. | -| [10] | `services[n].weight` | Defines the weight to apply to the server load balancing | -| [11] | `services[n].terminationDelay` | corresponds to the deadline that the proxy sets, after one of its connected peers indicates it has closed the writing capability of its connection, to close the reading capability as well, hence fully terminating the connection. It is a duration in milliseconds, defaulting to 100. A negative value means an infinite deadline (i.e. the reading capability is never closed). | -| [12] | `proxyProtocol` | Defines the [PROXY protocol](../services/index.md#proxy-protocol) configuration | -| [13] | `version` | Defines the [PROXY protocol](../services/index.md#proxy-protocol) version | -| [14] | `tls` | Defines [TLS](../routers/index.md#tls_1) certificate configuration | -| [15] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) | -| [16] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) | -| [17] | `options.name` | Defines the [TLSOption](#kind-tlsoption) name | -| [18] | `options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace | -| [19] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver_1) | -| [20] | `tls.domains` | List of [domains](../routers/index.md#domains_1) | -| [21] | `domains[n].main` | Defines the main domain name | -| [22] | `domains[n].sans` | List of SANs (alternative domains) | -| [23] | `tls.passthrough` | If `true`, delegates the TLS termination to the backend | +| Ref | Attribute | Purpose | +|------|-------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [1] | `entryPoints` | List of [entrypoints](../routers/index.md#entrypoints_1) names | +| [2] | `routes` | List of routes | +| [3] | `routes[n].match` | Defines the [rule](../routers/index.md#rule_1) of the underlying router | +| [4] | `routes[n].priority` | Defines the [priority](../routers/index.md#priority_1) to disambiguate rules of the same length, for route matching | +| [5] | `middlewares[n].name` | Defines the [MiddlewareTCP](#kind-middlewaretcp) name | +| [6] | `middlewares[n].namespace` | Defines the [MiddlewareTCP](#kind-middlewaretcp) namespace | +| [7] | `routes[n].services` | List of [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) definitions (See below for `ExternalName Service` setup) | +| [8] | `services[n].name` | Defines the name of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) | +| [9] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. | +| [10] | `services[n].weight` | Defines the weight to apply to the server load balancing | +| [11] | `services[n].proxyProtocol` | Defines the [PROXY protocol](../services/index.md#proxy-protocol) configuration | +| [12] | `services[n].proxyProtocol.version` | Defines the [PROXY protocol](../services/index.md#proxy-protocol) version | +| [13] | `services[n].serversTransport` | Defines the reference to a [ServersTransportTCP](#kind-serverstransporttcp). The ServersTransport namespace is assumed to be the [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) namespace (see [ServersTransport reference](#serverstransport-reference)). | +| [14] | `services[n].nativeLB` | Controls, when creating the load-balancer, whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. | +| [15] | `tls` | Defines [TLS](../routers/index.md#tls_1) certificate configuration | +| [16] | `tls.secretName` | Defines the [secret](https://kubernetes.io/docs/concepts/configuration/secret/) name used to store the certificate (in the `IngressRoute` namespace) | +| [17] | `tls.options` | Defines the reference to a [TLSOption](#kind-tlsoption) | +| [18] | `tls.options.name` | Defines the [TLSOption](#kind-tlsoption) name | +| [19] | `tls.options.namespace` | Defines the [TLSOption](#kind-tlsoption) namespace | +| [20] | `tls.certResolver` | Defines the reference to a [CertResolver](../routers/index.md#certresolver_1) | +| [21] | `tls.domains` | List of [domains](../routers/index.md#domains_1) | +| [22] | `tls.domains[n].main` | Defines the main domain name | +| [23] | `tls.domains[n].sans` | List of SANs (alternative domains) | +| [24] | `tls.passthrough` | If `true`, delegates the TLS termination to the backend | ??? example "Declaring an IngressRouteTCP" ```yaml tab="IngressRouteTCP" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: ingressroutetcpfoo @@ -1161,11 +1207,9 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube services: - name: foo port: 8080 - terminationDelay: 400 weight: 10 - name: bar port: 8081 - terminationDelay: 500 weight: 10 tls: certResolver: foo @@ -1182,7 +1226,7 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube ``` ```yaml tab="TLSOption" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: opt @@ -1217,7 +1261,7 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube ```yaml tab="Only on IngressRouteTCP" --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route @@ -1246,7 +1290,7 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube ```yaml tab="On both sides" --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route @@ -1275,6 +1319,45 @@ Register the `IngressRouteTCP` [kind](../../reference/dynamic-configuration/kube - port: 80 ``` +!!! important "Kubernetes Service Native Load-Balancing" + + To avoid creating the server load-balancer with the pods IPs and use Kubernetes Service clusterIP directly, + one should set the TCP service `NativeLB` option to true. + By default, `NativeLB` is false. + + ??? example "Examples" + + ```yaml + --- + apiVersion: traefik.io/v1alpha1 + kind: IngressRouteTCP + metadata: + name: test.route + namespace: default + + spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`*`) + services: + - name: svc + port: 80 + # Here, nativeLB instructs to build the servers load balancer with the Kubernetes Service clusterIP only. + nativeLB: true + + --- + apiVersion: v1 + kind: Service + metadata: + name: svc + namespace: default + spec: + type: ClusterIP + ... + ``` + ### Kind: `MiddlewareTCP` `MiddlewareTCP` is the CRD implementation of a [Traefik TCP middleware](../../middlewares/tcp/overview.md). @@ -1284,7 +1367,7 @@ Register the `MiddlewareTCP` [kind](../../reference/dynamic-configuration/kubern ??? "Declaring and Referencing a MiddlewareTCP " ```yaml tab="Middleware" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: ipallowlist @@ -1296,7 +1379,7 @@ Register the `MiddlewareTCP` [kind](../../reference/dynamic-configuration/kubern ``` ```yaml tab="IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutebar @@ -1335,7 +1418,7 @@ Register the `IngressRouteUDP` [kind](../../reference/dynamic-configuration/kube !!! info "IngressRouteUDP Attributes" ```yaml - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: ingressrouteudpfoo @@ -1348,21 +1431,23 @@ Register the `IngressRouteUDP` [kind](../../reference/dynamic-configuration/kube - name: foo # [4] port: 8080 # [5] weight: 10 # [6] + nativeLB: true # [7] ``` -| Ref | Attribute | Purpose | -|------|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [1] | `entryPoints` | List of [entrypoints](../routers/index.md#entrypoints_1) names | -| [2] | `routes` | List of routes | -| [3] | `routes[n].services` | List of [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) definitions (See below for `ExternalName Service` setup) | -| [4] | `services[n].name` | Defines the name of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) | -| [6] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. | -| [7] | `services[n].weight` | Defines the weight to apply to the server load balancing | +| Ref | Attribute | Purpose | +|-----|-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| +| [1] | `entryPoints` | List of [entrypoints](../routers/index.md#entrypoints_1) names | +| [2] | `routes` | List of routes | +| [3] | `routes[n].services` | List of [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) definitions (See below for `ExternalName Service` setup) | +| [4] | `services[n].name` | Defines the name of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) | +| [5] | `services[n].port` | Defines the port of a [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/). This can be a reference to a named port. | +| [6] | `services[n].weight` | Defines the weight to apply to the server load balancing | +| [7] | `services[n].nativeLB` | Controls, when creating the load-balancer, whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. | ??? example "Declaring an IngressRouteUDP" ```yaml - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: ingressrouteudpfoo @@ -1394,7 +1479,7 @@ Register the `IngressRouteUDP` [kind](../../reference/dynamic-configuration/kube ```yaml tab="IngressRouteUDP" --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route @@ -1422,7 +1507,7 @@ Register the `IngressRouteUDP` [kind](../../reference/dynamic-configuration/kube ```yaml tab="ExternalName Service" --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route @@ -1451,7 +1536,7 @@ Register the `IngressRouteUDP` [kind](../../reference/dynamic-configuration/kube ```yaml tab="Both sides" --- - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route @@ -1479,6 +1564,44 @@ Register the `IngressRouteUDP` [kind](../../reference/dynamic-configuration/kube - port: 80 ``` +!!! important "Kubernetes Service Native Load-Balancing" + + To avoid creating the server load-balancer with the pods IPs and use Kubernetes Service clusterIP directly, + one should set the UDP service `NativeLB` option to true. + By default, `NativeLB` is false. + + ??? example "Example" + + ```yaml + --- + apiVersion: traefik.io/v1alpha1 + kind: IngressRouteUDP + metadata: + name: test.route + namespace: default + + spec: + entryPoints: + - foo + + routes: + - services: + - name: svc + port: 80 + # Here, nativeLB instructs to build the servers load balancer with the Kubernetes Service clusterIP only. + nativeLB: true + + --- + apiVersion: v1 + kind: Service + metadata: + name: svc + namespace: default + spec: + type: ClusterIP + ... + ``` + ### Kind: `TLSOption` `TLSOption` is the CRD implementation of a [Traefik "TLS Option"](../../https/tls.md#tls-options). @@ -1489,7 +1612,7 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre !!! info "TLSOption Attributes" ```yaml tab="TLSOption" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: mytlsoption # [1] @@ -1534,7 +1657,7 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre ??? example "Declaring and referencing a TLSOption" ```yaml tab="TLSOption" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: mytlsoption @@ -1554,7 +1677,7 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre ``` ```yaml tab="IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutebar @@ -1609,22 +1732,22 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre `TLSStore` is the CRD implementation of a [Traefik "TLS Store"](../../https/tls.md#certificates-stores). -Register the `TLSStore` kind in the Kubernetes cluster before creating `TLSStore` objects -or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`IngressRouteTCP`](#kind-ingressroutetcp) objects. +Register the `TLSStore` kind in the Kubernetes cluster before creating `TLSStore` objects. !!! important "Default TLS Store" Traefik currently only uses the [TLS Store named "default"](../../https/tls.md#certificates-stores). + This _default_ `TLSStore` should be in a namespace discoverable by Traefik. Since it is used by default on [`IngressRoute`](#kind-ingressroute) and [`IngressRouteTCP`](#kind-ingressroutetcp) objects, there never is a need to actually reference it. This means that you cannot have two stores that are named default in different Kubernetes namespaces. - For the time being, please only configure one TLSStore named default. + As a consequence, with respect to TLS stores, the only change that makes sense (and only if needed) is to configure the default TLSStore. !!! info "TLSStore Attributes" ```yaml tab="TLSStore" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TLSStore metadata: name: default - namespace: default + spec: certificates: # [1] - secretName: foo @@ -1641,35 +1764,32 @@ or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`Ingres ??? example "Declaring and referencing a TLSStore" ```yaml tab="TLSStore" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: TLSStore metadata: name: default - namespace: default - + spec: defaultCertificate: secretName: supersecret ``` ```yaml tab="IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutebar spec: entryPoints: - - web + - websecure routes: - match: Host(`example.com`) && PathPrefix(`/stripit`) kind: Rule services: - name: whoami port: 80 - tls: - store: - name: default + tls: {} ``` ```yaml tab="Secret" @@ -1689,33 +1809,38 @@ or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`Ingres !!! important "Default serversTransport" If no `serversTransport` is specified, the `default@internal` will be used. - The `default@internal` serversTransport is created from the [static configuration](../overview.md#transport-configuration). + The `default@internal` serversTransport is created from the [static configuration](../overview.md#http-servers-transports). !!! info "ServersTransport Attributes" ```yaml tab="ServersTransport" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - serverName: foobar # [1] - insecureSkipVerify: true # [2] - rootCAsSecrets: # [3] + serverName: foobar # [1] + insecureSkipVerify: true # [2] + rootCAsSecrets: # [3] - foobar - foobar - certificatesSecrets: # [4] + certificatesSecrets: # [4] - foobar - foobar - maxIdleConnsPerHost: 1 # [5] - forwardingTimeouts: # [6] - dialTimeout: 42s # [7] - responseHeaderTimeout: 42s # [8] - idleConnTimeout: 42s # [9] - peerCertURI: foobar # [10] - disableHTTP2: true # [11] + maxIdleConnsPerHost: 1 # [5] + forwardingTimeouts: # [6] + dialTimeout: 42s # [7] + responseHeaderTimeout: 42s # [8] + idleConnTimeout: 42s # [9] + peerCertURI: foobar # [10] + disableHTTP2: true # [11] + spiffe: # [12] + ids: # [13] + - spiffe://trust-domain/id1 + - spiffe://trust-domain/id2 + trustDomain: "spiffe://trust-domain" # [14] ``` | Ref | Attribute | Purpose | @@ -1731,6 +1856,9 @@ or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`Ingres | [9] | `idleConnTimeout` | The maximum amount of time an idle (keep-alive) connection will remain idle before closing itself. If zero, no timeout exists. | | [10] | `peerCertURI` | URI used to match against SAN URIs during the server's certificate verification. | | [11] | `disableHTTP2` | Disables HTTP/2 for connections with servers. | +| [12] | `spiffe` | The spiffe configuration. | +| [13] | `ids` | Defines the allowed SPIFFE IDs (takes precedence over the SPIFFE TrustDomain). | +| [14] | `trustDomain` | Defines the allowed SPIFFE trust domain. | !!! info "CA Secret" @@ -1739,7 +1867,7 @@ or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`Ingres ??? example "Declaring and referencing a ServersTransport" ```yaml tab="ServersTransport" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport @@ -1751,7 +1879,7 @@ or referencing TLS stores in the [`IngressRoute`](#kind-ingressroute) / [`Ingres ``` ```yaml tab="IngressRoute" - apiVersion: traefik.containo.us/v1alpha1 + apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: testroute @@ -1775,10 +1903,110 @@ By default, the referenced ServersTransport CRD must be defined in the same [Kub To reference a ServersTransport CRD from another namespace, the value must be of form `namespace-name@kubernetescrd`, -and the [cross-namespace](../../../providers/kubernetes-crd/#allowcrossnamespace) option must be enabled. +and the [allowCrossNamespace](../../../providers/kubernetes-crd/#allowcrossnamespace) option must be enabled. If the ServersTransport CRD is defined in another provider the cross-provider format `name@provider` should be used. +### Kind: `ServersTransportTCP` + +`ServersTransportTCP` is the CRD implementation of a [ServersTransportTCP](../services/index.md#serverstransport_2). + +!!! important "Default serversTransportTCP" +If no `serversTransportTCP` is specified, the `default@internal` will be used. +The `default@internal` serversTransportTCP is created from the [static configuration](../overview.md#tcp-servers-transports). + +!!! info "ServersTransportTCP Attributes" + + ```yaml tab="ServersTransportTCP" + apiVersion: traefik.io/v1alpha1 + kind: ServersTransportTCP + metadata: + name: mytransport + namespace: default + + spec: + dialTimeout: 42s # [1] + dialKeepAlive: 42s # [2] + terminationDelay: 42s # [3] + tls: # [4] + serverName: foobar # [5] + insecureSkipVerify: true # [6] + peerCertURI: foobar # [7] + rootCAsSecrets: # [8] + - foobar + - foobar + certificatesSecrets: # [9] + - foobar + - foobar + spiffe: # [10] + ids: # [11] + - spiffe://trust-domain/id1 + - spiffe://trust-domain/id2 + trustDomain: "spiffe://trust-domain" # [12] + ``` + +| Ref | Attribute | Purpose | +|------|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [1] | `dialTimeout` | The amount of time to wait until a connection to a server can be established. If zero, no timeout exists. | +| [2] | `dialKeepAlive` | The interval between keep-alive probes for an active network connection. If zero, keep-alive probes are sent with a default value (currently 15 seconds), if supported by the protocol and operating system. Network protocols or operating systems that do not support keep-alives ignore this field. If negative, keep-alive probes are disabled. | +| [3] | `terminationDelay` | Defines the delay to wait before fully terminating the connection, after one connected peer has closed its writing capability. | +| [4] | `tls` | The TLS configuration. | +| [5] | `serverName` | ServerName used to contact the server. | +| [6] | `insecureSkipVerify` | Controls whether the server's certificate chain and host name is verified. | +| [7] | `peerCertURI` | URI used to match against SAN URIs during the server's certificate verification. | +| [8] | `rootCAsSecrets` | Defines the set of root certificate authorities to use when verifying server certificates. The secret must contain a certificate under either a tls.ca or a ca.crt key. | +| [9] | `certificatesSecrets` | Certificates to present to the server for mTLS. | +| [10] | `spiffe` | The SPIFFE configuration. | +| [11] | `ids` | Defines the allowed SPIFFE IDs (takes precedence over the SPIFFE TrustDomain). | +| [12] | `trustDomain` | Defines the allowed SPIFFE trust domain. | + +!!! info "CA Secret" + + The CA secret must contain a base64 encoded certificate under either a `tls.ca` or a `ca.crt` key. + +??? example "Declaring and referencing a ServersTransportTCP" + + ```yaml tab="ServersTransportTCP" + apiVersion: traefik.io/v1alpha1 + kind: ServersTransportTCP + metadata: + name: mytransport + namespace: default + + spec: + tls: + serverName: example.org + insecureSkipVerify: true + ``` + + ```yaml tab="IngressRouteTCP" + apiVersion: traefik.io/v1alpha1 + kind: IngressRouteTCP + metadata: + name: testroute + namespace: default + + spec: + entryPoints: + - tcpep + routes: + - match: HostSNI(`bar`) + services: + - name: whoamitcp + port: 8080 + serversTransport: mytransport + ``` + +#### ServersTransportTCP reference + +By default, the referenced ServersTransportTCP CRD must be defined in the same [Kubernetes service](https://kubernetes.io/docs/concepts/services-networking/service/) namespace. + +To reference a ServersTransportTCP CRD from another namespace, +the value must be of form `namespace-name@kubernetescrd`, +and the [allowCrossNamespace](../../../providers/kubernetes-crd/#allowcrossnamespace) option must be enabled. + +If the ServersTransportTCP CRD is defined in another provider the cross-provider format `name@provider` should be used. + ## Further Also see the [full example](../../user-guides/crd-acme/index.md) with Let's Encrypt. diff --git a/docs/content/routing/providers/kubernetes-gateway.md b/docs/content/routing/providers/kubernetes-gateway.md index f67f488fd99fb726c67ddf15220e94b5a911cc08..6c15acb4f1977bd424aedfa74296dee8d4fe24e0 100644 --- a/docs/content/routing/providers/kubernetes-gateway.md +++ b/docs/content/routing/providers/kubernetes-gateway.md @@ -39,13 +39,13 @@ The Kubernetes Gateway API, The Experimental Way. {: .subtitle } You can find an excerpt of the supported Kubernetes Gateway API resources in the table below: -| Kind | Purpose | Concept Behind | -|------------------------------------|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------| -| [GatewayClass](#kind-gatewayclass) | Defines a set of Gateways that share a common configuration and behaviour | [GatewayClass](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/gatewayclass) | -| [Gateway](#kind-gateway) | Describes how traffic can be translated to Services within the cluster | [Gateway](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/gateway) | -| [HTTPRoute](#kind-httproute) | HTTP rules for mapping requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/httproute) | -| [TCPRoute](#kind-tcproute) | Allows mapping TCP requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/v1alpha2/guides/tcp/)| -| [TLSRoute](#kind-tlsroute) | Allows mapping TLS requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/v1alpha2/guides/tls/)| +| Kind | Purpose | Concept Behind | +|------------------------------------|---------------------------------------------------------------------------|---------------------------------------------------------------------------------| +| [GatewayClass](#kind-gatewayclass) | Defines a set of Gateways that share a common configuration and behaviour | [GatewayClass](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/gatewayclass) | +| [Gateway](#kind-gateway) | Describes how traffic can be translated to Services within the cluster | [Gateway](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/gateway) | +| [HTTPRoute](#kind-httproute) | HTTP rules for mapping requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/v1alpha2/api-types/httproute) | +| [TCPRoute](#kind-tcproute) | Allows mapping TCP requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/v1alpha2/guides/tcp/) | +| [TLSRoute](#kind-tlsroute) | Allows mapping TLS requests from a Gateway to Kubernetes Services | [Route](https://gateway-api.sigs.k8s.io/v1alpha2/guides/tls/) | ### Kind: `GatewayClass` @@ -238,7 +238,7 @@ Kubernetes cluster before creating `HTTPRoute` objects. weight: 1 # [16] port: 8080 # [17] - name: api@internal - group: traefik.containo.us # [18] + group: traefik.io # [18] kind: TraefikService # [19] ``` @@ -261,7 +261,7 @@ Kubernetes cluster before creating `HTTPRoute` objects. | [15] | `name` | The name of the referent service. | | [16] | `weight` | The proportion of traffic forwarded to a targetRef, computed as weight/(sum of all weights in targetRefs). | | [17] | `port` | The port of the referent service. | -| [18] | `group` | Group is the group of the referent. Only `traefik.containo.us` and `gateway.networking.k8s.io` values are supported. | +| [18] | `group` | Group is the group of the referent. Only `traefik.io` and `gateway.networking.k8s.io` values are supported. | | [19] | `kind` | Kind is kind of the referent. Only `TraefikService` and `Service` values are supported. | ### Kind: `TCPRoute` @@ -290,23 +290,23 @@ Kubernetes cluster before creating `TCPRoute` objects. weight: 1 # [8] port: 8080 # [9] - name: api@internal - group: traefik.containo.us # [10] + group: traefik.io # [10] kind: TraefikService # [11] ``` -| Ref | Attribute | Description | -|------|---------------|----------------------------------------------------------------------------------------------------------------------| -| [1] | `parentRefs` | References the resources (usually Gateways) that a Route wants to be attached to. | -| [2] | `name` | Name of the referent. | -| [3] | `namespace` | Namespace of the referent. When unspecified (or empty string), this refers to the local namespace of the Route. | -| [4] | `sectionName` | Name of a section within the target resource (the Listener name). | -| [5] | `rules` | Rules are a list of TCP matchers and actions. | -| [6] | `backendRefs` | Defines the backend(s) where matching requests should be sent. | -| [7] | `name` | The name of the referent service. | -| [8] | `weight` | The proportion of traffic forwarded to a targetRef, computed as weight/(sum of all weights in targetRefs). | -| [9] | `port` | The port of the referent service. | -| [10] | `group` | Group is the group of the referent. Only `traefik.containo.us` and `gateway.networking.k8s.io` values are supported. | -| [11] | `kind` | Kind is kind of the referent. Only `TraefikService` and `Service` values are supported. | +| Ref | Attribute | Description | +|------|---------------|-----------------------------------------------------------------------------------------------------------------| +| [1] | `parentRefs` | References the resources (usually Gateways) that a Route wants to be attached to. | +| [2] | `name` | Name of the referent. | +| [3] | `namespace` | Namespace of the referent. When unspecified (or empty string), this refers to the local namespace of the Route. | +| [4] | `sectionName` | Name of a section within the target resource (the Listener name). | +| [5] | `rules` | Rules are a list of TCP matchers and actions. | +| [6] | `backendRefs` | Defines the backend(s) where matching requests should be sent. | +| [7] | `name` | The name of the referent service. | +| [8] | `weight` | The proportion of traffic forwarded to a targetRef, computed as weight/(sum of all weights in targetRefs). | +| [9] | `port` | The port of the referent service. | +| [10] | `group` | Group is the group of the referent. Only `traefik.io` and `gateway.networking.k8s.io` values are supported. | +| [11] | `kind` | Kind is kind of the referent. Only `TraefikService` and `Service` values are supported. | ### Kind: `TLSRoute` @@ -336,21 +336,21 @@ Kubernetes cluster before creating `TLSRoute` objects. weight: 1 # [9] port: 8080 # [10] - name: api@internal - group: traefik.containo.us # [11] + group: traefik.io # [11] kind: TraefikService # [12] ``` -| Ref | Attribute | Description | -|------|---------------|----------------------------------------------------------------------------------------------------------------------| -| [1] | `parentRefs` | References the resources (usually Gateways) that a Route wants to be attached to. | -| [2] | `name` | Name of the referent. | -| [3] | `namespace` | Namespace of the referent. When unspecified (or empty string), this refers to the local namespace of the Route. | -| [4] | `sectionName` | Name of a section within the target resource (the Listener name). | -| [5] | `hostnames` | Defines a set of SNI names that should match against the SNI attribute of TLS ClientHello message in TLS handshake. | -| [6] | `rules` | Rules are a list of TCP matchers and actions. | -| [7] | `backendRefs` | Defines the backend(s) where matching requests should be sent. | -| [8] | `name` | The name of the referent service. | -| [9] | `weight` | The proportion of traffic forwarded to a targetRef, computed as weight/(sum of all weights in targetRefs). | -| [10] | `port` | The port of the referent service. | -| [11] | `group` | Group is the group of the referent. Only `traefik.containo.us` and `gateway.networking.k8s.io` values are supported. | -| [12] | `kind` | Kind is kind of the referent. Only `TraefikService` and `Service` values are supported. | +| Ref | Attribute | Description | +|------|---------------|---------------------------------------------------------------------------------------------------------------------| +| [1] | `parentRefs` | References the resources (usually Gateways) that a Route wants to be attached to. | +| [2] | `name` | Name of the referent. | +| [3] | `namespace` | Namespace of the referent. When unspecified (or empty string), this refers to the local namespace of the Route. | +| [4] | `sectionName` | Name of a section within the target resource (the Listener name). | +| [5] | `hostnames` | Defines a set of SNI names that should match against the SNI attribute of TLS ClientHello message in TLS handshake. | +| [6] | `rules` | Rules are a list of TCP matchers and actions. | +| [7] | `backendRefs` | Defines the backend(s) where matching requests should be sent. | +| [8] | `name` | The name of the referent service. | +| [9] | `weight` | The proportion of traffic forwarded to a targetRef, computed as weight/(sum of all weights in targetRefs). | +| [10] | `port` | The port of the referent service. | +| [11] | `group` | Group is the group of the referent. Only `traefik.io` and `gateway.networking.k8s.io` values are supported. | +| [12] | `kind` | Kind is kind of the referent. Only `TraefikService` and `Service` values are supported. | diff --git a/docs/content/routing/providers/kubernetes-ingress.md b/docs/content/routing/providers/kubernetes-ingress.md index 5720889d8fde9087d397d8e9873708f47b096571..bb87501c4067a62d8e9e33cc3919a6d96397b54f 100644 --- a/docs/content/routing/providers/kubernetes-ingress.md +++ b/docs/content/routing/providers/kubernetes-ingress.md @@ -299,6 +299,17 @@ which in turn will create the resulting routers, services, handlers, etc. #### On Service +??? info "`traefik.ingress.kubernetes.io/service.nativelb`" + + Controls, when creating the load-balancer, whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the pods. + Please note that, by default, Traefik reuses the established connections to the backends for performance purposes. This can prevent the requests load balancing between the replicas from behaving as one would expect when the option is set. + By default, NativeLB is false. + + ```yaml + traefik.ingress.kubernetes.io/service.nativelb: "true" + ``` + ??? info "`traefik.ingress.kubernetes.io/service.serversscheme`" Overrides the default scheme. @@ -888,14 +899,24 @@ TLS certificates can be managed in Secrets objects. ### Communication Between Traefik and Pods +!!! info "Routing directly to [Kubernetes services](https://kubernetes.io/docs/concepts/services-networking/service/ "Link to Kubernetes service docs")" + + To route directly to the Kubernetes service, + one can use the `traefik.ingress.kubernetes.io/service.nativelb` annotation on the Kubernetes service. + It controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + + One alternative is to use an `ExternalName` service to forward requests to the Kubernetes service through DNS. + To do so, one must [allow external name services](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#allowexternalnameservices "Link to docs about allowing external name services"). + Traefik automatically requests endpoint information based on the service provided in the ingress spec. Although Traefik will connect directly to the endpoints (pods), it still checks the service port to see if TLS communication is required. -There are 3 ways to configure Traefik to use https to communicate with pods: +There are 3 ways to configure Traefik to use HTTPS to communicate with pods: 1. If the service port defined in the ingress spec is `443` (note that you can still use `targetPort` to use a different port on your pod). -1. If the service port defined in the ingress spec has a name that starts with https (such as `https-api`, `https-web` or just `https`). +1. If the service port defined in the ingress spec has a name that starts with `https` (such as `https-api`, `https-web` or just `https`). 1. If the service spec includes the annotation `traefik.ingress.kubernetes.io/service.serversscheme: https`. If either of those configuration options exist, then the backend communication protocol is assumed to be TLS, diff --git a/docs/content/routing/providers/kv.md b/docs/content/routing/providers/kv.md index bce4d7703d52f9fbca2ebcbda26440d158786daf..a54ef1c61b64a10b14868455c1b84adf83359053 100644 --- a/docs/content/routing/providers/kv.md +++ b/docs/content/routing/providers/kv.md @@ -406,21 +406,13 @@ You can declare TCP Routers and/or Services using KV. #### TCP Services -??? info "`traefik/tcp/services/<service_name>/loadbalancer/servers/<n>/url`" +??? info "`traefik/tcp/services/<service_name>/loadbalancer/servers/<n>/address`" See [servers](../services/index.md#servers) for more information. | Key (Path) | Value | |--------------------------------------------------------------------|------------------| | `traefik/tcp/services/mytcpservice/loadbalancer/servers/0/address` | `xx.xx.xx.xx:xx` | - -??? info "`traefik/tcp/services/<service_name>/loadbalancer/terminationdelay`" - - See [termination delay](../services/index.md#termination-delay) for more information. - - | Key (Path) | Value | - |-------------------------------------------------------------------|-------| - | `traefik/tcp/services/mytcpservice/loadbalancer/terminationdelay` | `100` | ??? info "`traefik/tcp/services/<service_name>/loadbalancer/proxyprotocol/version`" @@ -430,6 +422,15 @@ You can declare TCP Routers and/or Services using KV. |------------------------------------------------------------------------|-------| | `traefik/tcp/services/mytcpservice/loadbalancer/proxyprotocol/version` | `1` | +??? info "`traefik/tcp/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_2) for more information. + + | Key (Path) | Value | + |-----------------------------------------------------------------|---------------| + | `traefik/tcp/services/myservice/loadbalancer/serverstransport` | `foobar@file` | + ??? info "`traefik/tcp/services/<service_name>/weighted/services/<n>/name`" | Key (Path) | Value | diff --git a/docs/content/routing/providers/marathon.md b/docs/content/routing/providers/marathon.md deleted file mode 100644 index 19a8a8ddea8d31f75b2e4a8f81554e68e96530e5..0000000000000000000000000000000000000000 --- a/docs/content/routing/providers/marathon.md +++ /dev/null @@ -1,536 +0,0 @@ ---- -title: "Traefik Routing Configuration for Marathon" -description: "Traefik Proxy can be configured to use Marathon as a provider. Read the technical documentation to understand the Traefik routing configuration for Marathon." ---- - -# Traefik & Marathon - -Traefik can be configured to use Marathon as a provider. -{: .subtitle } - -See also [Marathon user guide](../../user-guides/marathon.md). - -## Routing Configuration - -!!! info "Labels" - - - Labels are case insensitive. - - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/marathon.md). - -### General - -Traefik creates, for each Marathon application, a corresponding [service](../services/index.md) and [router](../routers/index.md). - -The Service automatically gets a server per instance of the application, -and the router automatically gets a rule defined by defaultRule (if no rule for it was defined in labels). - -#### Service definition - ---8<-- "content/routing/providers/service-by-label.md" - -??? example "Automatic service assignment with labels" - - Service myservice gets automatically assigned to router myproxy. - - ```json - labels: { - "traefik.http.routers.myproxy.rule": "Host(`example.net`)", - "traefik.http.services.myservice.loadbalancer.server.port": "80" - } - ``` - -??? example "Automatic service creation and assignment with labels" - - No service specified or defined, and yet one gets automatically created. - and assigned to router myproxy. - - ```json - labels: { - "traefik.http.routers.myproxy.rule": "Host(`example.net`)" - } - ``` - -### Routers - -To update the configuration of the Router automatically attached to the application, -add labels starting with `traefik.http.routers.{router-name-of-your-choice}.` and followed by the option you want to change. - -For example, to change the routing rule, you could add the label ```"traefik.http.routers.routername.rule": "Host(`example.com`)"```. - -!!! warning "The character `@` is not authorized in the router name `<router_name>`." - -??? info "`traefik.http.routers.<router_name>.rule`" - - See [rule](../routers/index.md#rule) for more information. - - ```json - "traefik.http.routers.myrouter.rule": "Host(`example.com`)" - ``` - -??? info "`traefik.http.routers.<router_name>.entrypoints`" - - See [entry points](../routers/index.md#entrypoints) for more information. - - ```json - "traefik.http.routers.myrouter.entrypoints": "ep1,ep2" - ``` - -??? info "`traefik.http.routers.<router_name>.middlewares`" - - See [middlewares](../routers/index.md#middlewares) and [middlewares overview](../../middlewares/overview.md) for more information. - - ```json - "traefik.http.routers.myrouter.middlewares": "auth,prefix,cb" - ``` - -??? info "`traefik.http.routers.<router_name>.service`" - - See [rule](../routers/index.md#service) for more information. - - ```json - "traefik.http.routers.myrouter.service": "myservice" - ``` - -??? info "`traefik.http.routers.<router_name>.tls`" - - See [tls](../routers/index.md#tls) for more information. - - ```json - "traefik.http.routers.myrouter.tls": "true" - ``` - -??? info "`traefik.http.routers.<router_name>.tls.certresolver`" - - See [certResolver](../routers/index.md#certresolver) for more information. - - ```json - "traefik.http.routers.myrouter.tls.certresolver": "myresolver" - ``` - -??? info "`traefik.http.routers.<router_name>.tls.domains[n].main`" - - See [domains](../routers/index.md#domains) for more information. - - ```json - "traefik.http.routers.myrouter.tls.domains[0].main": "example.org" - ``` - -??? info "`traefik.http.routers.<router_name>.tls.domains[n].sans`" - - See [domains](../routers/index.md#domains) for more information. - - ```json - "traefik.http.routers.myrouter.tls.domains[0].sans": "test.example.org,dev.example.org" - ``` - -??? info "`traefik.http.routers.<router_name>.tls.options`" - - See [options](../routers/index.md#options) for more information. - - ```json - "traefik.http.routers.myrouter.tls.options": "foobar" - ``` - -??? info "`traefik.http.routers.<router_name>.priority`" - - See [priority](../routers/index.md#priority) for more information. - - ```json - "traefik.http.routers.myrouter.priority": "42" - ``` - -### Services - -To update the configuration of the Service automatically attached to the container, -add labels starting with `traefik.http.services.{service-name-of-your-choice}.`, followed by the option you want to change. - -For example, to change the passHostHeader behavior, you'd add the label `"traefik.http.services.servicename.loadbalancer.passhostheader": "false"`. - -!!! warning "The character `@` is not authorized in the service name `<service_name>`." - -??? info "`traefik.http.services.<service_name>.loadbalancer.server.port`" - - Registers a port. - Useful when the container exposes multiples ports. - - ```json - "traefik.http.services.myservice.loadbalancer.server.port": "8080" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.server.scheme`" - - Overrides the default scheme. - - ```json - "traefik.http.services.myservice.loadbalancer.server.scheme": "http" - ``` - -??? 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. - - ```json - "traefik.http.services.<service_name>.loadbalancer.serverstransport": "foobar@file" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`" - - See [pass Host header](../services/index.md#pass-host-header) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.passhostheader": "true" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.headers.X-Foo": "foobar" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.hostname": "example.org" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.interval": "10" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.path": "/foo" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.method`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.method": "foobar" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.status": "42" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.port": "42" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.scheme": "http" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.timeout": "10" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`" - - See [health check](../services/index.md#health-check) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.healthcheck.followredirects": "true" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.sticky.cookie": "true" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.sticky.cookie.httponly": "true" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.sticky.cookie.name": "foobar" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure": "true" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite": "none" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`" - - See [response forwarding](../services/index.md#response-forwarding) for more information. - - ```json - "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval": "10" - ``` - -### Middleware - -You can declare pieces of middleware using labels starting with `traefik.http.middlewares.{middleware-name-of-your-choice}.`, followed by the middleware type/options. - -For example, to declare a middleware [`redirectscheme`](../../middlewares/http/redirectscheme.md) named `my-redirect`, you'd write `"traefik.http.middlewares.my-redirect.redirectscheme.scheme": "https"`. - -More information about available middlewares in the dedicated [middlewares section](../../middlewares/overview.md). - -!!! warning "The character `@` is not authorized in the middleware name." - -??? example "Declaring and Referencing a Middleware" - - ```json - { - ... - "labels": { - "traefik.http.middlewares.my-redirect.redirectscheme.scheme": "https", - "traefik.http.routers.my-container.middlewares": "my-redirect" - } - } - ``` - -!!! warning "Conflicts in Declaration" - - If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared. - -### TCP - -You can declare TCP Routers and/or Services using labels. - -??? example "Declaring TCP Routers and Services" - - ```json - { - ... - "labels": { - "traefik.tcp.routers.my-router.rule": "HostSNI(`example.com`)", - "traefik.tcp.routers.my-router.tls": "true", - "traefik.tcp.services.my-service.loadbalancer.server.port": "4123" - } - } - ``` - -!!! warning "TCP and HTTP" - - If you declare a TCP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no TCP Router/Service is defined). - You can declare both a TCP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually). - -#### TCP Routers - -??? info "`traefik.tcp.routers.<router_name>.entrypoints`" - - See [entry points](../routers/index.md#entrypoints_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.entrypoints": "ep1,ep2" - ``` - - -??? info "`traefik.tcp.routers.<router_name>.rule`" - - See [rule](../routers/index.md#rule_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.rule": "HostSNI(`example.com`)" - ``` - -??? info "`traefik.tcp.routers.<router_name>.service`" - - See [service](../routers/index.md#services) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.service": "myservice" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls`" - - See [TLS](../routers/index.md#tls_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls": "true - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls.certresolver`" - - See [certResolver](../routers/index.md#certresolver_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls.certresolver": "myresolver" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].main`" - - See [domains](../routers/index.md#domains_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls.domains[0].main": "example.org" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].sans`" - - See [domains](../routers/index.md#domains_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls.domains[0].sans": "test.example.org,dev.example.org" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls.options`" - - See [options](../routers/index.md#options_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls.options": "mysoptions" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls.passthrough`" - - See [TLS](../routers/index.md#tls_1) for more information. - - ```json - "traefik.tcp.routers.mytcprouter.tls.passthrough": "true" - ``` - -??? info "`traefik.tcp.routers.<router_name>.priority`" - - See [priority](../routers/index.md#priority_1) for more information. - - ```json - "traefik.tcp.routers.myrouter.priority": "42" - ``` - -#### TCP Services - -??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.port`" - - Registers a port of the application. - - ```json - "traefik.tcp.services.mytcpservice.loadbalancer.server.port": "423" - ``` - -??? info "`traefik.tcp.services.<service_name>.loadbalancer.terminationdelay`" - - See [termination delay](../services/index.md#termination-delay) for more information. - - ```json - "traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay": "100" - ``` - -??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`" - - See [PROXY protocol](../services/index.md#proxy-protocol) for more information. - - ```json - "traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version": "1" - ``` - -### UDP - -You can declare UDP Routers and/or Services using labels. - -??? example "Declaring UDP Routers and Services" - - ```json - { - ... - "labels": { - "traefik.udp.routers.my-router.entrypoints": "udp", - "traefik.udp.services.my-service.loadbalancer.server.port": "4123" - } - } - ``` - -!!! warning "UDP and HTTP" - - If you declare a UDP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no UDP Router/Service is defined). - You can declare both a UDP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually). - -#### UDP Routers - -??? info "`traefik.udp.routers.<router_name>.entrypoints`" - - See [entry points](../routers/index.md#entrypoints_2) for more information. - - ```json - "traefik.udp.routers.myudprouter.entrypoints": "ep1,ep2" - ``` - -??? info "`traefik.udp.routers.<router_name>.service`" - - See [service](../routers/index.md#services_1) for more information. - - ```json - "traefik.udp.routers.myudprouter.service": "myservice" - ``` - -#### UDP Services - -??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`" - - Registers a port of the application. - - ```json - "traefik.udp.services.myudpservice.loadbalancer.server.port": "423" - ``` - -### Specific Provider Options - -#### `traefik.enable` - -```json -"traefik.enable": "true" -``` - -Setting this option controls whether Traefik exposes the application. -It overrides the value of `exposedByDefault`. - -#### `traefik.marathon.ipadressidx` - -```json -"traefik.marathon.ipadressidx": "1" -``` - -If a task has several IP addresses, this option specifies which one, in the list of available addresses, to select. diff --git a/docs/content/routing/providers/nomad.md b/docs/content/routing/providers/nomad.md index e4d24a942b0e314e36ca2d9841f3a178a7d9fe9f..b0143d09401bf546345f30194e0c4dd98061e8ae 100644 --- a/docs/content/routing/providers/nomad.md +++ b/docs/content/routing/providers/nomad.md @@ -396,12 +396,12 @@ You can declare TCP Routers and/or Services using tags. traefik.tcp.services.mytcpservice.loadbalancer.server.port=423 ``` -??? info "`traefik.tcp.services.<service_name>.loadbalancer.terminationdelay`" +??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.tls`" - See [termination delay](../services/index.md#termination-delay) for more information. + Determines whether to use TLS when dialing with the backend. ```yaml - traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100 + traefik.tcp.services.mytcpservice.loadbalancer.server.tls=true ``` ??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`" @@ -412,6 +412,15 @@ You can declare TCP Routers and/or Services using tags. traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version=1 ``` +??? info "`traefik.tcp.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_2) for more information. + + ```yaml + traefik.tcp.services.myservice.loadbalancer.serverstransport=foobar@file + ``` + ### UDP You can declare UDP Routers and/or Services using tags. diff --git a/docs/content/routing/providers/rancher.md b/docs/content/routing/providers/rancher.md deleted file mode 100644 index 7d392889eed9cdc98fa2fe8aa9f0e5466cf5ca40..0000000000000000000000000000000000000000 --- a/docs/content/routing/providers/rancher.md +++ /dev/null @@ -1,536 +0,0 @@ ---- -title: "Routing & Load Balancing Providers: Rancher" -description: "Traefik Proxy creates a corresponding service and router for each Rancher Service. Read the full documentation to learn more." ---- - -# Traefik & Rancher - -A Story of Labels, Services & Containers -{: .subtitle } - - - -Attach labels to your services and let Traefik do the rest! - -!!! important "This provider is specific to Rancher 1.x." - - Rancher 2.x requires Kubernetes and does not have a metadata endpoint of its own for Traefik to query. - As such, Rancher 2.x users should utilize the [Kubernetes provider](./kubernetes-crd.md) directly. - -## Routing Configuration - -!!! info "Labels" - - - Labels are case insensitive. - - The complete list of labels can be found in [the reference page](../../reference/dynamic-configuration/rancher.md). - -### General - -Traefik creates, for each rancher service, a corresponding [service](../services/index.md) and [router](../routers/index.md). - -The Service automatically gets a server per container in this rancher service, and the router gets a default rule attached to it, based on the service name. - -#### Service definition - ---8<-- "content/routing/providers/service-by-label.md" - -??? example "Automatic service assignment with labels" - - With labels in a compose file - - ```yaml - labels: - - "traefik.http.routers.myproxy.rule=Host(`example.net`)" - # service myservice gets automatically assigned to router myproxy - - "traefik.http.services.myservice.loadbalancer.server.port=80" - ``` - -??? example "Automatic service creation and assignment with labels" - - With labels in a compose file - - ```yaml - labels: - # no service specified or defined and yet one gets automatically created - # and assigned to router myproxy. - - "traefik.http.routers.myproxy.rule=Host(`example.net`)" - ``` - -### Routers - -To update the configuration of the Router automatically attached to the container, add labels starting with `traefik.routers.{name-of-your-choice}.` and followed by the option you want to change. - -For example, to change the rule, you could add the label ```traefik.http.routers.my-container.rule=Host(`example.com`)```. - -!!! warning "The character `@` is not authorized in the router name `<router_name>`." - -??? info "`traefik.http.routers.<router_name>.rule`" - - See [rule](../routers/index.md#rule) for more information. - - ```yaml - - "traefik.http.routers.myrouter.rule=Host(`example.com`)" - ``` - -??? info "`traefik.http.routers.<router_name>.entrypoints`" - - See [entry points](../routers/index.md#entrypoints) for more information. - - ```yaml - - "traefik.http.routers.myrouter.entrypoints=ep1,ep2" - ``` - -??? info "`traefik.http.routers.<router_name>.middlewares`" - - See [middlewares](../routers/index.md#middlewares) and [middlewares overview](../../middlewares/overview.md) for more information. - - ```yaml - - "traefik.http.routers.myrouter.middlewares=auth,prefix,cb" - ``` - -??? info "`traefik.http.routers.<router_name>.service`" - - See [rule](../routers/index.md#service) for more information. - - ```yaml - - "traefik.http.routers.myrouter.service=myservice" - ``` - -??? info "`traefik.http.routers.<router_name>.tls`" - - See [tls](../routers/index.md#tls) for more information. - - ```yaml - - "traefik.http.routers.myrouter>.tls=true" - ``` - -??? info "`traefik.http.routers.<router_name>.tls.certresolver`" - - See [certResolver](../routers/index.md#certresolver) for more information. - - ```yaml - - "traefik.http.routers.myrouter.tls.certresolver=myresolver" - ``` - -??? info "`traefik.http.routers.<router_name>.tls.domains[n].main`" - - See [domains](../routers/index.md#domains) for more information. - - ```yaml - - "traefik.http.routers.myrouter.tls.domains[0].main=example.org" - ``` - -??? info "`traefik.http.routers.<router_name>.tls.domains[n].sans`" - - See [domains](../routers/index.md#domains) for more information. - - ```yaml - - "traefik.http.routers.myrouter.tls.domains[0].sans=test.example.org,dev.example.org" - ``` - -??? info "`traefik.http.routers.<router_name>.tls.options`" - - See [options](../routers/index.md#options) for more information. - - ```yaml - - "traefik.http.routers.myrouter.tls.options=foobar" - ``` - -??? info "`traefik.http.routers.<router_name>.priority`" - - See [priority](../routers/index.md#priority) for more information. - - ```yaml - - "traefik.http.routers.myrouter.priority=42" - ``` - -### Services - -To update the configuration of the Service automatically attached to the container, -add labels starting with `traefik.http.services.{name-of-your-choice}.`, followed by the option you want to change. - -For example, to change the `passHostHeader` behavior, -you'd add the label `traefik.http.services.{name-of-your-choice}.loadbalancer.passhostheader=false`. - -!!! warning "The character `@` is not authorized in the service name `<service_name>`." - -??? info "`traefik.http.services.<service_name>.loadbalancer.server.port`" - - Registers a port. - Useful when the container exposes multiples ports. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.server.port=8080" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.server.scheme`" - - Overrides the default scheme. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.server.scheme=http" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.serverstransport`" - - Allows to reference a ServersTransport resource that is defined either with the File provider or the Kubernetes CRD one. - See [serverstransport](../services/index.md#serverstransport) for more information. - - ```yaml - - "traefik.http.services.<service_name>.loadbalancer.serverstransport=foobar@file" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.passhostheader`" - - See [pass Host header](../services/index.md#pass-host-header) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.passhostheader=true" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.headers.<header_name>`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.headers.X-Foo=foobar" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.hostname`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.hostname=example.org" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.interval`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.path`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.path=/foo" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.method`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.method=foobar" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.status`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.status=42" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.port`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.port=42" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.scheme`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.scheme=http" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.timeout`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.timeout=10" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.healthcheck.followredirects`" - - See [health check](../services/index.md#health-check) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.followredirects=true" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky.cookie=true" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.httponly`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky.cookie.httponly=true" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.name`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky.cookie.name=foobar" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.secure`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky.cookie.secure=true" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.sticky.cookie.samesite`" - - See [sticky sessions](../services/index.md#sticky-sessions) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.sticky.cookie.samesite=none" - ``` - -??? info "`traefik.http.services.<service_name>.loadbalancer.responseforwarding.flushinterval`" - - See [response forwarding](../services/index.md#response-forwarding) for more information. - - ```yaml - - "traefik.http.services.myservice.loadbalancer.responseforwarding.flushinterval=10" - ``` - -### Middleware - -You can declare pieces of middleware using labels starting with `traefik.http.middlewares.{name-of-your-choice}.`, followed by the middleware type/options. - -For example, to declare a middleware [`redirectscheme`](../../middlewares/http/redirectscheme.md) named `my-redirect`, you'd write `traefik.http.middlewares.my-redirect.redirectscheme.scheme: https`. - -More information about available middlewares in the dedicated [middlewares section](../../middlewares/overview.md). - -!!! warning "The character `@` is not authorized in the middleware name." - -??? example "Declaring and Referencing a Middleware" - - ```yaml - # ... - labels: - # Declaring a middleware - - traefik.http.middlewares.my-redirect.redirectscheme.scheme=https - # Referencing a middleware - - traefik.http.routers.my-container.middlewares=my-redirect - ``` - -!!! warning "Conflicts in Declaration" - - If you declare multiple middleware with the same name but with different parameters, the middleware fails to be declared. - -### TCP - -You can declare TCP Routers and/or Services using labels. - -??? example "Declaring TCP Routers and Services" - - ```yaml - services: - my-container: - # ... - labels: - - "traefik.tcp.routers.my-router.rule=HostSNI(`example.com`)" - - "traefik.tcp.routers.my-router.tls=true" - - "traefik.tcp.services.my-service.loadbalancer.server.port=4123" - ``` - -!!! warning "TCP and HTTP" - - If you declare a TCP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no TCP Router/Service is defined). - You can declare both a TCP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually). - -#### TCP Routers - -??? info "`traefik.tcp.routers.<router_name>.entrypoints`" - - See [entry points](../routers/index.md#entrypoints_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.entrypoints=ep1,ep2" - ``` - -??? info "`traefik.tcp.routers.<router_name>.rule`" - - See [rule](../routers/index.md#rule_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.rule=HostSNI(`example.com`)" - ``` - -??? info "`traefik.tcp.routers.<router_name>.service`" - - See [service](../routers/index.md#services) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.service=myservice" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls`" - - See [TLS](../routers/index.md#tls_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls=true" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls.certresolver`" - - See [certResolver](../routers/index.md#certresolver_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls.certresolver=myresolver" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].main`" - - See [domains](../routers/index.md#domains_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls.domains[0].main=example.org" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls.domains[n].sans`" - - See [domains](../routers/index.md#domains_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls.domains[0].sans=test.example.org,dev.example.org" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls.options`" - - See [options](../routers/index.md#options_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls.options=mysoptions" - ``` - -??? info "`traefik.tcp.routers.<router_name>.tls.passthrough`" - - See [TLS](../routers/index.md#tls_1) for more information. - - ```yaml - - "traefik.tcp.routers.mytcprouter.tls.passthrough=true" - ``` - -??? info "`traefik.tcp.routers.<router_name>.priority`" - - See [priority](../routers/index.md#priority_1) for more information. - - ```yaml - - "traefik.tcp.routers.myrouter.priority=42" - ``` - -#### TCP Services - -??? info "`traefik.tcp.services.<service_name>.loadbalancer.server.port`" - - Registers a port of the application. - - ```yaml - - "traefik.tcp.services.mytcpservice.loadbalancer.server.port=423" - ``` - -??? info "`traefik.tcp.services.<service_name>.loadbalancer.terminationdelay`" - - See [termination delay](../services/index.md#termination-delay) for more information. - - ```yaml - - "traefik.tcp.services.mytcpservice.loadbalancer.terminationdelay=100" - ``` - -??? info "`traefik.tcp.services.<service_name>.loadbalancer.proxyprotocol.version`" - - See [PROXY protocol](../services/index.md#proxy-protocol) for more information. - - ```yaml - - "traefik.tcp.services.mytcpservice.loadbalancer.proxyprotocol.version=1" - ``` - -### UDP - -You can declare UDP Routers and/or Services using labels. - -??? example "Declaring UDP Routers and Services" - - ```yaml - services: - my-container: - # ... - labels: - - "traefik.udp.routers.my-router.entrypoints=udp" - - "traefik.udp.services.my-service.loadbalancer.server.port=4123" - ``` - -!!! warning "UDP and HTTP" - - If you declare a UDP Router/Service, it will prevent Traefik from automatically creating an HTTP Router/Service (like it does by default if no UDP Router/Service is defined). - You can declare both a UDP Router/Service and an HTTP Router/Service for the same container (but you have to do so manually). - -#### UDP Routers - -??? info "`traefik.udp.routers.<router_name>.entrypoints`" - - See [entry points](../routers/index.md#entrypoints_2) for more information. - - ```yaml - - "traefik.udp.routers.myudprouter.entrypoints=ep1,ep2" - ``` - -??? info "`traefik.udp.routers.<router_name>.service`" - - See [service](../routers/index.md#services_1) for more information. - - ```yaml - - "traefik.udp.routers.myudprouter.service=myservice" - ``` - -#### UDP Services - -??? info "`traefik.udp.services.<service_name>.loadbalancer.server.port`" - - Registers a port of the application. - - ```yaml - - "traefik.udp.services.myudpservice.loadbalancer.server.port=423" - ``` - -### Specific Provider Options - -#### `traefik.enable` - -```yaml -- "traefik.enable=true" -``` - -You can tell Traefik to consider (or not) the container by setting `traefik.enable` to true or false. - -This option overrides the value of `exposedByDefault`. - -#### Port Lookup - -Traefik is capable of detecting the port to use, by following the default rancher flow. -That means, if you just expose lets say port `:1337` on the rancher ui, traefik will pick up this port and use it. diff --git a/docs/content/routing/routers/index.md b/docs/content/routing/routers/index.md index 51328317b766a00e465fb79dd1b0e780db64c52d..12bc83f609c2281a12da21bc0178f3a068d0a8b6 100644 --- a/docs/content/routing/routers/index.md +++ b/docs/content/routing/routers/index.md @@ -557,8 +557,7 @@ which is basically where the request will be passed along to. In general, a service assigned to a router should have been defined, but there are exceptions for label-based providers. -See the specific [docker](../providers/docker.md#service-definition), [rancher](../providers/rancher.md#service-definition), -or [marathon](../providers/marathon.md#service-definition) documentation. +See the specific [docker](../providers/docker.md#service-definition) documentation. !!! warning "The character `@` is not authorized in the service name." diff --git a/docs/content/routing/services/index.md b/docs/content/routing/services/index.md index 5e2766f0e5e2a11308b4491a1ebcb1947e205958..c809392f46addadebc78629e56550c6b81016876 100644 --- a/docs/content/routing/services/index.md +++ b/docs/content/routing/services/index.md @@ -473,9 +473,9 @@ By default, `passHostHeader` is true. #### ServersTransport -`serversTransport` allows to reference a [ServersTransport](./index.md#serverstransport_1) configuration for the communication between Traefik and your servers. +`serversTransport` allows to reference an [HTTP ServersTransport](./index.md#serverstransport_1) configuration for the communication between Traefik and your servers. -??? example "Specify a transport -- Using the [File Provider](../../providers/file.md)" +??? example "Specify an HTTP transport -- Using the [File Provider](../../providers/file.md)" ```yaml tab="YAML" ## Dynamic configuration @@ -494,9 +494,9 @@ By default, `passHostHeader` is true. serversTransport = "mytransport" ``` -!!! info default serversTransport +!!! info Default Servers Transport If no serversTransport is specified, the `default@internal` will be used. - The `default@internal` serversTransport is created from the [static configuration](../overview.md#transport-configuration). + The `default@internal` serversTransport is created from the [static configuration](../overview.md#http-servers-transports). #### Response Forwarding @@ -532,9 +532,9 @@ Below are the available options for the Response Forwarding mechanism: ### ServersTransport -ServersTransport allows to configure the transport between Traefik and your servers. +ServersTransport allows to configure the transport between Traefik and your HTTP servers. -#### `ServerName` +#### `serverName` _Optional_ @@ -555,17 +555,17 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - serverName: "test" + serverName: "test" ``` -#### `Certificates` +#### `certificates` _Optional_ @@ -590,14 +590,14 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - certificatesSecrets: + certificatesSecrets: - mycert --- @@ -606,9 +606,9 @@ kind: Secret metadata: name: mycert - data: - tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= - tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= ``` #### `insecureSkipVerify` @@ -632,14 +632,14 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - insecureSkipVerify: true + insecureSkipVerify: true ``` #### `rootCAs` @@ -665,14 +665,14 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - rootCAsSecrets: + rootCAsSecrets: - myca --- apiVersion: v1 @@ -680,8 +680,8 @@ kind: Secret metadata: name: myca - data: - ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= +data: + ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= ``` #### `maxIdleConnsPerHost` @@ -705,14 +705,14 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - maxIdleConnsPerHost: 7 + maxIdleConnsPerHost: 7 ``` #### `disableHTTP2` @@ -721,12 +721,6 @@ _Optional, Default=false_ `disableHTTP2` disables HTTP/2 for connections with servers. -```toml tab="File (TOML)" -## Dynamic configuration -[http.serversTransports.mytransport] - disableHTTP2 = true -``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: @@ -735,15 +729,21 @@ http: disableHTTP2: true ``` +```toml tab="File (TOML)" +## Dynamic configuration +[http.serversTransports.mytransport] + disableHTTP2 = true +``` + ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - disableHTTP2: true + disableHTTP2: true ``` #### `peerCertURI` @@ -752,12 +752,6 @@ _Optional, Default=false_ `peerCertURI` defines the URI used to match against SAN URIs during the server's certificate verification. -```toml tab="File (TOML)" -## Dynamic configuration -[http.serversTransports.mytransport] - peerCertURI = "foobar" -``` - ```yaml tab="File (YAML)" ## Dynamic configuration http: @@ -766,15 +760,21 @@ http: peerCertURI: foobar ``` +```toml tab="File (TOML)" +## Dynamic configuration +[http.serversTransports.mytransport] + peerCertURI = "foobar" +``` + ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - peerCertURI: foobar + peerCertURI: foobar ``` #### `spiffe` @@ -807,7 +807,7 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport @@ -842,7 +842,7 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport @@ -880,7 +880,7 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport @@ -916,15 +916,15 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - forwardingTimeouts: - responseHeaderTimeout: "1s" + forwardingTimeouts: + responseHeaderTimeout: "1s" ``` ##### `forwardingTimeouts.idleConnTimeout` @@ -950,15 +950,15 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - forwardingTimeouts: - idleConnTimeout: "1s" + forwardingTimeouts: + idleConnTimeout: "1s" ``` ##### `forwardingTimeouts.readIdleTimeout` @@ -988,15 +988,15 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - forwardingTimeouts: - readIdleTimeout: "1s" + forwardingTimeouts: + readIdleTimeout: "1s" ``` ##### `forwardingTimeouts.pingTimeout` @@ -1022,15 +1022,15 @@ http: ``` ```yaml tab="Kubernetes" -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport namespace: default spec: - forwardingTimeouts: - pingTimeout: "1s" + forwardingTimeouts: + pingTimeout: "1s" ``` ### Weighted Round Robin (service) @@ -1469,6 +1469,9 @@ The servers load balancer is in charge of balancing the requests between the ser #### Servers Servers declare a single instance of your program. + +#### `address` + The `address` option (IP:Port) point to a specific instance. ??? example "A Service with One Server -- Using the [File Provider](../../providers/file.md)" @@ -1491,54 +1494,74 @@ The `address` option (IP:Port) point to a specific instance. address = "xx.xx.xx.xx:xx" ``` -#### PROXY Protocol +#### `tls` -Traefik supports [PROXY Protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2 on TCP Services. -It can be enabled by setting `proxyProtocol` on the load balancer. +The `tls` determines whether to use TLS when dialing with the backend. -Below are the available options for the PROXY protocol: +??? example "A Service with One Server Using TLS -- Using the [File Provider](../../providers/file.md)" -- `version` specifies the version of the protocol to be used. Either `1` or `2`. + ```yaml tab="YAML" + ## Dynamic configuration + tcp: + services: + my-service: + loadBalancer: + servers: + - address: "xx.xx.xx.xx:xx" + tls: true + ``` -!!! info "Version" + ```toml tab="TOML" + ## Dynamic configuration + [tcp.services] + [tcp.services.my-service.loadBalancer] + [[tcp.services.my-service.loadBalancer.servers]] + address = "xx.xx.xx.xx:xx" + tls = true + ``` - Specifying a version is optional. By default the version 2 will be used. +#### ServersTransport -??? example "A Service with Proxy Protocol v1 -- Using the [File Provider](../../providers/file.md)" +`serversTransport` allows to reference a [TCP ServersTransport](./index.md#serverstransport_3) configuration for the communication between Traefik and your servers. + +??? example "Specify a TCP transport -- Using the [File Provider](../../providers/file.md)" ```yaml tab="YAML" ## Dynamic configuration tcp: services: - my-service: + Service01: loadBalancer: - proxyProtocol: - version: 1 + serversTransport: mytransport ``` ```toml tab="TOML" ## Dynamic configuration [tcp.services] - [tcp.services.my-service.loadBalancer] - [tcp.services.my-service.loadBalancer.proxyProtocol] - version = 1 + [tcp.services.Service01] + [tcp.services.Service01.loadBalancer] + serversTransport = "mytransport" ``` -#### Termination Delay +!!! info "Default Servers Transport" -As a proxy between a client and a server, it can happen that either side (e.g. client side) decides to terminate its writing capability on the connection (i.e. issuance of a FIN packet). -The proxy needs to propagate that intent to the other side, and so when that happens, it also does the same on its connection with the other side (e.g. backend side). + If no serversTransport is specified, the `default@internal` will be used. + The `default@internal` serversTransport is created from the [static configuration](../overview.md#tcp-servers-transports). -However, if for some reason (bad implementation, or malicious intent) the other side does not eventually do the same as well, -the connection would stay half-open, which would lock resources for however long. +#### PROXY Protocol -To that end, as soon as the proxy enters this termination sequence, it sets a deadline on fully terminating the connections on both sides. +Traefik supports [PROXY Protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt) version 1 and 2 on TCP Services. +It can be enabled by setting `proxyProtocol` on the load balancer. -The termination delay controls that deadline. -It is a duration in milliseconds, defaulting to 100. -A negative value means an infinite deadline (i.e. the connection is never fully terminated by the proxy itself). +Below are the available options for the PROXY protocol: -??? example "A Service with a termination delay -- Using the [File Provider](../../providers/file.md)" +- `version` specifies the version of the protocol to be used. Either `1` or `2`. + +!!! info "Version" + + Specifying a version is optional. By default the version 2 will be used. + +??? example "A Service with Proxy Protocol v1 -- Using the [File Provider](../../providers/file.md)" ```yaml tab="YAML" ## Dynamic configuration @@ -1546,15 +1569,16 @@ A negative value means an infinite deadline (i.e. the connection is never fully services: my-service: loadBalancer: - terminationDelay: 200 + proxyProtocol: + version: 1 ``` ```toml tab="TOML" ## Dynamic configuration [tcp.services] [tcp.services.my-service.loadBalancer] - [[tcp.services.my-service.loadBalancer]] - terminationDelay = 200 + [tcp.services.my-service.loadBalancer.proxyProtocol] + version = 1 ``` ### Weighted Round Robin @@ -1612,6 +1636,414 @@ tcp: address = "private-ip-server-2:8080/" ``` +### ServersTransport + +ServersTransport allows to configure the transport between Traefik and your TCP servers. + +#### `dialTimeout` + +_Optional, Default="30s"_ + +`dialTimeout` defines the timeout when dialing the backend TCP service. If zero, no timeout exists. + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + dialTimeout: 30s +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[tcp.serversTransports.mytransport] + dialTimeout = "30s" +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + dialTimeout: 30s +``` + +#### `dialKeepAlive` + +_Optional, Default="15s"_ + +`dialKeepAlive` defines the interval between keep-alive probes for an active network connection. +If zero, keep-alive probes are sent with a default value (currently 15 seconds), if supported by the protocol and +operating system. Network protocols or operating systems that do not support keep-alives ignore this field. If negative, +keep-alive probes are disabled. + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + dialKeepAlive: 30s +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[tcp.serversTransports.mytransport] + dialKeepAlive = "30s" +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + dialKeepAlive: 30s +``` + +#### `terminationDelay` + +_Optional, Default="100ms"_ + +As a proxy between a client and a server, it can happen that either side (e.g. client side) decides to terminate its writing capability on the connection (i.e. issuance of a FIN packet). +The proxy needs to propagate that intent to the other side, and so when that happens, it also does the same on its connection with the other side (e.g. backend side). + +However, if for some reason (bad implementation, or malicious intent) the other side does not eventually do the same as well, +the connection would stay half-open, which would lock resources for however long. + +To that end, as soon as the proxy enters this termination sequence, it sets a deadline on fully terminating the connections on both sides. + +The termination delay controls that deadline. +A negative value means an infinite deadline (i.e. the connection is never fully terminated by the proxy itself). + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + terminationDelay: 100ms +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[tcp.serversTransports.mytransport] + terminationDelay = "100ms" +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + terminationDelay: 100ms +``` + +#### `tls` + +`tls` defines the TLS configuration. + +_Optional_ + +An empty `tls` section enables TLS. + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + tls: {} +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[tcp.serversTransports.mytransport.tls] +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + tls: {} +``` + +#### `tls.serverName` + +_Optional_ + +`tls.serverName` configure the server name that will be used for SNI. + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + tls: + serverName: "myhost" +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[tcp.serversTransports.mytransport.tls] + serverName = "myhost" +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + tls: + serverName: "test" +``` + +#### `tls.certificates` + +_Optional_ + +`tls.certificates` is the list of certificates (as file paths, or data bytes) +that will be set as client certificates for mTLS. + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + tls: + certificates: + - certFile: foo.crt + keyFile: bar.crt +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[[tcp.serversTransports.mytransport.tls.certificates]] + certFile = "foo.crt" + keyFile = "bar.crt" +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + tls: + certificatesSecrets: + - mycert + +--- +apiVersion: v1 +kind: Secret +metadata: + name: mycert + +data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= +``` + +#### `tls.insecureSkipVerify` + +_Optional_ + +`tls.insecureSkipVerify` controls whether the server's certificate chain and host name is verified. + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + tls: + insecureSkipVerify: true +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[tcp.serversTransports.mytransport.tls] + insecureSkipVerify = true +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + tls: + insecureSkipVerify: true +``` + +#### `tls.rootCAs` + +_Optional_ + +`tls.rootCAs` defines the set of root certificate authorities (as file paths, or data bytes) to use when verifying server certificates. + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + tls: + rootCAs: + - foo.crt + - bar.crt +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[tcp.serversTransports.mytransport.tls] + rootCAs = ["foo.crt", "bar.crt"] +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + tls: + rootCAsSecrets: + - myca +--- +apiVersion: v1 +kind: Secret +metadata: + name: myca + +data: + ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= +``` + +#### `tls.peerCertURI` + +_Optional, Default=false_ + +`tls.peerCertURI` defines the URI used to match against SAN URIs during the server's certificate verification. + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + tls: + peerCertURI: foobar +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[tcp.serversTransports.mytransport.tls] + peerCertURI = "foobar" +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + tls: + peerCertURI: foobar +``` + +#### `spiffe` + +Please note that [SPIFFE](../../https/spiffe.md) must be enabled in the static configuration +before using it to secure the connection between Traefik and the backends. + +##### `spiffe.ids` + +_Optional_ + +`ids` defines the allowed SPIFFE IDs. +This takes precedence over the SPIFFE TrustDomain. + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + spiffe: + ids: + - spiffe://trust-domain/id1 + - spiffe://trust-domain/id2 +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[tcp.serversTransports.mytransport.spiffe] + ids = ["spiffe://trust-domain/id1", "spiffe://trust-domain/id2"] +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + spiffe: + ids: + - spiffe://trust-domain/id1 + - spiffe://trust-domain/id2 +``` + +##### `spiffe.trustDomain` + +_Optional_ + +`trustDomain` defines the allowed SPIFFE trust domain. + +```yaml tab="File (YAML)" +## Dynamic configuration +tcp: + serversTransports: + mytransport: + spiffe: + trustDomain: spiffe://trust-domain +``` + +```toml tab="File (TOML)" +## Dynamic configuration +[tcp.serversTransports.mytransport.spiffe] + trustDomain = "spiffe://trust-domain" +``` + +```yaml tab="Kubernetes" +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: mytransport + namespace: default + +spec: + spiffe: + trustDomain: "spiffe://trust-domain" +``` + ## Configuring UDP Services ### General diff --git a/docs/content/traefik-hub/index.md b/docs/content/traefik-hub/index.md index a6c57cee999a08e0dc25d9f527697865e96f576a..5c6698e9dbfb3b278f074665ad9b3766f7add308 100644 --- a/docs/content/traefik-hub/index.md +++ b/docs/content/traefik-hub/index.md @@ -2,7 +2,7 @@ ## Overview -Once the Traefik Hub Experimental feature is enabled in Traefik, +Once the Traefik Hub feature is enabled in Traefik, Traefik and its local agent communicate together. This agent can: @@ -27,7 +27,6 @@ This agent can: * Traefik Hub is compatible with Traefik Proxy 2.7 or later. * The Traefik Hub Agent must be installed to connect to the Traefik Hub platform. - * Activate this feature in the experimental section of the static configuration. !!! information "Configuration Discovery" @@ -38,9 +37,6 @@ This agent can: !!! example "Minimal Static Configuration to Activate Traefik Hub for Docker" ```yaml tab="File (YAML)" - experimental: - hub: true - hub: tls: insecure: true @@ -51,9 +47,6 @@ This agent can: ``` ```toml tab="File (TOML)" - [experimental] - hub = true - [hub] [hub.tls] insecure = true @@ -64,7 +57,6 @@ This agent can: ``` ```bash tab="CLI" - --experimental.hub --hub.tls.insecure --metrics.prometheus.addrouterslabels ``` @@ -72,9 +64,6 @@ This agent can: !!! example "Minimal Static Configuration to Activate Traefik Hub for Kubernetes" ```yaml tab="File (YAML)" - experimental: - hub: true - hub: {} metrics: @@ -83,9 +72,6 @@ This agent can: ``` ```toml tab="File (TOML)" - [experimental] - hub = true - [hub] [metrics] @@ -94,7 +80,6 @@ This agent can: ``` ```bash tab="CLI" - --experimental.hub --hub --metrics.prometheus.addrouterslabels ``` diff --git a/docs/content/user-guides/crd-acme/04-ingressroutes.yml b/docs/content/user-guides/crd-acme/04-ingressroutes.yml index 6c4616365918502dbd62844ff6fad6dfe7d47470..6f57d99f5c331816f0ead1404fa0477d0e14e6f9 100644 --- a/docs/content/user-guides/crd-acme/04-ingressroutes.yml +++ b/docs/content/user-guides/crd-acme/04-ingressroutes.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: simpleingressroute @@ -14,7 +14,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: ingressroutetls diff --git a/docs/content/user-guides/crd-acme/05-tlsoption.yml b/docs/content/user-guides/crd-acme/05-tlsoption.yml index f29d9bcd72fcad6a3e0c8f39bcbc74e327ba08d3..a94a610dcaba754452993ad35d81565d9251c0f8 100644 --- a/docs/content/user-guides/crd-acme/05-tlsoption.yml +++ b/docs/content/user-guides/crd-acme/05-tlsoption.yml @@ -1,5 +1,5 @@ --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: default diff --git a/docs/content/user-guides/crd-acme/index.md b/docs/content/user-guides/crd-acme/index.md index 67953a85b8fadf093680b52e417a0129c11a48e3..7eac2b9f8062fb98c25dcf319490f073ca1c1c68 100644 --- a/docs/content/user-guides/crd-acme/index.md +++ b/docs/content/user-guides/crd-acme/index.md @@ -49,10 +49,10 @@ and the RBAC authorization resources which will be referenced through the `servi ```bash # Install Traefik Resource Definitions: -kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.9/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml # Install RBAC for Traefik: -kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.9/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml +kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/reference/dynamic-configuration/kubernetes-crd-rbac.yml ``` ### Services @@ -60,7 +60,7 @@ kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.9/docs/con Then, the services. One for Traefik itself, and one for the app it routes for, i.e. in this case our demo HTTP server: [whoami](https://github.com/traefik/whoami). ```bash -kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.9/docs/content/user-guides/crd-acme/02-services.yml +kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/user-guides/crd-acme/02-services.yml ``` ```yaml @@ -73,7 +73,7 @@ Next, the deployments, i.e. the actual pods behind the services. Again, one pod for Traefik, and one for the whoami app. ```bash -kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.9/docs/content/user-guides/crd-acme/03-deployments.yml +kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/user-guides/crd-acme/03-deployments.yml ``` ```yaml @@ -100,7 +100,7 @@ Look it up. We can now finally apply the actual ingressRoutes, with: ```bash -kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.9/docs/content/user-guides/crd-acme/04-ingressroutes.yml +kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/user-guides/crd-acme/04-ingressroutes.yml ``` ```yaml @@ -126,7 +126,7 @@ Nowadays, TLS v1.0 and v1.1 are deprecated. In order to force TLS v1.2 or later on all your IngressRoute, you can define the `default` TLSOption: ```bash -kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v2.9/docs/content/user-guides/crd-acme/05-tlsoption.yml +kubectl apply -f https://raw.githubusercontent.com/traefik/traefik/v3.0/docs/content/user-guides/crd-acme/05-tlsoption.yml ``` ```yaml diff --git a/docs/content/user-guides/marathon.md b/docs/content/user-guides/marathon.md deleted file mode 100644 index 2b374ca240c26cdd886265de81252d45de4bbefe..0000000000000000000000000000000000000000 --- a/docs/content/user-guides/marathon.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: "Traefik Proxy and Marathon Integration Guide |Traefik Docs" -description: "This guide explains how to integrate Marathon and operate the cluster in a reliable way from the Traefik Proxy standpoint." ---- - -# Marathon - -This guide explains how to integrate Marathon and operate the cluster in a reliable way from Traefik's standpoint. - -## Host detection - -Marathon offers multiple ways to run (Docker-containerized) applications, the most popular ones being - -- BRIDGE-networked containers with dynamic high ports exposed -- HOST-networked containers with host machine ports -- containers with dedicated IP addresses ([IP-per-task](https://mesosphere.github.io/marathon/docs/ip-per-task.html)). - -Traefik tries to detect the configured mode and route traffic to the right IP addresses. It is possible to force using task hosts with the `forceTaskHostname` option. - -## Port detection - -Traefik also attempts to determine the right port (which is a [non-trivial matter in Marathon](https://mesosphere.github.io/marathon/docs/ports.html)) from the following sources: - -1. An arbitrary port specified through label `traefik.http.services.serviceName.loadbalancer.server.port=8080` -1. The task port. -1. The port from the application's `portDefinitions` field. -1. The port from the application's `ipAddressPerTask` field. - -### Port label syntax - -To select a port, you can either - -- specify the port directly: `traefik.http.services.serviceName.loadbalancer.server.port=8080` -- specify a port index: `traefik.http.services.serviceName.loadbalancer.server.port=index:0` -- specify a port name: `traefik.http.services.serviceName.loadbalancer.server.port=name:http` -- otherwise the first one is selected. - -## Achieving high availability - -### Scenarios - -There are three scenarios where the availability of a Marathon application could be impaired along with the risk of losing or failing requests: - -- During the startup phase when Traefik already routes requests to the backend even though it has not completed its bootstrapping process yet. -- During the shutdown phase when Traefik still routes requests to the backend while the backend is already terminating. -- During a failure of the application when Traefik has not yet identified the backend as being erroneous. - -The first two scenarios are common with every rolling upgrade of an application (i.e. a new version release or configuration update). - -The following sub-sections describe how to resolve or mitigate each scenario. - -#### Startup - -It is possible to define [readiness checks](https://mesosphere.github.io/marathon/docs/readiness-checks.html) (available since Marathon version 1.1) per application and have Marathon take these into account during the startup phase. - -The idea is that each application provides an HTTP endpoint that Marathon queries periodically during an ongoing deployment in order to mark the associated readiness check result as successful if and only if the endpoint returns a response within the configured HTTP code range. -As long as the check keeps failing, Marathon will not proceed with the deployment (within the configured upgrade strategy bounds). - -Beginning with version 1.4, Traefik respects readiness check results if the Traefik option is set and checks are configured on the applications accordingly. - -!!! note - Due to the way readiness check results are currently exposed by the Marathon API, ready tasks may be taken into rotation with a small delay. - It is on the order of one readiness check timeout interval (as configured on the application specification) and guarantees that non-ready tasks do not receive traffic prematurely. - -If readiness checks are not possible, a current mitigation strategy is to enable [retries](../middlewares/http/retry.md) and make sure that a sufficient number of healthy application tasks exist so that one retry will likely hit one of those. -Apart from its probabilistic nature, the workaround comes at the price of increased latency. - -#### Shutdown - -It is possible to install a [termination handler](https://mesosphere.github.io/marathon/docs/health-checks.html) (available since Marathon version 1.3) with each application whose responsibility it is to delay the shutdown process long enough until the backend has been taken out of load-balancing rotation with reasonable confidence (i.e., Traefik has received an update from the Marathon event bus, recomputes the available Marathon backends, and applies the new configuration). -Specifically, each termination handler should install a signal handler listening for a SIGTERM signal and implement the following steps on signal reception: - -1. Disable Keep-Alive HTTP connections. -1. Keep accepting HTTP requests for a certain period of time. -1. Stop accepting new connections. -1. Finish serving any in-flight requests. -1. Shut down. - -Traefik already ignores Marathon tasks whose state does not match `TASK_RUNNING`; since terminating tasks transition into the `TASK_KILLING` and eventually `TASK_KILLED` state, there is nothing further that needs to be done on Traefik's end. - -How long HTTP requests should continue to be accepted in step 2 depends on how long Traefik needs to receive and process the Marathon configuration update. -Under regular operational conditions, it should be on the order of seconds, with 10 seconds possibly being a good default value. - -Again, configuring Traefik to do retries (as discussed in the previous section) can serve as a decent workaround strategy. -Paired with termination handlers, they would cover for those cases where either the termination sequence or Traefik cannot complete their part of the orchestration process in time. - -#### Failure - -A failing application always happens unexpectedly, and hence, it is very difficult or even impossible to rule out the adversal effects categorically. - -Failure reasons vary broadly and could stretch from unacceptable slowness, a task crash, or a network split. - -There are two mitigation efforts: - -1. Configure [Marathon health checks](https://mesosphere.github.io/marathon/docs/health-checks.html) on each application. -2. Configure Traefik health checks (possibly via the `traefik.http.services.yourServiceName.loadbalancer.healthcheck.*` labels) and make sure they probe with proper frequency. - -The Marathon health check makes sure that applications once deemed dysfunctional are being rescheduled to different slaves. -However, they might take a while to get triggered and the follow-up processes to complete. - -For that reason, the Traefik health check provides an additional check that responds more rapidly and does not require a configuration reload to happen. -Additionally, it protects from cases that the Marathon health check may not be able to cover, such as a network split. - -### (Non-)Alternatives - -There are a few alternatives of varying quality that are frequently asked for. - -The remaining section is going to explore them along with a benefit/cost trade-off. - -#### Reusing Marathon health checks - -It may seem obvious to reuse the Marathon health checks as a signal to Traefik whether an application should be taken into load-balancing rotation or not. - -Apart from the increased latency a failing health check may have, a major problem with this is that Marathon does not persist the health check results. -Consequently, if a master re-election occurs in the Marathon clusters, all health check results will revert to the _unknown_ state, effectively causing all applications inside the cluster to become unavailable and leading to a complete cluster failure. -Re-elections do not only happen during regular maintenance work (often requiring rolling upgrades of the Marathon nodes) but also when the Marathon leader fails spontaneously. -As such, there is no way to handle this situation deterministically. - -Finally, Marathon health checks are not mandatory (the default is to use the task state as reported by Mesos), so requiring them for Traefik would raise the entry barrier for Marathon users. - -Traefik used to use the health check results as a strict requirement but moved away from it as [users reported the dramatic consequences](https://github.com/traefik/traefik/issues/653). - -#### Draining - -Another common approach is to let a proxy drain backends that are supposed to shut down. -That is, once a backend is supposed to shut down, Traefik would stop forwarding requests. - -On the plus side, this would not require any modifications to the application in question. -However, implementing this fully within Traefik seems like a non-trivial undertaking. - -Additionally, the approach is less flexible compared to a custom termination handler since only the latter allows for the implementation of custom termination sequences that go beyond simple request draining (e.g., persisting a snapshot state to disk prior to terminating). - -The feature is currently not implemented; a request for draining in general is at [issue 41](https://github.com/traefik/traefik/issues/41). diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 91b163347752edb8d442f3d66945e04a4a32ccc2..3237cc82e90f01acedadd5e6b4277116e046d4f3 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -27,7 +27,7 @@ theme: prev: 'Previous' next: 'Next' -copyright: "Copyright © 2016-2020 Containous; 2020-2022 Traefik Labs" +copyright: 'Traefik Labs • Copyright © 2016-2023' extra_javascript: - assets/js/hljs/highlight.pack.js # Download from https://highlightjs.org/download/ and enable YAML, TOML and Dockerfile @@ -81,8 +81,6 @@ nav: - 'Consul Catalog': 'providers/consul-catalog.md' - 'Nomad': 'providers/nomad.md' - 'ECS': 'providers/ecs.md' - - 'Marathon': 'providers/marathon.md' - - 'Rancher': 'providers/rancher.md' - 'File': 'providers/file.md' - 'Consul': 'providers/consul.md' - 'Etcd': 'providers/etcd.md' @@ -102,8 +100,6 @@ nav: - 'Consul Catalog': 'routing/providers/consul-catalog.md' - 'Nomad': 'routing/providers/nomad.md' - 'ECS': 'routing/providers/ecs.md' - - 'Marathon': 'routing/providers/marathon.md' - - 'Rancher': 'routing/providers/rancher.md' - 'KV': 'routing/providers/kv.md' - 'HTTPS & TLS': - 'Overview': 'https/overview.md' @@ -155,7 +151,6 @@ nav: - 'Metrics': - 'Overview': 'observability/metrics/overview.md' - 'Datadog': 'observability/metrics/datadog.md' - - 'InfluxDB': 'observability/metrics/influxdb.md' - 'InfluxDB2': 'observability/metrics/influxdb2.md' - 'OpenTelemetry': 'observability/metrics/opentelemetry.md' - 'Prometheus': 'observability/metrics/prometheus.md' @@ -172,7 +167,6 @@ nav: - 'User Guides': - 'Kubernetes and Let''s Encrypt': 'user-guides/crd-acme/index.md' - 'gRPC Examples': 'user-guides/grpc.md' - - 'Marathon': 'user-guides/marathon.md' - 'Docker': - 'Basic Example': 'user-guides/docker-compose/basic-example/index.md' - 'HTTPS with Let''s Encrypt': @@ -208,8 +202,6 @@ nav: - 'Nomad': "reference/dynamic-configuration/nomad.md" - 'ECS': 'reference/dynamic-configuration/ecs.md' - 'KV': 'reference/dynamic-configuration/kv.md' - - 'Marathon': 'reference/dynamic-configuration/marathon.md' - - 'Rancher': 'reference/dynamic-configuration/rancher.md' - 'Deprecation Notices': - 'Releases': 'deprecation/releases.md' - 'Features': 'deprecation/features.md' diff --git a/docs/scripts/verify.sh b/docs/scripts/verify.sh index 830fb448ea23c647287c71bb1dae64a5b83e8d5e..970d18988447cf9dce7e0b0cb2e4b92fcf6a38b9 100755 --- a/docs/scripts/verify.sh +++ b/docs/scripts/verify.sh @@ -22,7 +22,7 @@ find "${PATH_TO_SITE}" -type f -not -path "/app/site/theme/*" \ --alt_ignore="/traefikproxy-vertical-logo-color.svg/" \ --http_status_ignore="0,500,501,503" \ --file_ignore="/404.html/" \ - --url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/,/www.linode.com/,/www.alibabacloud.com/,/www.cloudxns.net/,/www.vultr.com/,/vscale.io/,/hetzner.com/,/docs.github.com/,/njal.la/,/www.wedos.com/" \ + --url_ignore="/https://groups.google.com/a/traefik.io/forum/#!forum/security/,/localhost:/,/127.0.0.1:/,/fonts.gstatic.com/,/.minikube/,/github.com\/traefik\/traefik\/*edit*/,/github.com\/traefik\/traefik/,/doc.traefik.io/,/github\.com\/golang\/oauth2\/blob\/36a7019397c4c86cf59eeab3bc0d188bac444277\/.+/,/www.akamai.com/,/pilot.traefik.io\/profile/,/traefik.io/,/doc.traefik.io\/traefik-mesh/,/www.mkdocs.org/,/squidfunk.github.io/,/ietf.org/,/www.namesilo.com/,/www.youtube.com/,/www.linode.com/,/www.alibabacloud.com/,/www.cloudxns.net/,/www.vultr.com/,/vscale.io/,/hetzner.com/,/docs.github.com/,/njal.la/,/www.wedos.com/,/www.reg.ru/" \ '{}' 1>/dev/null ## HTML-proofer options at https://github.com/gjtorikian/html-proofer#configuration diff --git a/exp.Dockerfile b/exp.Dockerfile index bb2fc4997f990d76548c2f4bf59fe17485c9f24f..843f8ca0f24262d8094ccde1b0a6d6fa055e9537 100644 --- a/exp.Dockerfile +++ b/exp.Dockerfile @@ -12,7 +12,7 @@ RUN yarn install RUN yarn build # BUILD -FROM golang:1.19-alpine as gobuild +FROM golang:1.20-alpine as gobuild RUN apk --no-cache --no-progress add git mercurial bash gcc musl-dev curl tar ca-certificates tzdata \ && update-ca-certificates \ diff --git a/go.mod b/go.mod index 47c37943df93b2cac7800f7bfcced0b08ba07115..a083b62ce3500b86934075492fdfd956dfdbfb48 100644 --- a/go.mod +++ b/go.mod @@ -1,33 +1,32 @@ -module github.com/traefik/traefik/v2 +module github.com/traefik/traefik/v3 -go 1.19 +go 1.20 require ( github.com/BurntSushi/toml v1.2.1 github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61 - github.com/Masterminds/sprig/v3 v3.2.2 + github.com/Masterminds/sprig/v3 v3.2.3 github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000 github.com/andybalholm/brotli v1.0.4 github.com/aws/aws-sdk-go v1.44.47 - github.com/cenkalti/backoff/v4 v4.1.3 + github.com/cenkalti/backoff/v4 v4.2.0 github.com/compose-spec/compose-go v1.0.3 github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf github.com/davecgh/go-spew v1.1.1 github.com/docker/cli v20.10.11+incompatible github.com/docker/compose/v2 v2.0.1 - github.com/docker/docker v20.10.7+incompatible + github.com/docker/docker v20.10.21+incompatible github.com/docker/go-connections v0.4.0 github.com/fatih/structs v1.1.0 - github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 - github.com/go-acme/lego/v4 v4.9.1 + github.com/go-acme/lego/v4 v4.10.2 github.com/go-check/check v0.0.0-00010101000000-000000000000 github.com/go-kit/kit v0.10.1-0.20200915143503-439c4d2ed3ea github.com/golang/protobuf v1.5.2 github.com/google/go-github/v28 v28.1.1 github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.5.0 - github.com/hashicorp/consul v1.10.4 + github.com/hashicorp/consul v1.10.12 github.com/hashicorp/consul/api v1.14.0 github.com/hashicorp/go-hclog v1.2.0 github.com/hashicorp/go-multierror v1.1.1 @@ -44,7 +43,6 @@ require ( github.com/kvtools/redis v1.0.2 github.com/kvtools/valkeyrie v1.0.0 github.com/kvtools/zookeeper v1.0.2 - github.com/lucas-clemente/quic-go v0.28.1 github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f github.com/miekg/dns v1.1.50 github.com/mitchellh/copystructure v1.2.0 @@ -59,43 +57,43 @@ require ( github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_golang v1.12.2-0.20220704083116-e8f91604d835 github.com/prometheus/client_model v0.2.0 - github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac + github.com/quic-go/quic-go v0.33.0 github.com/rs/zerolog v1.28.0 github.com/sirupsen/logrus v1.9.0 github.com/spiffe/go-spiffe/v2 v2.1.1 github.com/stretchr/testify v1.8.1 github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 github.com/tailscale/tscert v0.0.0-20220316030059-54bbcb9f74e2 - github.com/traefik/paerser v0.1.9 - github.com/traefik/yaegi v0.14.3 + github.com/traefik/paerser v0.2.0 + github.com/traefik/yaegi v0.15.0 github.com/uber/jaeger-client-go v2.30.0+incompatible github.com/uber/jaeger-lib v2.2.0+incompatible github.com/unrolled/render v1.0.2 github.com/unrolled/secure v1.0.9 github.com/vdemeester/shakers v0.1.0 - github.com/vulcand/oxy/v2 v2.0.0-20221121151423-d5cb734e4467 + github.com/vulcand/oxy/v2 v2.0.0-20230227135449-a0e9f7ff1040 github.com/vulcand/predicate v1.2.0 go.elastic.co/apm v1.13.1 go.elastic.co/apm/module/apmot v1.13.1 go.opentelemetry.io/collector/pdata v0.64.1 - go.opentelemetry.io/otel v1.11.1 - go.opentelemetry.io/otel/bridge/opentracing v1.11.1 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.33.0 - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.33.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.1 - go.opentelemetry.io/otel/metric v0.33.0 - go.opentelemetry.io/otel/sdk v1.11.1 - go.opentelemetry.io/otel/sdk/metric v0.33.0 - go.opentelemetry.io/otel/trace v1.11.1 - golang.org/x/exp v0.0.0-20221114191408-850992195362 + go.opentelemetry.io/otel v1.11.2 + go.opentelemetry.io/otel/bridge/opentracing v1.11.2 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.34.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.2 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.2 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.2 + go.opentelemetry.io/otel/metric v0.34.0 + go.opentelemetry.io/otel/sdk v1.11.2 + go.opentelemetry.io/otel/sdk/metric v0.34.0 + go.opentelemetry.io/otel/trace v1.11.2 + golang.org/x/exp v0.0.0-20221205204356-47842c84f3db golang.org/x/mod v0.6.0 - golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 - golang.org/x/text v0.5.0 - golang.org/x/time v0.0.0-20220609170525-579cf78fd858 + golang.org/x/net v0.7.0 + golang.org/x/text v0.7.0 + golang.org/x/time v0.3.0 golang.org/x/tools v0.2.0 - google.golang.org/grpc v1.50.1 + google.golang.org/grpc v1.51.0 gopkg.in/DataDog/dd-trace-go.v1 v1.43.1 gopkg.in/fsnotify.v1 v1.4.7 gopkg.in/yaml.v3 v3.0.1 @@ -109,7 +107,7 @@ require ( ) require ( - cloud.google.com/go v0.97.0 // indirect + cloud.google.com/go/compute/metadata v0.2.0 // indirect github.com/AlecAivazis/survey/v2 v2.2.3 // indirect github.com/Azure/azure-sdk-for-go v40.3.0+incompatible // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect @@ -129,9 +127,9 @@ require ( github.com/DataDog/sketches-go v1.2.1 // indirect github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.1.1 // indirect + github.com/Masterminds/semver/v3 v3.2.0 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect - github.com/Microsoft/hcsshim v0.8.23 // indirect + github.com/Microsoft/hcsshim v0.8.24 // indirect github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect @@ -147,16 +145,15 @@ require ( github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect github.com/buger/goterm v1.0.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/cheekybits/genny v1.0.0 // indirect github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect github.com/circonus-labs/circonusllhist v0.1.3 // indirect github.com/civo/civogo v0.3.11 // indirect github.com/cloudflare/cloudflare-go v0.49.0 // indirect github.com/compose-spec/godotenv v1.0.0 // indirect - github.com/containerd/cgroups v1.0.1 // indirect - github.com/containerd/console v1.0.2 // indirect - github.com/containerd/containerd v1.5.9 // indirect - github.com/containerd/continuity v0.1.0 // indirect + github.com/containerd/cgroups v1.0.3 // indirect + github.com/containerd/console v1.0.3 // indirect + github.com/containerd/containerd v1.5.16 // indirect + github.com/containerd/continuity v0.3.0 // indirect github.com/containerd/typeurl v1.0.2 // indirect github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534 // indirect @@ -169,12 +166,11 @@ require ( github.com/distribution/distribution/v3 v3.0.0-20210316161203-a01c71e2477e // indirect github.com/dnsimple/dnsimple-go v0.71.1 // indirect github.com/docker/buildx v0.5.2-0.20210422185057-908a856079fc // indirect - github.com/docker/distribution v2.7.1+incompatible // indirect + github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/docker-credential-helpers v0.6.4-0.20210125172408-38bea2ce277a // indirect github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.4.0 // indirect - github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e // indirect github.com/dustin/go-humanize v1.0.0 // indirect github.com/elastic/go-licenser v0.3.1 // indirect github.com/elastic/go-sysinfo v1.1.1 // indirect @@ -187,6 +183,7 @@ require ( github.com/fvbommel/sortorder v1.0.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.0.1 // indirect + github.com/go-jose/go-jose/v3 v3.0.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect @@ -209,14 +206,16 @@ require ( github.com/google/go-cmp v0.5.9 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/gax-go/v2 v2.1.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.6.0 // indirect github.com/gophercloud/gophercloud v1.0.0 // indirect github.com/gophercloud/utils v0.0.0-20210216074907-f6de111f2eae // indirect github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0 // indirect github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect github.com/hashicorp/consul/sdk v0.10.0 // indirect github.com/hashicorp/cronexpr v1.1.1 // indirect @@ -230,11 +229,11 @@ require ( github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/memberlist v0.3.1 // indirect - github.com/hashicorp/raft v1.3.2 // indirect + github.com/hashicorp/raft v1.3.6 // indirect github.com/hashicorp/raft-autopilot v0.1.5 // indirect github.com/hashicorp/serf v0.9.7 // indirect github.com/hashicorp/yamux v0.0.0-20210826001029-26ff87cf9493 // indirect - github.com/huandu/xstrings v1.3.2 // indirect + github.com/huandu/xstrings v1.3.3 // indirect github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect @@ -262,15 +261,10 @@ require ( github.com/mailgun/multibuf v0.1.2 // indirect github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/marten-seemann/qpack v0.2.1 // indirect - github.com/marten-seemann/qtls-go1-16 v0.1.5 // indirect - github.com/marten-seemann/qtls-go1-17 v0.1.2 // indirect - github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect - github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1 // indirect github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-shellwords v1.0.12 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/miekg/pkcs11 v1.0.3 // indirect github.com/mimuret/golang-iij-dpf v0.7.1 // indirect @@ -281,7 +275,7 @@ require ( github.com/moby/buildkit v0.8.2-0.20210401015549-df49b648c8bf // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/sys/mount v0.2.0 // indirect - github.com/moby/sys/mountinfo v0.4.1 // indirect + github.com/moby/sys/mountinfo v0.5.0 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -295,11 +289,10 @@ require ( github.com/nrdcg/goinwx v0.8.1 // indirect github.com/nrdcg/namesilo v0.2.1 // indirect github.com/nrdcg/porkbun v0.1.1 // indirect - github.com/nxadm/tail v1.4.8 // indirect - github.com/onsi/ginkgo v1.16.5 // indirect + github.com/onsi/ginkgo/v2 v2.2.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect - github.com/opencontainers/runc v1.0.3 // indirect + github.com/opencontainers/runc v1.1.4 // indirect github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect github.com/oracle/oci-go-sdk v24.3.0+incompatible // indirect github.com/ovh/go-ovh v1.1.0 // indirect @@ -308,6 +301,9 @@ require ( github.com/pquerna/otp v1.3.0 // indirect github.com/prometheus/common v0.35.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect + github.com/quic-go/qpack v0.4.0 // indirect + github.com/quic-go/qtls-go1-19 v0.2.1 // indirect + github.com/quic-go/qtls-go1-20 v0.1.1 // indirect github.com/rs/cors v1.7.0 // indirect github.com/sacloud/api-client-go v0.2.1 // indirect github.com/sacloud/go-http v0.1.2 // indirect @@ -333,6 +329,7 @@ require ( github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect github.com/transip/gotransip/v6 v6.17.0 // indirect github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect + github.com/ultradns/ultradns-go-sdk v1.4.0-20221107152238-f3f1d1d // indirect github.com/vinyldns/go-vinyldns v0.9.16 // indirect github.com/vultr/govultr/v2 v2.17.2 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect @@ -347,8 +344,8 @@ require ( go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect go.etcd.io/etcd/client/v3 v3.5.4 // indirect go.opencensus.io v0.23.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.33.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.34.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect @@ -356,22 +353,21 @@ require ( go.uber.org/zap v1.21.0 // indirect go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 // indirect - golang.org/x/crypto v0.1.0 // indirect + golang.org/x/crypto v0.5.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect - golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect - golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect - golang.org/x/sys v0.3.0 // indirect - golang.org/x/term v0.3.0 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - google.golang.org/api v0.57.0 // indirect + golang.org/x/oauth2 v0.4.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/term v0.5.0 // indirect + golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect + google.golang.org/api v0.98.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 // indirect + google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.6 // indirect gopkg.in/ns1/ns1-go.v2 v2.6.5 // indirect - gopkg.in/square/go-jose.v2 v2.6.0 // indirect - gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect inet.af/netaddr v0.0.0-20220617031823-097006376321 // indirect @@ -387,7 +383,6 @@ require ( replace ( github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e github.com/go-check/check => github.com/containous/check v0.0.0-20170915194414-ca0bf163426a - github.com/gorilla/mux => github.com/containous/mux v0.0.0-20220627093034-b2dd784e613f github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595 ) @@ -397,5 +392,3 @@ replace github.com/jaguilar/vt100 => github.com/tonistiigi/vt100 v0.0.0-20190402 // ambiguous import: found package github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http in multiple modules // tencentcloud uses monorepo with multimodule but the go.mod files are incomplete. exclude github.com/tencentcloud/tencentcloud-sdk-go v3.0.83+incompatible - -// replace github.com/go-logr/logr => github.com/go-logr/logr v0.4.0 diff --git a/go.sum b/go.sum index 629581f80e6e9398c33467bab52b98e787be3c0a..baf98752366713074a487ca3677203cf21bae368 100644 --- a/go.sum +++ b/go.sum @@ -2,9 +2,7 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxo bitbucket.org/liamstask/goose v0.0.0-20150115234039-8488cc47d90c/go.mod h1:hSVuE3qU7grINVSwrmzHfpg9k87ALBk+XaualNyUzI4= cloud.google.com/go v0.25.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo= cloud.google.com/go v0.37.4/go.mod h1:NHPJ89PdicEuT9hdPXMROBD91xc5uRDxsMtSB16k7hw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= @@ -31,17 +29,30 @@ cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWc cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0 h1:3DXvAyifywvq64LfkKaMOmkWPS1CikIQdMe2lY9vxU8= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.105.0 h1:DNtEKRBAAzeS4KyIory52wWHuClNaXJ5x1F7xa4q+5Y= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= +cloud.google.com/go/compute/metadata v0.2.0 h1:nBbNSZyDpkNlo3DepaaLKVuO7ClyifSAmNloSCZrHnQ= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -51,12 +62,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU= -dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= -dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= -git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/AlecAivazis/survey/v2 v2.2.3 h1:utJR2X4Ibp2fBxdjalQUiMFf3zfQNjA15YE8+ftlKEs= github.com/AlecAivazis/survey/v2 v2.2.3/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= @@ -146,10 +153,10 @@ github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -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/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8= -github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= +github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Microsoft/go-winio v0.4.3/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= @@ -171,8 +178,8 @@ github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2 github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= github.com/Microsoft/hcsshim v0.8.18/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= -github.com/Microsoft/hcsshim v0.8.23 h1:47MSwtKGXet80aIn+7h4YI6fwPmwIghAnsx2aOUrG2M= -github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= +github.com/Microsoft/hcsshim v0.8.24 h1:jP+GMeRXIR1sH1kG4lJr9ShmSjVrua5jmFZDtfYGkn4= +github.com/Microsoft/hcsshim v0.8.24/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -221,7 +228,6 @@ github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9or github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -261,7 +267,6 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA= github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= @@ -272,13 +277,11 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/buger/goterm v1.0.0 h1:ZB6uUlY8+sjJyFGzz2WpRqX2XYPeXVgtZAOJMwOsTWM= github.com/buger/goterm v1.0.0/go.mod h1:16STi3LquiscTIHA8SXUNKEa/Cnu4ZHBH8NsCaWgso0= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/bugsnag-go v1.4.1/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= github.com/bugsnag/bugsnag-go v1.5.0 h1:tP8hiPv1pGGW3LA6LKy5lW6WG+y9J2xWUdPd3WC452k= @@ -294,8 +297,8 @@ github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= +github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20180118203423-deb3ae2ef261/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -305,8 +308,7 @@ github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cb github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= -github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= -github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -315,6 +317,7 @@ github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLI github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= @@ -366,15 +369,17 @@ github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1 github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.1 h1:iJnMvco9XGvKUvNQkv88bE4uJXxRQH18efbKo9w5vHQ= github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= +github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= +github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= -github.com/containerd/console v1.0.2 h1:Pi6D+aZXM+oUw1czuKgH5IJ+y0jhYcwBJfx5/Ghn9dE= github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -392,8 +397,8 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= github.com/containerd/containerd v1.5.5/go.mod h1:oSTh0QpT1w6jYcGmbiSbxv9OSQYaa88mPyWIuU79zyo= -github.com/containerd/containerd v1.5.9 h1:rs6Xg1gtIxaeyG+Smsb/0xaSDu1VgFhOCKBXxMxbsF4= -github.com/containerd/containerd v1.5.9/go.mod h1:fvQqCfadDGga5HZyn3j4+dx56qj2I9YwBrlSdalvJYQ= +github.com/containerd/containerd v1.5.16 h1:WsTS9tV0vQmRxkWAiiaoasHJ20jqVxVA15s93Bs4GIU= +github.com/containerd/containerd v1.5.16/go.mod h1:bVZZA+0blg2Lw6+I4xDml7L3gum0LsFKe3TnFELlSFw= github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -401,8 +406,9 @@ github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= -github.com/containerd/continuity v0.1.0 h1:UFRRY5JemiAhPZrr/uE0n8fMTLcZsUvySPr1+D7pgr8= github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= +github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= +github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= github.com/containerd/fifo v0.0.0-20190816180239-bda0ff6ed73c/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= @@ -461,8 +467,6 @@ github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e h1:D+uTE github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e/go.mod h1:s8kLgBQolDbsJOPVIGCEEv9zGAKUUf/685Gi0Qqg8z8= github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595 h1:aPspFRO6b94To3gl4yTDOEtpjFwXI7V2W+z0JcNljQ4= github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595/go.mod h1:+lHFbEasIiQVGzhVDVw/cn0ZaOzde2OwNncp1NhXV4c= -github.com/containous/mux v0.0.0-20220627093034-b2dd784e613f h1:1uEtynq2C0ljy3630jt7EAxg8jZY2gy6YHdGwdqEpWw= -github.com/containous/mux v0.0.0-20220627093034-b2dd784e613f/go.mod h1:z8WW7n06n8/1xF9Jl9WmuDeZuHAhfL+bwarNjsciwwg= github.com/coredns/coredns v1.1.2/go.mod h1:zASH/MVDgR6XZTbxvOnsZfffS+31vg6Ackf/wo1+AM0= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -476,7 +480,6 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -499,6 +502,7 @@ github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= @@ -556,15 +560,17 @@ github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TT github.com/docker/distribution v2.6.0-rc.1.0.20180327202408-83389a148052+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -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.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= +github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v0.0.0-20200511152416-a93e9eb0e95c/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20180531152204-71cd53e4a197/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.4.2-0.20181229214054-f76d6a078d88/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v17.12.0-ce-rc1.0.20200730172259-9f28837c1d93+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ= github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.21+incompatible h1:UTLdBmHk3bEY+w8qeO5KttOhy6OmXWsl/FEet9Uswog= +github.com/docker/docker v20.10.21+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/docker-credential-helpers v0.6.4-0.20210125172408-38bea2ce277a h1:1DndKi+f9qs3AexOfI6di7RkWcWlNHzdqHu1cX19/ac= github.com/docker/docker-credential-helpers v0.6.4-0.20210125172408-38bea2ce277a/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c= @@ -593,8 +599,6 @@ github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNE github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docker/spdystream v0.0.0-20181023171402-6480d4af844c/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e h1:rMOGp6HPeMHbdLrZkX2nD+94uqDunc27tXVuS+ey4mQ= -github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -652,11 +656,9 @@ github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYF github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.0/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s= @@ -669,8 +671,6 @@ github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmV github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 h1:df6OFl8WNXk82xxP3R9ZPZ5seOA8XZkwLdbEzZF1/xI= -github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2/go.mod h1:GLyXJD41gBO/NPKVPGQbhyyC06eugGy15QEZyUkE2/s= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.87.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= @@ -683,10 +683,9 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= -github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/go-acme/lego/v4 v4.9.1 h1:n9Z5MQwANeGSQKlVE3bEh9SDvAySK9oVYOKCGCESqQE= -github.com/go-acme/lego/v4 v4.9.1/go.mod h1:g3JRUyWS3L/VObpp4bCxzJftKyf/Wba8QrSSnoiqjg4= +github.com/go-acme/lego/v4 v4.10.2 h1:5eW3qmda5v/LP21v1Hj70edKY1jeFZQwO617tdkwp6Q= +github.com/go-acme/lego/v4 v4.10.2/go.mod h1:EMbf0Jmqwv94nJ5WL9qWnSXIBZnvsS9gNypansHGc6U= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-cmd/cmd v1.0.5/go.mod h1:y8q8qlK5wQibcw63djSl/ntiHUHXHGdCkPk0j4QeW4s= @@ -696,6 +695,8 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= +github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -782,6 +783,7 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6 github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/flock v0.7.3/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/flock v0.8.0 h1:MSdYClljsF3PbENUUEx85nkWfJSGfzYI9yEBZOJz6CY= github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= @@ -818,7 +820,6 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -877,10 +878,10 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.0.0-20191015185424-71da34e4d9b3/go.mod h1:ZXFeSndFcK4vB1NR4voH1Zm38K7ViUNiYtfIBDxrwf0= -github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI= @@ -912,6 +913,7 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= @@ -923,12 +925,19 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= -github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0 h1:6DWmvNpomjL1+3liNSZbVns3zsYzzCjm6pRBO1tLeso= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -936,6 +945,7 @@ github.com/googleapis/gnostic v0.2.2/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTV github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gophercloud/gophercloud v0.15.1-0.20210202035223-633d73521055/go.mod h1:wRtmUelyIIv3CSSDI47aUwbs075O6i+LY+pXsKCBsb4= github.com/gophercloud/gophercloud v1.0.0 h1:9nTGx0jizmHxDobe4mck89FyQHVyA3CaXLIUSGJjP9k= @@ -946,6 +956,11 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -964,12 +979,12 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaD github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 h1:BZHcxBETFHIdVyhyEfOvn/RdU/QGdLI4y34qQGjGWO0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0 h1:t7uX3JBHdVwAi3G7sSSdbsk8NfgA+LnUS88V/2EKaA0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.14.0/go.mod h1:4OGVnY4qf2+gw+ssiHbW+pq4mo2yko94YxxMmXZ7jCA= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= @@ -978,8 +993,8 @@ github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= github.com/hanwen/go-fuse/v2 v2.0.4-0.20201208195215-4a458845028b/go.mod h1:0EQM6aH2ctVpvZ6a+onrQ/vaykxh2GH7hy3e13vzTUY= -github.com/hashicorp/consul v1.10.4 h1:rqKmYP49KnCSSxbiaJ4J2CnLA3zUAmI6KwASKxmPqFc= -github.com/hashicorp/consul v1.10.4/go.mod h1:3EJeqDz7W0LQJ2I4KzRtZZBgG5H80kZvgEtOLis/yCo= +github.com/hashicorp/consul v1.10.12 h1:xMazys3KaH5JsZS4Ra6KEAXO0nAj20EsTpsDyhd/3Do= +github.com/hashicorp/consul v1.10.12/go.mod h1:z9c9dZQI0/tKODT1x3s32wLbHyLfkG8G+FRYtn36UAc= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/api v1.10.0/go.mod h1:sDjTOq0yUyv5G4h+BqSea7Fn6BU+XbolEz1952UB+mk= @@ -1069,7 +1084,6 @@ github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.2.4/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.3.1 h1:MXgUXLqva1QvpVEDQW1IQLG0wivQAtmFlHRQ+1vWZfM= github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= @@ -1078,8 +1092,8 @@ github.com/hashicorp/nomad/api v0.0.0-20220506174431-b5665129cd1f h1:jSBbBJcPca4 github.com/hashicorp/nomad/api v0.0.0-20220506174431-b5665129cd1f/go.mod h1:b/AoT79m3PEpb6tKCFKva/M+q1rKJNUk5mdu1S8DymM= github.com/hashicorp/raft v1.1.1/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= github.com/hashicorp/raft v1.2.0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= -github.com/hashicorp/raft v1.3.2 h1:j2tqHqFnDdWCepLxzuo3b6WzS2krIweBrvEoqBbWMTo= -github.com/hashicorp/raft v1.3.2/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft v1.3.6 h1:v5xW5KzByoerQlN/o31VJrFNiozgzGyDoMgDJgXpsto= +github.com/hashicorp/raft v1.3.6/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= github.com/hashicorp/raft-autopilot v0.1.5 h1:onEfMH5uHVdXQqtas36zXUHEZxLdsJVu/nXHLcLdL1I= github.com/hashicorp/raft-autopilot v0.1.5/go.mod h1:Af4jZBwaNOI+tXfIqIdbcAnh/UyyqIMj/pOISIfhArw= github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= @@ -1097,9 +1111,8 @@ github.com/hashicorp/yamux v0.0.0-20210826001029-26ff87cf9493/go.mod h1:CtWFDAQg github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ= github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= -github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -1140,7 +1153,6 @@ github.com/jcchavezs/porto v0.1.0 h1:Xmxxn25zQMmgE7/yHYmh19KcItG81hIwfbEEFnd6w/Q github.com/jcchavezs/porto v0.1.0/go.mod h1:fESH0gzDHiutHRdX2hv27ojnOVFco37hg1W6E9EZF4A= github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03 h1:FUwcHNlEqkqLjLBdCp5PRlCFijNjvcYANOZXzCfXwCM= github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= -github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jinzhu/gorm v1.9.2/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo= github.com/jinzhu/gorm v1.9.11 h1:gaHGvE+UnWGlbWG4Y3FUwY1EcZ5n6S9WtqBA/uySMLE= @@ -1219,7 +1231,6 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= @@ -1276,9 +1287,6 @@ github.com/liquidweb/liquidweb-go v1.6.3/go.mod h1:SuXXp+thr28LnjEw18AYtWwIbWMHS github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= github.com/looplab/fsm v0.1.0 h1:Qte7Zdn/5hBNbXzP7yxVU4OIFHWXBovyTT2LaBTyC20= github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI= -github.com/lucas-clemente/quic-go v0.28.1 h1:Uo0lvVxWg5la9gflIF9lwa39ONq85Xq2D91YNEIslzU= -github.com/lucas-clemente/quic-go v0.28.1/go.mod h1:oGz5DKK41cJt5+773+BSO9BXDsREY4HLf7+0odGAPO0= -github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= @@ -1293,7 +1301,6 @@ github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51/go.mod h1:RYmqHb github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f h1:ZZYhg16XocqSKPGNQAe0aeweNtFxuedbwwb4fSlg7h4= github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f/go.mod h1:8heskWJ5c0v5J9WH89ADhyal1DOZcayll8fSbhB+/9A= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= @@ -1301,16 +1308,6 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= -github.com/marten-seemann/qpack v0.2.1 h1:jvTsT/HpCn2UZJdP+UUB53FfUUgeOyG5K1ns0OJOGVs= -github.com/marten-seemann/qpack v0.2.1/go.mod h1:F7Gl5L1jIgN1D11ucXefiuJS9UMVP2opoCp2jDKb7wc= -github.com/marten-seemann/qtls-go1-16 v0.1.5 h1:o9JrYPPco/Nukd/HpOHMHZoBDXQqoNtUCmny98/1uqQ= -github.com/marten-seemann/qtls-go1-16 v0.1.5/go.mod h1:gNpI2Ol+lRS3WwSOtIUUtRwZEQMXjYK+dQSBFbethAk= -github.com/marten-seemann/qtls-go1-17 v0.1.2 h1:JADBlm0LYiVbuSySCHeY863dNkcpMmDR7s0bLKJeYlQ= -github.com/marten-seemann/qtls-go1-17 v0.1.2/go.mod h1:C2ekUKcDdz9SDWxec1N/MvcXBpaX9l3Nx67XaR84L5s= -github.com/marten-seemann/qtls-go1-18 v0.1.2 h1:JH6jmzbduz0ITVQ7ShevK10Av5+jBEKAHMntXmIV7kM= -github.com/marten-seemann/qtls-go1-18 v0.1.2/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4= -github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1 h1:7m/WlWcSROrcK5NxuXaxYD32BZqe/LEEnBrWcH/cOqQ= -github.com/marten-seemann/qtls-go1-19 v0.1.0-beta.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1330,8 +1327,8 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -1343,11 +1340,11 @@ github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsO github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= -github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= @@ -1380,6 +1377,7 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y= github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -1408,8 +1406,9 @@ github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7s github.com/moby/sys/mountinfo v0.1.0/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o= github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM= github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc= @@ -1450,8 +1449,6 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= -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/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= @@ -1488,13 +1485,12 @@ github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.2.0 h1:3ZNA3L1c5FYDFTTxbFeVGGD8jYvjYauHD30YgLxVsNI= +github.com/onsi/ginkgo/v2 v2.2.0/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -1504,12 +1500,11 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= -github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.20.1 h1:PA/3qinGoukvymdIDV8pii6tiZgC8kbmJO6Z5+b002Q= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= @@ -1529,9 +1524,8 @@ github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rm github.com/opencontainers/runc v1.0.0-rc92/go.mod h1:X1zlU4p7wOlX4+WRCz+hvlRv8phdL7UqbYD+vQwNMmE= github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= github.com/opencontainers/runc v1.0.1/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= -github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= -github.com/opencontainers/runc v1.0.3 h1:1hbqejyQWCJBvtKAfdO0b1FmaEf2z/bxnjqbARass5k= -github.com/opencontainers/runc v1.0.3/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runc v1.1.4 h1:nRCz/8sKg6K6jgYAFLDlXzPeITBZJyX28DBVhWD+5dg= +github.com/opencontainers/runc v1.1.4/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -1543,8 +1537,9 @@ github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.m github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= -github.com/opencontainers/selinux v1.8.2 h1:c4ca10UMgRcvZ6h0K4HtS15UaVSBEaE+iln2LVpAuGc= github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opencontainers/selinux v1.10.0 h1:rAiKF8hTcgLI3w0DHm6i0ylVVcOrlgR1kK99DRLDhyU= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU= @@ -1555,7 +1550,6 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5 h1:ZCnq+JUrvXcDVhX/xRolRBZifmabN1HcS1wrPSvxhrU= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI= @@ -1608,7 +1602,6 @@ github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prY github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs= github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= @@ -1632,7 +1625,6 @@ github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1648,7 +1640,6 @@ github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+ github.com/prometheus/common v0.35.0 h1:Eyr+Pw2VymWejHqCugNaQXkAi6KayVNxaHeu6khmFBE= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1668,8 +1659,14 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/qri-io/jsonpointer v0.1.0/go.mod h1:DnJPaYgiKu56EuDp8TU5wFLdZIcAnb/uH9v37ZaMV64= github.com/qri-io/jsonschema v0.1.1/go.mod h1:QpzJ6gBQ0GYgGmh7mDQ1YsvvhSgE4rYj0k8t5MBOmUY= -github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac h1:wBGhHdXKICZmvAPWS8gQoMyOWDH7QAi9bU4Z1nDWnFU= -github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac/go.mod h1:67sLWL17mVlO1HFROaTBmU71NB4R8UNCesFHhg0f6LQ= +github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= +github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= +github.com/quic-go/qtls-go1-19 v0.2.1 h1:aJcKNMkH5ASEJB9FXNeZCyTEIHU1J7MmHyz1Q1TSG1A= +github.com/quic-go/qtls-go1-19 v0.2.1/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= +github.com/quic-go/qtls-go1-20 v0.1.1 h1:KbChDlg82d3IHqaj2bn6GfKRj84Per2VGf5XV3wSwQk= +github.com/quic-go/qtls-go1-20 v0.1.1/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= +github.com/quic-go/quic-go v0.33.0 h1:ItNoTDN/Fm/zBlq769lLJc8ECe9gYaW40veHCCco7y0= +github.com/quic-go/quic-go v0.33.0/go.mod h1:YMuhaAV9/jIu0XclDXwZPAsP/2Kgr5yMYhe9oxhhOFA= github.com/rboyer/safeio v0.2.1/go.mod h1:Cq/cEPK+YXFn622lsQ0K4KsPZSPtaptHHEldsy7Fmig= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1716,6 +1713,7 @@ github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5/go.mod h1:BeybITEsBEg6 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= @@ -1724,29 +1722,7 @@ github.com/shirou/gopsutil/v3 v3.20.10/go.mod h1:igHnfak0qnw1biGeI2qKQvu0ZkwvEkU github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= -github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= -github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= -github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= -github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= -github.com/shurcooL/gofontwoff v0.0.0-20180329035133-29b52fc0a18d/go.mod h1:05UtEgK5zq39gLST6uB0cf3NEHjETfB4Fgr3Gx5R9Vw= -github.com/shurcooL/gopherjslib v0.0.0-20160914041154-feb6d3990c2c/go.mod h1:8d3azKNyqcHP1GaQE/c6dDgjkgSx2BZ4IoEi4F1reUI= -github.com/shurcooL/highlight_diff v0.0.0-20170515013008-09bb4053de1b/go.mod h1:ZpfEhSmds4ytuByIcDnOLkTHGUI6KNqRNPDLHDk+mUU= -github.com/shurcooL/highlight_go v0.0.0-20181028180052-98c3abbbae20/go.mod h1:UDKB5a1T23gOMUJrI+uSuH0VRDStOiUVSjBTRDVBVag= -github.com/shurcooL/home v0.0.0-20181020052607-80b7ffcb30f9/go.mod h1:+rgNQw2P9ARFAs37qieuu7ohDNQ3gds9msbT2yn85sg= -github.com/shurcooL/htmlg v0.0.0-20170918183704-d01228ac9e50/go.mod h1:zPn1wHpTIePGnXSHpsVPWEktKXHr6+SS6x/IKRb7cpw= -github.com/shurcooL/httperror v0.0.0-20170206035902-86b7830d14cc/go.mod h1:aYMfkZ6DWSJPJ6c4Wwz3QtW22G7mf/PEgaB9k/ik5+Y= -github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/httpgzip v0.0.0-20180522190206-b1c53ac65af9/go.mod h1:919LwcH0M7/W4fcZ0/jy0qGght1GIhqyS/EgWGH2j5Q= -github.com/shurcooL/issues v0.0.0-20181008053335-6292fdc1e191/go.mod h1:e2qWDig5bLteJ4fwvDAc2NHzqFEthkqn7aOZAOpj+PQ= -github.com/shurcooL/issuesapp v0.0.0-20180602232740-048589ce2241/go.mod h1:NPpHK2TI7iSaM0buivtFUc9offApnI0Alt/K8hcHy0I= -github.com/shurcooL/notifications v0.0.0-20181007000457-627ab5aea122/go.mod h1:b5uSkrEVM1jQUspwbixRBhaIjIzL2xazXp6kntxYle0= -github.com/shurcooL/octicon v0.0.0-20181028054416-fa4f57f9efb2/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ= -github.com/shurcooL/reactions v0.0.0-20181006231557-f2e0b4ca5b82/go.mod h1:TCR1lToEk4d2s07G3XGfz2QrgHXg4RJBvjrOozvoWfk= -github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= -github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -1772,8 +1748,6 @@ github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e h1:3OgWYFw7jxCZPc github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e/go.mod h1:fKZCUVdirrxrBpwd9wb+lSoVixvpwAu8eHzbQB2tums= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= -github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:UdhH50NIW0fCiwBSr0co2m7BnFLdv4fQTgdqdJTHFeE= -github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -1845,7 +1819,6 @@ github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tailscale/tscert v0.0.0-20220316030059-54bbcb9f74e2 h1:xwMw7LFhV9dbvot9A7NLClP9udqbjrQlIwWMH8e7uiQ= github.com/tailscale/tscert v0.0.0-20220316030059-54bbcb9f74e2/go.mod h1:hL4gB6APAasMR2NNi/JHzqKkxW3EPQlFgLEq9PMi2t0= -github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490 h1:mmz27tVi2r70JYnm5y0Zk8w0Qzsx+vfUw3oqSyrEfP8= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.490/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= @@ -1864,10 +1837,10 @@ github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/ github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk= github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305 h1:y/1cL5AL2oRcfzz8CAHHhR6kDDfIOT0WEyH5k40sccM= github.com/tonistiigi/vt100 v0.0.0-20190402012908-ad4c4a574305/go.mod h1:gXOLibKqQTRAVuVZ9gX7G9Ykky8ll8yb4slxsEMoY0c= -github.com/traefik/paerser v0.1.9 h1:x5hZafOt/yogLvr6upoSOYIAn2nh2GsnLb236MOzd4I= -github.com/traefik/paerser v0.1.9/go.mod h1:Dk3Bfz6Zyj13/S8pJyRdx/FNvXlsVRVbtp0UK4ZSiA0= -github.com/traefik/yaegi v0.14.3 h1:LqA0k8DKwvRMc+msfQjNusphHJc+r6WC5tZU5TmUFOM= -github.com/traefik/yaegi v0.14.3/go.mod h1:AVRxhaI2G+nUsaM1zyktzwXn69G3t/AuTDrCiTds9p0= +github.com/traefik/paerser v0.2.0 h1:zqCLGSXoNlcBd+mzqSCLjon/I6phqIjeJL2xFB2ysgQ= +github.com/traefik/paerser v0.2.0/go.mod h1:afzaVcgF8A+MpTnPG4wBr4whjanCSYA6vK5RwaYVtRc= +github.com/traefik/yaegi v0.15.0 h1:ScDDfQXTT75rKvcsMcP84rOxHsZ8b6NiQJyGocGDB7g= +github.com/traefik/yaegi v0.15.0/go.mod h1:AVRxhaI2G+nUsaM1zyktzwXn69G3t/AuTDrCiTds9p0= github.com/transip/gotransip/v6 v6.17.0 h1:2RCyqYqz5+Ej8z96EyE4sf6tQrrfEBaFDO0LliSl6+8= github.com/transip/gotransip/v6 v6.17.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= @@ -1885,6 +1858,8 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= +github.com/ultradns/ultradns-go-sdk v1.4.0-20221107152238-f3f1d1d h1:pLMpEtrkiaeA2NY6CzA2+K75YnY6c5ka02SbxQ9YgSo= +github.com/ultradns/ultradns-go-sdk v1.4.0-20221107152238-f3f1d1d/go.mod h1:IgdoVzrGYzq4H4IGI0DAVnM3CbcuQDSxEP4s/j6cztI= github.com/unrolled/render v1.0.2 h1:dGS3EmChQP3yOi1YeFNO/Dx+MbWZhdvhQJTXochM5bs= github.com/unrolled/render v1.0.2/go.mod h1:gN9T0NhL4Bfbwu8ann7Ry/TGHYfosul+J0obPf6NBdM= github.com/unrolled/secure v1.0.9 h1:BWRuEb1vDrBFFDdbCnKkof3gZ35I/bnHGyt0LB0TNyQ= @@ -1900,8 +1875,6 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vdemeester/shakers v0.1.0 h1:K+n9sSyUCg2ywmZkv+3c7vsYZfivcfKhMh8kRxCrONM= github.com/vdemeester/shakers v0.1.0/go.mod h1:IZ1HHynUOQt32iQ3rvAeVddXLd19h/6LWiKsh9RZtAQ= -github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= -github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/vinyldns/go-vinyldns v0.9.16 h1:GZJStDkcCk1F1AcRc64LuuMh+ENL8pHA0CVd4ulRMcQ= github.com/vinyldns/go-vinyldns v0.9.16/go.mod h1:5qIJOdmzAnatKjurI+Tl4uTus7GJKJxb+zitufjHs3Q= github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= @@ -1914,8 +1887,8 @@ github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6Ac github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmware/govmomi v0.18.0/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/vulcand/oxy/v2 v2.0.0-20221121151423-d5cb734e4467 h1:Dbv3KJLgwtDKLpCZzTf1ISeG5ZYudPaLfTdYi4O2dSU= -github.com/vulcand/oxy/v2 v2.0.0-20221121151423-d5cb734e4467/go.mod h1:0kOEB8mKzSeGHknF53gTM47UEvQnPoAPnM+58baqn2o= +github.com/vulcand/oxy/v2 v2.0.0-20230227135449-a0e9f7ff1040 h1:L+nLher4530BUkyOpxxBsl2SLbrD4fSlDH5rGZ8DRBM= +github.com/vulcand/oxy/v2 v2.0.0-20230227135449-a0e9f7ff1040/go.mod h1:A2voDnpONyqdplUDK0lt5y4XHLiBXPBw7iQES8+ZWRw= github.com/vulcand/predicate v1.2.0 h1:uFsW1gcnnR7R+QTID+FVcs0sSYlIGntoGOTb3rQJt50= github.com/vulcand/predicate v1.2.0/go.mod h1:VipoNYXny6c8N381zGUWkjuuNHiRbeAZhE7Qm9c+2GA= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= @@ -1947,6 +1920,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -1985,7 +1959,6 @@ go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsX go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= -go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -1998,32 +1971,32 @@ go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/collector/pdata v0.64.1 h1:8E06uHr0nnenGftFwhwdenA88QhVnF4dJam+qVXgdVg= go.opentelemetry.io/collector/pdata v0.64.1/go.mod h1:IzvXUGQml2mrnvdb8zIlEW3qQs9oFLdD2hLwJdZ+pek= -go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= -go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= -go.opentelemetry.io/otel/bridge/opentracing v1.11.1 h1:/ZBsgjXWUpiZ5M9zm+Ft3kuDUGErIGcEJbKRIsFN6jA= -go.opentelemetry.io/otel/bridge/opentracing v1.11.1/go.mod h1:vw9hN4H+G0ek+XQtxP+Mm1McLcmdx2FXHNrWn2bBqxU= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 h1:X2GndnMCsUPh6CiY2a+frAbNsXaPLbB0soHRYhAZ5Ig= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1/go.mod h1:i8vjiSzbiUC7wOQplijSXMYUpNM93DtlS5CbUT+C6oQ= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.33.0 h1:OT/UjHcjog4A1s1UMCtyehIKS+vpjM5Du0r7KGsH6TE= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.33.0/go.mod h1:0XctNDHEWmiSDIU8NPbJElrK05gBJFcYlGP4FMGo4g4= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.33.0 h1:1SVtGtRsNyGgv1fRfNXfh+sJowIwzF0gkf+61lvTgdg= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.33.0/go.mod h1:ryB27ubOBXsiqfh6MwtSdx5knzbSZtjvPnMMmt3AykQ= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.33.0 h1:NoG4v01cdLZfOeNGBQmSe4f4SeP+fx8I/0qzRgTKsGI= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.33.0/go.mod h1:6anbDXBcTp3Qit87pfFmT0paxTJ8sWRccTNYVywN/H8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1 h1:MEQNafcNCB0uQIti/oHgU7CZpUMYQ7qigBwMVKycHvc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1/go.mod h1:19O5I2U5iys38SsmT2uDJja/300woyzE1KPIQxEUBUc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1 h1:LYyG/f1W/jzAix16jbksJfMQFpOH/Ma6T639pVPMgfI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1/go.mod h1:QrRRQiY3kzAoYPNLP0W/Ikg0gR6V3LMc+ODSxr7yyvg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.1 h1:tFl63cpAAcD9TOU6U8kZU7KyXuSRYAZlbx1C61aaB74= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.1/go.mod h1:X620Jww3RajCJXw/unA+8IRTgxkdS7pi+ZwK9b7KUJk= -go.opentelemetry.io/otel/metric v0.33.0 h1:xQAyl7uGEYvrLAiV/09iTJlp1pZnQ9Wl793qbVvED1E= -go.opentelemetry.io/otel/metric v0.33.0/go.mod h1:QlTYc+EnYNq/M2mNk1qDDMRLpqCOj2f/r5c7Fd5FYaI= -go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZpKxs= -go.opentelemetry.io/otel/sdk v1.11.1/go.mod h1:/l3FE4SupHJ12TduVjUkZtlfFqDCQJlOlithYrdktys= -go.opentelemetry.io/otel/sdk/metric v0.33.0 h1:oTqyWfksgKoJmbrs2q7O7ahkJzt+Ipekihf8vhpa9qo= -go.opentelemetry.io/otel/sdk/metric v0.33.0/go.mod h1:xdypMeA21JBOvjjzDUtD0kzIcHO/SPez+a8HOzJPGp0= -go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= -go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= +go.opentelemetry.io/otel v1.11.2 h1:YBZcQlsVekzFsFbjygXMOXSs6pialIZxcjfO/mBDmR0= +go.opentelemetry.io/otel v1.11.2/go.mod h1:7p4EUV+AqgdlNV9gL97IgUZiVR3yrFXYo53f9BM3tRI= +go.opentelemetry.io/otel/bridge/opentracing v1.11.2 h1:Wx51zQDSZDNo5wxMPhkPwzgpUZLQYYDtT41LCcl7opg= +go.opentelemetry.io/otel/bridge/opentracing v1.11.2/go.mod h1:kBrIQ2vqDIqtuS7Np7ALjmm8Tml7yxgsAGQwBhNvuU0= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2 h1:htgM8vZIF8oPSCxa341e3IZ4yr/sKxgu8KZYllByiVY= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2/go.mod h1:rqbht/LlhVBgn5+k3M5QK96K5Xb0DvXpMJ5SFQpY6uw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.34.0 h1:kpskzLZ60cJ48SJ4uxWa6waBL+4kSV6nVK8rP+QM8Wg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.34.0/go.mod h1:4+x3i62TEegDHuzNva0bMcAN8oUi5w4liGb1d/VgPYo= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.34.0 h1:e7kFb4pJLbhJgAwUdoVTHzB9pGujs5O8/7gFyZL88fg= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.34.0/go.mod h1:3x00m9exjIbhK+zTO4MsCSlfbVmgvLP0wjDgDKa/8bw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.34.0 h1:t4Ajxj8JGjxkqoBtbkCOY2cDUl9RwiNE9LPQavooi9U= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.34.0/go.mod h1:WO7omosl4P7JoanH9NgInxDxEn2F2M5YinIh8EyeT8w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.2 h1:fqR1kli93643au1RKo0Uma3d2aPQKT+WBKfTSBaKbOc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.2/go.mod h1:5Qn6qvgkMsLDX+sYK64rHb1FPhpn0UtxF+ouX1uhyJE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.2 h1:ERwKPn9Aer7Gxsc0+ZlutlH1bEEAUXAUhqm3Y45ABbk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.2/go.mod h1:jWZUM2MWhWCJ9J9xVbRx7tzK1mXKpAlze4CeulycwVY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.2 h1:Us8tbCmuN16zAnK5TC69AtODLycKbwnskQzaB6DfFhc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.2/go.mod h1:GZWSQQky8AgdJj50r1KJm8oiQiIPaAX7uZCFQX9GzC8= +go.opentelemetry.io/otel/metric v0.34.0 h1:MCPoQxcg/26EuuJwpYN1mZTeCYAUGx8ABxfW07YkjP8= +go.opentelemetry.io/otel/metric v0.34.0/go.mod h1:ZFuI4yQGNCupurTXCwkeD/zHBt+C2bR7bw5JqUm/AP8= +go.opentelemetry.io/otel/sdk v1.11.2 h1:GF4JoaEx7iihdMFu30sOyRx52HDHOkl9xQ8SMqNXUiU= +go.opentelemetry.io/otel/sdk v1.11.2/go.mod h1:wZ1WxImwpq+lVRo4vsmSOxdd+xwoUJ6rqyLc3SyX9aU= +go.opentelemetry.io/otel/sdk/metric v0.34.0 h1:7ElxfQpXCFZlRTvVRTkcUvK8Gt5DC8QzmzsLsO2gdzo= +go.opentelemetry.io/otel/sdk/metric v0.34.0/go.mod h1:l4r16BIqiqPy5rd14kkxllPy/fOI4tWo1jkpD9Z3ffQ= +go.opentelemetry.io/otel/trace v1.11.2 h1:Xf7hWSF2Glv0DE3MH7fBHvtpSBsjcBUe5MYAmZM/+y0= +go.opentelemetry.io/otel/trace v1.11.2/go.mod h1:4N+yC7QEz7TTsG9BSRLNAa63eg5E06ObSbKPmxQ/pKA= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -2035,6 +2008,7 @@ go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= @@ -2050,22 +2024,18 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= -go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org/intern v0.0.0-20211027215823-ae77deb06f29 h1:UXLjNohABv4S58tHmeuIZDO6e3mHpW2Dx33gaNt03LE= go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA= go4.org/unsafe/assume-no-moving-gc v0.0.0-20211027215541-db492cf91b37/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760 h1:FyBZqvoA/jbNzuAWLQE2kG820zMAkcilx6BMjGbL/E4= go4.org/unsafe/assume-no-moving-gc v0.0.0-20220617031537-928513b29760/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E= -golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190404164418-38d8ce5564a5/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= @@ -2076,15 +2046,14 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191028145041-f83a4685e152/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200422194213-44a606286825/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -2102,8 +2071,9 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE= +golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -2118,12 +2088,11 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20221114191408-850992195362 h1:NoHlPRbyl1VFI6FjwHtPQCN7wAMXI6cKcqrmXhOOfBQ= -golang.org/x/exp v0.0.0-20221114191408-850992195362/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= +golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -2149,6 +2118,7 @@ golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hM golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2158,8 +2128,6 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2167,7 +2135,6 @@ golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -2220,16 +2187,22 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10 h1:Frnccbp+ok2GkUS2tC84yAq/U9Vg+0sIO7aRL3T4Xnc= -golang.org/x/net v0.3.1-0.20221206200815-1e63c2f08a10/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180724155351-3d292e4d0cdc/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2247,9 +2220,12 @@ golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.4.0 h1:NF0gk8LVPg1Ml7SSbGyySuoxdsXitj7TvgvuRxIMc/M= +golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2261,15 +2237,16 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2279,7 +2256,6 @@ golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2385,24 +2361,40 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= -golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2413,8 +2405,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2424,14 +2417,13 @@ golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858 h1:Dpdu/EMxGMFgq0CeYMh4fazTD2vtlZRYE7wyynxJb9U= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2503,13 +2495,17 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= @@ -2517,9 +2513,6 @@ gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -2550,11 +2543,22 @@ google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNe google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0 h1:4t9zuDlHLcIx0ZEhmXEeFVCRsiOgpgn2QOH9N0MNjPI= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.98.0 h1:yxZrcxXESimy6r6mdL5Q6EnZwmewDJK2dVg3g75s5Dg= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2565,10 +2569,6 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= -google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -2617,6 +2617,7 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= @@ -2632,14 +2633,35 @@ google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21 h1:hrbNEivu7Zn1pxvHk6MBrq9iE22woVILTHqexqBxe6I= -google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 h1:jmIfw8+gSvXcZSgaFAGyInDXeWzUhvYH57G/5GKMn70= +google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -2673,11 +2695,16 @@ google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= -google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/examples v0.0.0-20201130180447-c456688b1860/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -2746,9 +2773,8 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= @@ -2772,7 +2798,6 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2902,6 +2927,4 @@ sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= -sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= -sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= vbom.ml/util v0.0.0-20180919145318-efcd4e0f9787/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/integration/access_log_test.go b/integration/access_log_test.go index d2f5715db5dd2082819cfc81187cba91e3ea7e6a..272a1b37117988acd46950b4d67e94ffc25f38d5 100644 --- a/integration/access_log_test.go +++ b/integration/access_log_test.go @@ -13,8 +13,8 @@ import ( "github.com/go-check/check" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/middlewares/accesslog" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/middlewares/accesslog" checker "github.com/vdemeester/shakers" ) diff --git a/integration/acme_test.go b/integration/acme_test.go index 73e9958bbfe726ee3a222a01117362189fcbf2d8..fe5fc413b1bf6803f32f4f385e265f62126743fa 100644 --- a/integration/acme_test.go +++ b/integration/acme_test.go @@ -12,11 +12,11 @@ import ( "github.com/go-check/check" "github.com/miekg/dns" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/provider/acme" - "github.com/traefik/traefik/v2/pkg/testhelpers" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/provider/acme" + "github.com/traefik/traefik/v3/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/types" checker "github.com/vdemeester/shakers" ) diff --git a/integration/conf_throttling_test.go b/integration/conf_throttling_test.go index 6c4333b35c5e1a46e217254182246959c62196c8..3a7b89baabfcf9d120892a004d34d6809fafadf2 100644 --- a/integration/conf_throttling_test.go +++ b/integration/conf_throttling_test.go @@ -11,8 +11,8 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/config/dynamic" checker "github.com/vdemeester/shakers" ) diff --git a/integration/consul_catalog_test.go b/integration/consul_catalog_test.go index bdefbd4cc353955c987b8d44b59c3623738ad62d..bf0db5da1854e792fa0524d6490909eecc4b03f0 100644 --- a/integration/consul_catalog_test.go +++ b/integration/consul_catalog_test.go @@ -9,7 +9,7 @@ import ( "github.com/go-check/check" "github.com/hashicorp/consul/api" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/consul_test.go b/integration/consul_test.go index 357f03deaa1416add8f6d702a97701315917d05d..441d56db7476af0c81dca9e6a717e4c541497249 100644 --- a/integration/consul_test.go +++ b/integration/consul_test.go @@ -16,8 +16,8 @@ import ( "github.com/kvtools/valkeyrie" "github.com/kvtools/valkeyrie/store" "github.com/pmezard/go-difflib/difflib" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/api" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/api" checker "github.com/vdemeester/shakers" ) diff --git a/integration/docker_compose_test.go b/integration/docker_compose_test.go index 2c2969fe02ff7456777cd30697dc8312ba4e9618..39347dca599628d8a436d36720288d6dbfcff469 100644 --- a/integration/docker_compose_test.go +++ b/integration/docker_compose_test.go @@ -8,9 +8,9 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/api" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/api" + "github.com/traefik/traefik/v3/pkg/testhelpers" checker "github.com/vdemeester/shakers" ) diff --git a/integration/docker_test.go b/integration/docker_test.go index fe7051f7f621e776482dbe29f785e4eda603e71f..dad1ef809ceb80626aaa2bf51834386673e1c6ed 100644 --- a/integration/docker_test.go +++ b/integration/docker_test.go @@ -9,7 +9,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/error_pages_test.go b/integration/error_pages_test.go index 436b2cc96cd6beec32009caafbccbc19ae19116e..8a6deba8982baca0f5cabe37cf589b0077355c82 100644 --- a/integration/error_pages_test.go +++ b/integration/error_pages_test.go @@ -2,11 +2,12 @@ package integration import ( "net/http" + "net/http/httptest" "os" "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) @@ -29,7 +30,7 @@ func (s *ErrorPagesSuite) TestSimpleConfiguration(c *check.C) { file := s.adaptFile(c, "fixtures/error_pages/simple.toml", struct { Server1 string Server2 string - }{s.BackendIP, s.ErrorPageIP}) + }{"http://" + s.BackendIP + ":80", s.ErrorPageIP}) defer os.Remove(file) cmd, display := s.traefikCmd(withConfigFile(file)) @@ -67,3 +68,33 @@ func (s *ErrorPagesSuite) TestErrorPage(c *check.C) { err = try.Request(frontendReq, 2*time.Second, try.BodyContains("An error occurred.")) c.Assert(err, checker.IsNil) } + +func (s *ErrorPagesSuite) TestErrorPageFlush(c *check.C) { + srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + rw.Header().Add("Transfer-Encoding", "chunked") + rw.WriteHeader(http.StatusInternalServerError) + _, _ = rw.Write([]byte("KO")) + })) + + file := s.adaptFile(c, "fixtures/error_pages/simple.toml", struct { + Server1 string + Server2 string + }{srv.URL, s.ErrorPageIP}) + defer os.Remove(file) + + cmd, display := s.traefikCmd(withConfigFile(file)) + defer display(c) + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer s.killCmd(cmd) + + frontendReq, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8080", nil) + c.Assert(err, checker.IsNil) + frontendReq.Host = "test.local" + + err = try.Request(frontendReq, 2*time.Second, + try.BodyContains("An error occurred."), + try.HasHeaderValue("Content-Type", "text/html", true), + ) + c.Assert(err, checker.IsNil) +} diff --git a/integration/etcd_test.go b/integration/etcd_test.go index 1ffd9225230943f8c0dd68558ed5848c3ed9272e..a9e9bb53245044f99e2ec9893d2e4800347e2d17 100644 --- a/integration/etcd_test.go +++ b/integration/etcd_test.go @@ -15,8 +15,8 @@ import ( "github.com/kvtools/valkeyrie" "github.com/kvtools/valkeyrie/store" "github.com/pmezard/go-difflib/difflib" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/api" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/api" checker "github.com/vdemeester/shakers" ) diff --git a/integration/file_test.go b/integration/file_test.go index 5537638c25871b9906fc5575ba86cf979e680ccd..38c30db358edb16f93c6154dc064574ccb735183 100644 --- a/integration/file_test.go +++ b/integration/file_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/fixtures/error_pages/simple.toml b/integration/fixtures/error_pages/simple.toml index a60f7393d6dfe03e349aae4e01f321236d8a3e52..9ff846f7497d54c050f0f2256d34459ecd221f40 100644 --- a/integration/fixtures/error_pages/simple.toml +++ b/integration/fixtures/error_pages/simple.toml @@ -31,7 +31,7 @@ [http.services.service1.loadBalancer] passHostHeader = true [[http.services.service1.loadBalancer.servers]] - url = "http://{{.Server1}}:80" + url = "{{.Server1}}" [http.services.error.loadBalancer] [[http.services.error.loadBalancer.servers]] diff --git a/integration/fixtures/k8s/01-traefik-crd.yml b/integration/fixtures/k8s/01-traefik-crd.yml index 4a7f19a662c199de5184d0b942fab96b3f6e50bb..37849dedc6f7291d86569326348804565a13bfb6 100644 --- a/integration/fixtures/k8s/01-traefik-crd.yml +++ b/integration/fixtures/k8s/01-traefik-crd.yml @@ -6,9 +6,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: ingressroutes.traefik.containo.us + name: ingressroutes.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: IngressRoute listKind: IngressRouteList @@ -104,6 +104,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs + or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes @@ -274,9 +281,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: ingressroutetcps.traefik.containo.us + name: ingressroutetcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: IngressRouteTCP listKind: IngressRouteTCPList @@ -357,6 +364,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs + or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean port: anyOf: - type: integer @@ -373,15 +387,16 @@ spec: to use. type: integer type: object - terminationDelay: - description: TerminationDelay defines the deadline that - the proxy sets, after one of its connected peers indicates - it has closed the writing capability of its connection, - to close the reading capability as well, hence fully - terminating the connection. It is a duration in milliseconds, - defaulting to 100. A negative value means an infinite - deadline (i.e. the reading capability is never closed). - type: integer + serversTransport: + description: ServersTransport defines the name of ServersTransportTCP + resource to use. It allows to configure the transport + between Traefik and your servers. Can only be used on + a Kubernetes Service. + type: string + tls: + description: TLS determines whether to use TLS when dialing + with the backend. + type: boolean weight: description: Weight defines the weight used when balancing requests between multiple Kubernetes Service. @@ -485,9 +500,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: ingressrouteudps.traefik.containo.us + name: ingressrouteudps.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: IngressRouteUDP listKind: IngressRouteUDPList @@ -542,6 +557,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs + or if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean port: anyOf: - type: integer @@ -583,9 +605,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: middlewares.traefik.containo.us + name: middlewares.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: Middleware listKind: MiddlewareList @@ -818,6 +840,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if + the only child is the Kubernetes Service clusterIP. The + Kubernetes Service itself does load-balance to the pods. + By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. @@ -1478,9 +1507,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: middlewaretcps.traefik.containo.us + name: middlewaretcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: MiddlewareTCP listKind: MiddlewareTCPList @@ -1550,9 +1579,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: serverstransports.traefik.containo.us + name: serverstransports.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: ServersTransport listKind: ServersTransportList @@ -1691,9 +1720,131 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: tlsoptions.traefik.containo.us + name: serverstransporttcps.traefik.io spec: - group: traefik.containo.us + group: traefik.io + names: + kind: ServersTransportTCP + listKind: ServersTransportTCPList + plural: serverstransporttcps + singular: serverstransporttcp + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: 'ServersTransportTCP is the CRD implementation of a TCPServersTransport. + If no tcpServersTransport is specified, a default one named default@internal + will be used. The default@internal tcpServersTransport can be configured + in the static configuration. More info: https://doc.traefik.io/traefik/v3.0/routing/services/#serverstransport_3' + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ServersTransportTCPSpec defines the desired state of a ServersTransportTCP. + properties: + dialKeepAlive: + anyOf: + - type: integer + - type: string + description: DialKeepAlive is the interval between keep-alive probes + for an active network connection. If zero, keep-alive probes are + sent with a default value (currently 15 seconds), if supported by + the protocol and operating system. Network protocols or operating + systems that do not support keep-alives ignore this field. If negative, + keep-alive probes are disabled. + x-kubernetes-int-or-string: true + dialTimeout: + anyOf: + - type: integer + - type: string + description: DialTimeout is the amount of time to wait until a connection + to a backend server can be established. + x-kubernetes-int-or-string: true + terminationDelay: + anyOf: + - type: integer + - type: string + description: TerminationDelay defines the delay to wait before fully + terminating the connection, after one connected peer has closed + its writing capability. + x-kubernetes-int-or-string: true + tls: + description: TLS defines the TLS configuration + properties: + certificatesSecrets: + description: CertificatesSecrets defines a list of secret storing + client certificates for mTLS. + items: + type: string + type: array + insecureSkipVerify: + description: InsecureSkipVerify disables TLS certificate verification. + type: boolean + peerCertURI: + description: MaxIdleConnsPerHost controls the maximum idle (keep-alive) + to keep per-host. PeerCertURI defines the peer cert URI used + to match against SAN URI during the peer certificate verification. + type: string + rootCAsSecrets: + description: RootCAsSecrets defines a list of CA secret used to + validate self-signed certificates. + items: + type: string + type: array + serverName: + description: ServerName defines the server name used to contact + the server. + type: string + spiffe: + description: Spiffe defines the SPIFFE configuration. + properties: + ids: + description: IDs defines the allowed SPIFFE IDs (takes precedence + over the SPIFFE TrustDomain). + items: + type: string + type: array + trustDomain: + description: TrustDomain defines the allowed SPIFFE trust + domain. + type: string + type: object + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.2 + creationTimestamp: null + name: tlsoptions.traefik.io +spec: + group: traefik.io names: kind: TLSOption listKind: TLSOptionList @@ -1798,9 +1949,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: tlsstores.traefik.containo.us + name: tlsstores.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: TLSStore listKind: TLSStoreList @@ -1897,9 +2048,9 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.6.2 creationTimestamp: null - name: traefikservices.traefik.containo.us + name: traefikservices.traefik.io spec: - group: traefik.containo.us + group: traefik.io names: kind: TraefikService listKind: TraefikServiceList @@ -1966,6 +2117,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or + if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. @@ -2057,6 +2215,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or if the + only child is the Kubernetes Service clusterIP. The Kubernetes + Service itself does load-balance to the pods. By default, NativeLB + is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. By default, @@ -2154,6 +2319,13 @@ spec: description: Namespace defines the namespace of the referenced Kubernetes Service or TraefikService. type: string + nativeLB: + description: NativeLB controls, when creating the load-balancer, + whether the LB's children are directly the pods IPs or + if the only child is the Kubernetes Service clusterIP. + The Kubernetes Service itself does load-balance to the + pods. By default, NativeLB is false. + type: boolean passHostHeader: description: PassHostHeader defines whether the client Host header is forwarded to the upstream Kubernetes Service. diff --git a/integration/fixtures/k8s/03-ingressroute.yml b/integration/fixtures/k8s/03-ingressroute.yml index c040988b54d231c23cc00498a11a269e8efca3e4..d00f4e34ef4419e72557fba1dd119f62cf734b5d 100644 --- a/integration/fixtures/k8s/03-ingressroute.yml +++ b/integration/fixtures/k8s/03-ingressroute.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/integration/fixtures/k8s/03-tlsoption.yml b/integration/fixtures/k8s/03-tlsoption.yml index 7c5df10fc1b6a08a2c2e81c47b8c2b9b6ad98b00..1d57c5065cdbcc54fc42faf0f6a56197cac3129e 100644 --- a/integration/fixtures/k8s/03-tlsoption.yml +++ b/integration/fixtures/k8s/03-tlsoption.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: mytlsoption diff --git a/integration/fixtures/k8s/03-tlsstore.yml b/integration/fixtures/k8s/03-tlsstore.yml index 5dea5d0fd09502b3ed85e7e0650a7dc2a8934709..add5979ccb69ac529d4d5bf24b5405c7cbfe7798 100644 --- a/integration/fixtures/k8s/03-tlsstore.yml +++ b/integration/fixtures/k8s/03-tlsstore.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSStore metadata: name: mytlsstore diff --git a/integration/fixtures/k8s/04-ingressroute.yml b/integration/fixtures/k8s/04-ingressroute.yml index 85643e638bb410ece0151495d768a06e70fdea2d..2d8670c4af471114cdb5ec5fbd20b522d1c80325 100644 --- a/integration/fixtures/k8s/04-ingressroute.yml +++ b/integration/fixtures/k8s/04-ingressroute.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: mychain @@ -10,7 +10,7 @@ spec: - name: stripprefix --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: stripprefix @@ -22,7 +22,7 @@ spec: - /tobestripped --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test2.route diff --git a/integration/fixtures/k8s/05-ingressroutetcp.yml b/integration/fixtures/k8s/05-ingressroutetcp.yml index a717a1999dababad2032918578210c5ee448541e..1059648f0828b354f2ec45f6fa2aaa6931338f2c 100644 --- a/integration/fixtures/k8s/05-ingressroutetcp.yml +++ b/integration/fixtures/k8s/05-ingressroutetcp.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test3.route diff --git a/integration/fixtures/k8s/05-ingressrouteudp.yml b/integration/fixtures/k8s/05-ingressrouteudp.yml index 358559c230b7bcda2f884c0a81b9a107ae787edc..54da9a2c916e84fb02d3057e6fe5d491cb0eb71b 100644 --- a/integration/fixtures/k8s/05-ingressrouteudp.yml +++ b/integration/fixtures/k8s/05-ingressrouteudp.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test3.route diff --git a/integration/fixtures/k8s/06-ingressroute-traefikservices.yml b/integration/fixtures/k8s/06-ingressroute-traefikservices.yml index 3e096d1a75e20255d6215e32340f7b195da1af28..d979bc425ae3800467058cb721cbbf2b8a4797c8 100644 --- a/integration/fixtures/k8s/06-ingressroute-traefikservices.yml +++ b/integration/fixtures/k8s/06-ingressroute-traefikservices.yml @@ -1,5 +1,5 @@ --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror1 @@ -14,7 +14,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 @@ -29,7 +29,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test3.route @@ -45,7 +45,7 @@ spec: - name: wrr1 kind: TraefikService --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: api.route diff --git a/integration/fixtures/k8s/07-ingressroute-cross-namespace.yml b/integration/fixtures/k8s/07-ingressroute-cross-namespace.yml index fbdeb88a44171b973a7e802735e5f76e94f329c9..ef437e25b3bee831910ec483c00fa80c8b50cf9b 100644 --- a/integration/fixtures/k8s/07-ingressroute-cross-namespace.yml +++ b/integration/fixtures/k8s/07-ingressroute-cross-namespace.yml @@ -20,7 +20,7 @@ spec: task: whoami --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test6.route @@ -65,7 +65,7 @@ spec: - name: test-errorpage --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr2 @@ -78,7 +78,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr3 @@ -92,7 +92,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: stripprefix2 @@ -104,7 +104,7 @@ spec: - /tobestripped --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-errorpage diff --git a/integration/fixtures/k8s/07-ingressroute-serverstransport.yml b/integration/fixtures/k8s/07-ingressroute-serverstransport.yml index aa1ff9ecc68f7b619751a428a9b3a08b5a63c6d6..8ad7369176c5d9491d09e66958d051e2aeac7d75 100644 --- a/integration/fixtures/k8s/07-ingressroute-serverstransport.yml +++ b/integration/fixtures/k8s/07-ingressroute-serverstransport.yml @@ -1,5 +1,5 @@ --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: testst.route @@ -17,7 +17,7 @@ spec: serversTransport: mytransport --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: mytransport diff --git a/integration/fixtures/marathon/simple.toml b/integration/fixtures/k8s_ingressclass_disabled.toml similarity index 54% rename from integration/fixtures/marathon/simple.toml rename to integration/fixtures/k8s_ingressclass_disabled.toml index d43cdbc2ed3f3e1ee638009f8b051bb7cebfaec0..8afc19e971a0376723a656d34e74d3dda784d9a5 100644 --- a/integration/fixtures/marathon/simple.toml +++ b/integration/fixtures/k8s_ingressclass_disabled.toml @@ -6,17 +6,13 @@ level = "DEBUG" noColor = true +[api] + insecure = true + [entryPoints] [entryPoints.web] address = ":8000" - [entryPoints.traefik] - address = ":9090" - -[api] - insecure = true -[providers] - [providers.marathon] - endpoint = "{{.MarathonURL}}" - watch = true - exposedByDefault = true +[providers.kubernetesIngress] + ingressClass = "traefik-keep" + disableIngressClassLookup = true diff --git a/integration/grpc_test.go b/integration/grpc_test.go index a18975864b4ee0c55f2263f6c797d9414ab5e8ee..bf96e1eceeaaee2794f8950dfb220be6cea81577 100644 --- a/integration/grpc_test.go +++ b/integration/grpc_test.go @@ -12,8 +12,8 @@ import ( "github.com/go-check/check" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/integration/helloworld" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/helloworld" + "github.com/traefik/traefik/v3/integration/try" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" diff --git a/integration/headers_test.go b/integration/headers_test.go index 6e4b7e9b9c766c20e4875ab90dd62ea7a02436be..60fd59578a33390e6415879e7f0aa3f8e66aa1ce 100644 --- a/integration/headers_test.go +++ b/integration/headers_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/healthcheck_test.go b/integration/healthcheck_test.go index 128a447e881d2cea11b12577e752732f68f0b31d..86a93b96de5c47c89ee363c72c147e9aec473a98 100644 --- a/integration/healthcheck_test.go +++ b/integration/healthcheck_test.go @@ -10,7 +10,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/hostresolver_test.go b/integration/hostresolver_test.go index d765520168ccf3c18f617ecebfea344dcc9197ac..e69e33dd91fe7e4cc8f897bfb9adba83691b7a18 100644 --- a/integration/hostresolver_test.go +++ b/integration/hostresolver_test.go @@ -5,7 +5,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/http_test.go b/integration/http_test.go index 6e18fcb80d30975792b6bdc90bb42e1b1d90d253..6e28fa2d7d8ce06da75bc3742ad6dfe7123b6a47 100644 --- a/integration/http_test.go +++ b/integration/http_test.go @@ -8,8 +8,8 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/config/dynamic" checker "github.com/vdemeester/shakers" ) diff --git a/integration/https_test.go b/integration/https_test.go index f16b390db164401d34626df951407882a8a850f0..9814708412f1f47b925ea292013c5623344bd8f9 100644 --- a/integration/https_test.go +++ b/integration/https_test.go @@ -12,9 +12,9 @@ import ( "github.com/BurntSushi/toml" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" checker "github.com/vdemeester/shakers" ) diff --git a/integration/integration_test.go b/integration/integration_test.go index d71409d38df98e270623305267589b54785b8189..6c13e75b3941c9de5c7615810a6dfbd3e043e163 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -31,7 +31,7 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" "github.com/sirupsen/logrus" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/logs" checker "github.com/vdemeester/shakers" ) @@ -91,8 +91,6 @@ func Test(t *testing.T) { } check.Suite(&KeepAliveSuite{}) check.Suite(&LogRotationSuite{}) - check.Suite(&MarathonSuite{}) - check.Suite(&MarathonSuite15{}) if !useVPN { check.Suite(&ProxyProtocolSuite{}) } diff --git a/integration/k8s_test.go b/integration/k8s_test.go index bfb73d93cccbb48fb7228c92bc496c38012e3611..5d54bc3e14eccdf6559163e695718b4015694104 100644 --- a/integration/k8s_test.go +++ b/integration/k8s_test.go @@ -16,8 +16,8 @@ import ( "github.com/go-check/check" "github.com/pmezard/go-difflib/difflib" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/api" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/api" checker "github.com/vdemeester/shakers" ) @@ -128,6 +128,17 @@ func (s *K8sSuite) TestIngressclass(c *check.C) { testConfiguration(c, "testdata/rawdata-ingressclass.json", "8080") } +func (s *K8sSuite) TestDisableIngressclassLookup(c *check.C) { + cmd, display := s.traefikCmd(withConfigFile("fixtures/k8s_ingressclass_disabled.toml")) + defer display(c) + + err := cmd.Start() + c.Assert(err, checker.IsNil) + defer s.killCmd(cmd) + + testConfiguration(c, "testdata/rawdata-ingressclass-disabled.json", "8080") +} + func testConfiguration(c *check.C, path, apiPort string) { err := try.GetRequest("http://127.0.0.1:"+apiPort+"/api/entrypoints", 20*time.Second, try.BodyContains(`"name":"web"`)) c.Assert(err, checker.IsNil) @@ -204,7 +215,7 @@ func matchesConfig(wantConfig string, buf *bytes.Buffer) try.ResponseCondition { // The pods IPs are dynamic, so we cannot predict them, // which is why we have to ignore them in the comparison. rxURL := regexp.MustCompile(`"(url|address)":\s+(".*")`) - sanitizedExpected := rxURL.ReplaceAll(expected, []byte(`"$1": "XXXX"`)) + sanitizedExpected := rxURL.ReplaceAll(bytes.TrimSpace(expected), []byte(`"$1": "XXXX"`)) sanitizedGot := rxURL.ReplaceAll(got, []byte(`"$1": "XXXX"`)) rxServerStatus := regexp.MustCompile(`"http://.*?":\s+(".*")`) diff --git a/integration/keepalive_test.go b/integration/keepalive_test.go index df3bef5750e30c63e5dc9eab4b324f1119af633d..a56cbdd48faae21d1870a29eb569eb3b470cac4b 100644 --- a/integration/keepalive_test.go +++ b/integration/keepalive_test.go @@ -9,7 +9,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/log_rotation_test.go b/integration/log_rotation_test.go index 241e09353c5e2ddd457c93e0dcd99fee667a4736..c753dc7ff529929373029248e407ea10a06767e2 100644 --- a/integration/log_rotation_test.go +++ b/integration/log_rotation_test.go @@ -13,7 +13,7 @@ import ( "github.com/go-check/check" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/marathon15_test.go b/integration/marathon15_test.go deleted file mode 100644 index 493db256a7322d54705ec6e03e8ff364275344bb..0000000000000000000000000000000000000000 --- a/integration/marathon15_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package integration - -import ( - "net/http" - "os" - "time" - - "github.com/gambol99/go-marathon" - "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" - checker "github.com/vdemeester/shakers" -) - -// Marathon test suites. -type MarathonSuite15 struct { - BaseSuite - marathonURL string -} - -func (s *MarathonSuite15) SetUpSuite(c *check.C) { - s.createComposeProject(c, "marathon15") - s.composeUp(c) - - s.marathonURL = "http://" + s.getComposeServiceIP(c, containerNameMarathon) + ":8080" - - // Wait for Marathon readiness prior to creating the client so that we - // don't run into the "all cluster members down" state right from the - // start. - err := try.GetRequest(s.marathonURL+"/v2/leader", 1*time.Minute, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) -} - -func (s *MarathonSuite15) TestConfigurationUpdate(c *check.C) { - // Start Traefik. - file := s.adaptFile(c, "fixtures/marathon/simple.toml", struct { - MarathonURL string - }{s.marathonURL}) - defer os.Remove(file) - cmd, display := s.traefikCmd(withConfigFile(file)) - defer display(c) - err := cmd.Start() - c.Assert(err, checker.IsNil) - defer s.killCmd(cmd) - - // Wait for Traefik to turn ready. - err = try.GetRequest("http://127.0.0.1:8000/", 2*time.Second, try.StatusCodeIs(http.StatusNotFound)) - c.Assert(err, checker.IsNil) - - // Prepare Marathon client. - config := marathon.NewDefaultConfig() - config.URL = s.marathonURL - client, err := marathon.NewClient(config) - c.Assert(err, checker.IsNil) - - // Create test application to be deployed. - app := marathon.NewDockerApplication(). - Name("/whoami"). - CPU(0.1). - Memory(32). - EmptyNetworks(). - AddLabel("traefik.http.Routers.rt.Rule", "PathPrefix(`/service`)") - app.Container. - Expose(80). - Docker. - Container("traefik/whoami") - *app.Networks = append(*app.Networks, *marathon.NewBridgePodNetwork()) - - // Deploy the test application. - deployApplication(c, client, app) - - // Query application via Traefik. - err = try.GetRequest("http://127.0.0.1:8000/service", 30*time.Second, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) - - // Create test application with services to be deployed. - app = marathon.NewDockerApplication(). - Name("/whoami"). - CPU(0.1). - Memory(32). - EmptyNetworks(). - AddLabel("traefik.http.Routers.app.Rule", "PathPrefix(`/app`)") - app.Container. - Expose(80). - Docker. - Container("traefik/whoami") - *app.Networks = append(*app.Networks, *marathon.NewBridgePodNetwork()) - - // Deploy the test application. - deployApplication(c, client, app) - - // Query application via Traefik. - err = try.GetRequest("http://127.0.0.1:8000/app", 30*time.Second, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) -} diff --git a/integration/marathon_test.go b/integration/marathon_test.go deleted file mode 100644 index 5552e0d0b47d9883229bdb9b0b6eb86d6b802f84..0000000000000000000000000000000000000000 --- a/integration/marathon_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package integration - -import ( - "net/http" - "os" - "time" - - "github.com/gambol99/go-marathon" - "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" - checker "github.com/vdemeester/shakers" -) - -const containerNameMarathon = "marathon" - -// Marathon test suites. -type MarathonSuite struct { - BaseSuite - marathonURL string -} - -func (s *MarathonSuite) SetUpSuite(c *check.C) { - s.createComposeProject(c, "marathon") - s.composeUp(c) - - s.marathonURL = "http://" + s.getComposeServiceIP(c, containerNameMarathon) + ":8080" - - // Wait for Marathon readiness prior to creating the client so that we - // don't run into the "all cluster members down" state right from the - // start. - err := try.GetRequest(s.marathonURL+"/v2/leader", 1*time.Minute, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) -} - -func deployApplication(c *check.C, client marathon.Marathon, application *marathon.Application) { - deploy, err := client.UpdateApplication(application, false) - c.Assert(err, checker.IsNil) - // Wait for deployment to complete. - c.Assert(client.WaitOnDeployment(deploy.DeploymentID, 1*time.Minute), checker.IsNil) -} - -func (s *MarathonSuite) TestConfigurationUpdate(c *check.C) { - // Start Traefik. - file := s.adaptFile(c, "fixtures/marathon/simple.toml", struct { - MarathonURL string - }{s.marathonURL}) - defer os.Remove(file) - - cmd, display := s.traefikCmd(withConfigFile(file)) - defer display(c) - err := cmd.Start() - c.Assert(err, checker.IsNil) - defer s.killCmd(cmd) - - // Wait for Traefik to turn ready. - err = try.GetRequest("http://127.0.0.1:8000/", 2*time.Second, try.StatusCodeIs(http.StatusNotFound)) - c.Assert(err, checker.IsNil) - - // Prepare Marathon client. - config := marathon.NewDefaultConfig() - config.URL = s.marathonURL - client, err := marathon.NewClient(config) - c.Assert(err, checker.IsNil) - - // Create test application to be deployed. - app := marathon.NewDockerApplication(). - Name("/whoami"). - CPU(0.1). - Memory(32). - AddLabel("traefik.http.Routers.rt.Rule", "PathPrefix(`/service`)") - app.Container.Docker.Bridged(). - Expose(80). - Container("traefik/whoami") - - // Deploy the test application. - deployApplication(c, client, app) - - // Query application via Traefik. - err = try.GetRequest("http://127.0.0.1:8000/service", 30*time.Second, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) - - // Create test application with services to be deployed. - app = marathon.NewDockerApplication(). - Name("/whoami"). - CPU(0.1). - Memory(32). - AddLabel("traefik.http.Routers.app.Rule", "PathPrefix(`/app`)") - app.Container.Docker.Bridged(). - Expose(80). - Container("traefik/whoami") - - // Deploy the test application. - deployApplication(c, client, app) - - // Query application via Traefik. - err = try.GetRequest("http://127.0.0.1:8000/app", 30*time.Second, try.StatusCodeIs(http.StatusOK)) - c.Assert(err, checker.IsNil) -} diff --git a/integration/proxy_protocol_test.go b/integration/proxy_protocol_test.go index 7ed8300af7dd3aef4692d55e9db1437d3cea2fa7..40640bae7e29c99e694d378781b5d8aece6f9cd2 100644 --- a/integration/proxy_protocol_test.go +++ b/integration/proxy_protocol_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/ratelimit_test.go b/integration/ratelimit_test.go index 5d45e8086c275a11d06fc2c464e36ac4c0598431..5edbf64b8fa6e79c03604b1955907a426aa5e448 100644 --- a/integration/ratelimit_test.go +++ b/integration/ratelimit_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/redis_test.go b/integration/redis_test.go index d696ad6704a0fb0c0e9888433143a8385d28ad8d..a5f45bff79a7d48970a8c896e7ad14af189d07a9 100644 --- a/integration/redis_test.go +++ b/integration/redis_test.go @@ -15,8 +15,8 @@ import ( "github.com/kvtools/valkeyrie" "github.com/kvtools/valkeyrie/store" "github.com/pmezard/go-difflib/difflib" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/api" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/api" checker "github.com/vdemeester/shakers" ) diff --git a/integration/resources/compose/marathon.yml b/integration/resources/compose/marathon.yml deleted file mode 100644 index 5a2be1e6771759bbac7f925606ae166c4d018cf9..0000000000000000000000000000000000000000 --- a/integration/resources/compose/marathon.yml +++ /dev/null @@ -1,60 +0,0 @@ -version: "3.8" -services: - zookeeper: - image: zookeeper:3.4.10 - - mesos-master: - image: mesosphere/mesos-master:1.0.1-2.0.93.ubuntu1404 - # Uncomment published ports for interactive debugging. - # ports: - # - "5050:5050" - environment: - MESOS_HOSTNAME: mesos-master - MESOS_CLUSTER: local - MESOS_REGISTRY: in_memory - MESOS_LOG_DIR: /var/log - MESOS_WORK_DIR: /var/lib/mesos - MESOS_ZK: zk://zookeeper:2181/mesos - - mesos-slave: - image: docker:dind - privileged: true - # Uncomment published ports for interactive debugging. - # ports: - # - "5051:5051" - # docker version in mesosphere/mesos-slave-dind:0.3.0_mesos-1.0.1_docker-1.10.3_ubuntu-14.04.5 is too old and can't - # pull images on new kernels. - command: - - "/bin/sh" - - "-c" - - "(/usr/local/bin/dockerd-entrypoint.sh &); sleep 10; set -x; \ - docker -H unix:///var/run/docker.sock run -d --net=host --privileged \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /cgroup:/cgroup -v /sys:/sys \ - -v /usr/local/bin/docker:/usr/local/bin/docker \ - -e MESOS_HOSTNAME=$$(hostname -i) \ - -e MESOS_CONTAINERIZERS=docker,mesos \ - -e MESOS_ISOLATOR=cgroups/cpu,cgroups/mem \ - -e MESOS_LOG_DIR=/var/log \ - -e MESOS_MASTER=zk://zookeeper:2181/mesos \ - -e MESOS_PORT=5051 \ - -e MESOS_WORK_DIR=/var/lib/mesos \ - -e MESOS_EXECUTOR_REGISTRATION_TIMEOUT=5mins \ - -e MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD=90secs \ - -e MESOS_DOCKER_STOP_TIMEOUT=60secs \ - -e MESOS_RESOURCES='cpus:2;mem:2048;disk:20480;ports(*):[12000-12999]' \ - mesosphere/mesos-slave:1.0.3; sleep 600" - - marathon: - image: mesosphere/marathon:v1.3.12 - # Uncomment published ports for interactive debugging. - # ports: - # - "8080:8080" - environment: - MARATHON_ZK: zk://zookeeper:2181/marathon - MARATHON_MASTER: zk://zookeeper:2181/mesos - -networks: - default: - name: traefik-test-network - external: true diff --git a/integration/resources/compose/marathon15.yml b/integration/resources/compose/marathon15.yml deleted file mode 100644 index 6a5774fc76d26af0cc6fcb077295bcabbae1ac5f..0000000000000000000000000000000000000000 --- a/integration/resources/compose/marathon15.yml +++ /dev/null @@ -1,59 +0,0 @@ -version: "3.8" -services: - zookeeper: - image: zookeeper:3.4.10 - - mesos-master: - image: mesosphere/mesos-master:1.4.1 - # Uncomment published ports for interactive debugging. - # ports: - # - "5050:5050" - environment: - MESOS_HOSTNAME: mesos-master - MESOS_CLUSTER: local - MESOS_REGISTRY: in_memory - MESOS_LOG_DIR: /var/log - MESOS_WORK_DIR: /var/lib/mesos - MESOS_ZK: zk://zookeeper:2181/mesos - - mesos-slave: - image: docker:dind - privileged: true - # Uncomment published ports for interactive debugging. - # ports: - # - "5051:5051" - command: - - "/bin/sh" - - "-c" - - "(/usr/local/bin/dockerd-entrypoint.sh &); sleep 10; set -x; \ - docker -H unix:///var/run/docker.sock run -d --net=host --privileged \ - -v /var/run/docker.sock:/var/run/docker.sock \ - -v /cgroup:/cgroup -v /sys:/sys \ - -v /usr/local/bin/docker:/usr/local/bin/docker \ - -e MESOS_HOSTNAME=$$(hostname -i) \ - -e MESOS_CONTAINERIZERS=docker,mesos \ - -e MESOS_ISOLATOR=cgroups/cpu,cgroups/mem \ - -e MESOS_LOG_DIR=/var/log \ - -e MESOS_MASTER=zk://zookeeper:2181/mesos \ - -e MESOS_PORT=5051 \ - -e MESOS_WORK_DIR=/var/lib/mesos \ - -e MESOS_EXECUTOR_REGISTRATION_TIMEOUT=5mins \ - -e MESOS_EXECUTOR_SHUTDOWN_GRACE_PERIOD=90secs \ - -e MESOS_DOCKER_STOP_TIMEOUT=60secs \ - -e MESOS_RESOURCES='cpus:2;mem:2048;disk:20480;ports(*):[12000-12999]' \ - -e MESOS_SYSTEMD_ENABLE_SUPPORT=false \ - mesosphere/mesos-slave:1.4.1; sleep 600" - - marathon: - image: mesosphere/marathon:v1.5.9 - # Uncomment published ports for interactive debugging. - # ports: - # - "8080:8080" - environment: - MARATHON_ZK: zk://zookeeper:2181/marathon - MARATHON_MASTER: zk://zookeeper:2181/mesos - -networks: - default: - name: traefik-test-network - external: true diff --git a/integration/rest_test.go b/integration/rest_test.go index d72f1631458ffdcb0487deeb288947e30b9a9af3..1178fbb943be69d2fadc0830f54d20361b55972f 100644 --- a/integration/rest_test.go +++ b/integration/rest_test.go @@ -10,8 +10,8 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/config/dynamic" checker "github.com/vdemeester/shakers" ) diff --git a/integration/retry_test.go b/integration/retry_test.go index 6a146e5ce45b36cf9d3b0b4f3b0b6ad782f9e5b8..29fc0e7d0af6487c3e0c8d4caea3f5afc507b2dd 100644 --- a/integration/retry_test.go +++ b/integration/retry_test.go @@ -7,7 +7,7 @@ import ( "github.com/go-check/check" "github.com/gorilla/websocket" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/simple_test.go b/integration/simple_test.go index 41751d6a6fba100fd2cac32c1b18584a182cd08f..367c9aa17ba2830edd607b167617787a8b76dd93 100644 --- a/integration/simple_test.go +++ b/integration/simple_test.go @@ -18,8 +18,8 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/config/dynamic" checker "github.com/vdemeester/shakers" ) diff --git a/integration/tcp_test.go b/integration/tcp_test.go index b7a8b84c980b489e9a4ade3ab70a944cec3990db..43a7158d034f87b73df5c789645173face77efbb 100644 --- a/integration/tcp_test.go +++ b/integration/tcp_test.go @@ -13,7 +13,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/testdata/rawdata-crd-label-selector.json b/integration/testdata/rawdata-crd-label-selector.json index 63ace05eb37f0875333463c8e4bc82889e2a90fc..b5c9f1669a8713149f0fdc3f296b7bbc1b4b8f9d 100644 --- a/integration/testdata/rawdata-crd-label-selector.json +++ b/integration/testdata/rawdata-crd-label-selector.json @@ -6,6 +6,7 @@ ], "service": "api@internal", "rule": "PathPrefix(`/api`)", + "priority": 18, "status": "enabled", "using": [ "web" @@ -44,7 +45,7 @@ "url": "http://10.42.0.3:80" }, { - "url": "http://10.42.0.4:80" + "url": "http://10.42.0.6:80" } ], "passHostHeader": true, @@ -58,7 +59,7 @@ ], "serverStatus": { "http://10.42.0.3:80": "UP", - "http://10.42.0.4:80": "UP" + "http://10.42.0.6:80": "UP" } }, "noop@internal": { diff --git a/integration/testdata/rawdata-crd.json b/integration/testdata/rawdata-crd.json index a49ebddb22dc570e43514eaf1e8814d13bf63a41..81f397196943c4a3319e6225fa075990e42545f9 100644 --- a/integration/testdata/rawdata-crd.json +++ b/integration/testdata/rawdata-crd.json @@ -6,6 +6,7 @@ ], "service": "api@internal", "rule": "PathPrefix(`/api`)", + "priority": 18, "status": "enabled", "using": [ "web" @@ -35,6 +36,7 @@ ], "service": "default-test2-route-23c7f4c450289ee29016", "rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/tobestripped`)", + "priority": 46, "status": "enabled", "using": [ "web" @@ -46,6 +48,7 @@ ], "service": "default-wrr1", "rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/wrr1`)", + "priority": 38, "status": "enabled", "using": [ "web" @@ -57,6 +60,7 @@ ], "service": "default-testst-route-60ad45fcb5fc1f5f3629", "rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/serverstransport`)", + "priority": 50, "status": "enabled", "using": [ "web" @@ -68,6 +72,7 @@ ], "service": "other-ns-wrr3", "rule": "Host(`foo.com`) \u0026\u0026 PathPrefix(`/c`)", + "priority": 35, "error": [ "the service \"other-ns-wrr3@kubernetescrd\" does not exist" ], @@ -131,7 +136,7 @@ "loadBalancer": { "servers": [ { - "url": "http://10.42.0.6:80" + "url": "http://10.42.0.3:80" }, { "url": "http://10.42.0.7:80" @@ -147,7 +152,7 @@ "default-test-route-6b204d94623b3df4370c@kubernetescrd" ], "serverStatus": { - "http://10.42.0.6:80": "UP", + "http://10.42.0.3:80": "UP", "http://10.42.0.7:80": "UP" } }, @@ -155,7 +160,7 @@ "loadBalancer": { "servers": [ { - "url": "http://10.42.0.6:80" + "url": "http://10.42.0.3:80" }, { "url": "http://10.42.0.7:80" @@ -171,7 +176,7 @@ "default-test2-route-23c7f4c450289ee29016@kubernetescrd" ], "serverStatus": { - "http://10.42.0.6:80": "UP", + "http://10.42.0.3:80": "UP", "http://10.42.0.7:80": "UP" } }, @@ -179,7 +184,7 @@ "loadBalancer": { "servers": [ { - "url": "http://10.42.0.6:80" + "url": "http://10.42.0.3:80" }, { "url": "http://10.42.0.7:80" @@ -196,7 +201,7 @@ "default-testst-route-60ad45fcb5fc1f5f3629@kubernetescrd" ], "serverStatus": { - "http://10.42.0.6:80": "UP", + "http://10.42.0.3:80": "UP", "http://10.42.0.7:80": "UP" } }, @@ -204,7 +209,7 @@ "loadBalancer": { "servers": [ { - "url": "http://10.42.0.6:80" + "url": "http://10.42.0.3:80" }, { "url": "http://10.42.0.7:80" @@ -217,7 +222,7 @@ }, "status": "enabled", "serverStatus": { - "http://10.42.0.6:80": "UP", + "http://10.42.0.3:80": "UP", "http://10.42.0.7:80": "UP" } }, @@ -261,6 +266,7 @@ ], "service": "default-test3.route-673acf455cb2dab0b43a", "rule": "HostSNI(`*`)", + "priority": -1, "tls": { "passthrough": false, "options": "default-mytlsoption" @@ -274,7 +280,6 @@ "tcpServices": { "default-test3.route-673acf455cb2dab0b43a-externalname-svc-9090@kubernetescrd": { "loadBalancer": { - "terminationDelay": 100, "servers": [ { "address": "domain.com:9090" @@ -285,13 +290,12 @@ }, "default-test3.route-673acf455cb2dab0b43a-whoamitcp-8080@kubernetescrd": { "loadBalancer": { - "terminationDelay": 100, "servers": [ { - "address": "10.42.0.10:8080" + "address": "10.42.0.2:8080" }, { - "address": "10.42.0.8:8080" + "address": "10.42.0.4:8080" } ] }, @@ -343,10 +347,10 @@ "loadBalancer": { "servers": [ { - "address": "10.42.0.4:8090" + "address": "10.42.0.5:8090" }, { - "address": "10.42.0.9:8090" + "address": "10.42.0.6:8090" } ] }, diff --git a/integration/testdata/rawdata-gateway.json b/integration/testdata/rawdata-gateway.json index 46c50efd696dde66fc958a1bf697724cb774e714..d629cfc41b12108c9826d1f9dbe34fb8c3c33f72 100644 --- a/integration/testdata/rawdata-gateway.json +++ b/integration/testdata/rawdata-gateway.json @@ -34,6 +34,7 @@ ], "service": "default-http-app-1-my-gateway-web-1c0cf64bde37d9d0df06-wrr", "rule": "Host(`foo.com`) \u0026\u0026 Path(`/bar`)", + "priority": 31, "status": "enabled", "using": [ "web" @@ -45,6 +46,7 @@ ], "service": "default-http-app-1-my-https-gateway-websecure-1c0cf64bde37d9d0df06-wrr", "rule": "Host(`foo.com`) \u0026\u0026 Path(`/bar`)", + "priority": 31, "tls": {}, "status": "enabled", "using": [ @@ -122,10 +124,10 @@ "loadBalancer": { "servers": [ { - "url": "http://10.42.0.6:80" + "url": "http://10.42.0.3:80" }, { - "url": "http://10.42.0.7:80" + "url": "http://10.42.0.4:80" } ], "passHostHeader": true, @@ -135,8 +137,8 @@ }, "status": "enabled", "serverStatus": { - "http://10.42.0.6:80": "UP", - "http://10.42.0.7:80": "UP" + "http://10.42.0.3:80": "UP", + "http://10.42.0.4:80": "UP" } }, "noop@internal": { @@ -150,6 +152,7 @@ ], "service": "default-tcp-app-1-my-tcp-gateway-footcp-e3b0c44298fc1c149afb-wrr-0", "rule": "HostSNI(`*`)", + "priority": -1, "status": "enabled", "using": [ "footcp" @@ -161,6 +164,7 @@ ], "service": "default-tcp-app-1-my-tls-gateway-footlsterminate-e3b0c44298fc1c149afb-wrr-0", "rule": "HostSNI(`*`)", + "priority": -1, "tls": { "passthrough": false }, @@ -175,6 +179,7 @@ ], "service": "default-tls-app-1-my-tls-gateway-footlspassthrough-2279fe75c5156dc5eb26-wrr-0", "rule": "HostSNI(`foo.bar`)", + "priority": 18, "tls": { "passthrough": true }, @@ -229,13 +234,12 @@ }, "default-whoamitcp-8080@kubernetesgateway": { "loadBalancer": { - "terminationDelay": 100, "servers": [ { "address": "10.42.0.2:8080" }, { - "address": "10.42.0.4:8080" + "address": "10.42.0.6:8080" } ] }, diff --git a/integration/testdata/rawdata-ingress-label-selector.json b/integration/testdata/rawdata-ingress-label-selector.json index 54fbae930579cb8a54d6fd0c931f126d5c672f5b..d72826ae7b2f33577b0b71a85001f7196d8bcc69 100644 --- a/integration/testdata/rawdata-ingress-label-selector.json +++ b/integration/testdata/rawdata-ingress-label-selector.json @@ -34,6 +34,7 @@ ], "service": "default-whoami-http", "rule": "Host(`whoami.test`) \u0026\u0026 PathPrefix(`/whoami`)", + "priority": 44, "status": "enabled", "using": [ "web" diff --git a/integration/testdata/rawdata-ingress.json b/integration/testdata/rawdata-ingress.json index a912d1ea029d3a17515fe24d3bd3c86d8e9c1de7..ecfa38ee6abd9c752a03b4d14a3e604f141b9b7c 100644 --- a/integration/testdata/rawdata-ingress.json +++ b/integration/testdata/rawdata-ingress.json @@ -34,6 +34,7 @@ ], "service": "default-whoami-http", "rule": "Host(`whoami.test.https`) \u0026\u0026 PathPrefix(`/whoami`)", + "priority": 50, "status": "enabled", "using": [ "web" @@ -45,6 +46,7 @@ ], "service": "default-whoami-http", "rule": "Host(`whoami.test`) \u0026\u0026 PathPrefix(`/whoami`)", + "priority": 44, "status": "enabled", "using": [ "web" @@ -56,6 +58,7 @@ ], "service": "default-whoami-80", "rule": "Host(`whoami.test.drop`) \u0026\u0026 PathPrefix(`/drop`)", + "priority": 47, "status": "enabled", "using": [ "web" @@ -67,6 +70,7 @@ ], "service": "default-whoami-80", "rule": "Host(`whoami.test.keep`) \u0026\u0026 PathPrefix(`/keep`)", + "priority": 47, "status": "enabled", "using": [ "web" diff --git a/integration/testdata/rawdata-ingressclass-disabled.json b/integration/testdata/rawdata-ingressclass-disabled.json new file mode 100644 index 0000000000000000000000000000000000000000..14649419c60863fb0d4e065773193d805c0db36e --- /dev/null +++ b/integration/testdata/rawdata-ingressclass-disabled.json @@ -0,0 +1,74 @@ +{ + "routers": { + "api@internal": { + "entryPoints": [ + "traefik" + ], + "service": "api@internal", + "rule": "PathPrefix(`/api`)", + "priority": 2147483646, + "status": "enabled", + "using": [ + "traefik" + ] + }, + "dashboard@internal": { + "entryPoints": [ + "traefik" + ], + "middlewares": [ + "dashboard_redirect@internal", + "dashboard_stripprefix@internal" + ], + "service": "dashboard@internal", + "rule": "PathPrefix(`/`)", + "priority": 2147483645, + "status": "enabled", + "using": [ + "traefik" + ] + } + }, + "middlewares": { + "dashboard_redirect@internal": { + "redirectRegex": { + "regex": "^(http:\\/\\/(\\[[\\w:.]+\\]|[\\w\\._-]+)(:\\d+)?)\\/$", + "replacement": "${1}/dashboard/", + "permanent": true + }, + "status": "enabled", + "usedBy": [ + "dashboard@internal" + ] + }, + "dashboard_stripprefix@internal": { + "stripPrefix": { + "prefixes": [ + "/dashboard/", + "/dashboard" + ] + }, + "status": "enabled", + "usedBy": [ + "dashboard@internal" + ] + } + }, + "services": { + "api@internal": { + "status": "enabled", + "usedBy": [ + "api@internal" + ] + }, + "dashboard@internal": { + "status": "enabled", + "usedBy": [ + "dashboard@internal" + ] + }, + "noop@internal": { + "status": "enabled" + } + } +} \ No newline at end of file diff --git a/integration/testdata/rawdata-ingressclass.json b/integration/testdata/rawdata-ingressclass.json index e592135bcddb43a4e17af9b533ab568b22a40684..4215504c058d7e80fe41478c2c81dff1ff4aa15a 100644 --- a/integration/testdata/rawdata-ingressclass.json +++ b/integration/testdata/rawdata-ingressclass.json @@ -34,6 +34,7 @@ ], "service": "default-whoami-80", "rule": "Host(`whoami.test.keep`) \u0026\u0026 PathPrefix(`/keep`)", + "priority": 47, "status": "enabled", "using": [ "web" diff --git a/integration/timeout_test.go b/integration/timeout_test.go index 68c5886ca547b5320b618d5ddb9e0f0e539a3ea7..457e2bcfb8e128fbe4fe9cca609819d5596d5c0a 100644 --- a/integration/timeout_test.go +++ b/integration/timeout_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/tls_client_headers_test.go b/integration/tls_client_headers_test.go index 3bc587acd0f006fb99080a1676fda0dab5cb5596..08f0c7ea522747d63199ab2ca55208f54d032923 100644 --- a/integration/tls_client_headers_test.go +++ b/integration/tls_client_headers_test.go @@ -7,7 +7,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/tracing_test.go b/integration/tracing_test.go index 2c9582b7ba3769c0cd68af2d9b722c2348d7347a..f2a1f29ad3c079399994a4962d4f16ef23edcea6 100644 --- a/integration/tracing_test.go +++ b/integration/tracing_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/udp_test.go b/integration/udp_test.go index c5ee868a1fc9531ef7e2c77adf5abb5c3654caeb..3493af17ea25d5e4dc87d0e9fef9fcf9646cc5f1 100644 --- a/integration/udp_test.go +++ b/integration/udp_test.go @@ -8,7 +8,7 @@ import ( "time" "github.com/go-check/check" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" ) diff --git a/integration/websocket_test.go b/integration/websocket_test.go index 33425624fcc0a030c2e0950453613ae662220b01..c343c1b7869297f41a3cf906f3264f7928d122ea 100644 --- a/integration/websocket_test.go +++ b/integration/websocket_test.go @@ -12,7 +12,7 @@ import ( "github.com/go-check/check" gorillawebsocket "github.com/gorilla/websocket" - "github.com/traefik/traefik/v2/integration/try" + "github.com/traefik/traefik/v3/integration/try" checker "github.com/vdemeester/shakers" "golang.org/x/net/websocket" ) diff --git a/integration/zk_test.go b/integration/zk_test.go index 21f536cb6294d4479e19b11f9fe61103aea41933..1e5820cc5489951d995a89d3cf73d1e9734372ac 100644 --- a/integration/zk_test.go +++ b/integration/zk_test.go @@ -15,8 +15,8 @@ import ( "github.com/kvtools/valkeyrie/store" "github.com/kvtools/zookeeper" "github.com/pmezard/go-difflib/difflib" - "github.com/traefik/traefik/v2/integration/try" - "github.com/traefik/traefik/v2/pkg/api" + "github.com/traefik/traefik/v3/integration/try" + "github.com/traefik/traefik/v3/pkg/api" checker "github.com/vdemeester/shakers" ) diff --git a/internal/gendoc.go b/internal/gendoc.go index 397f700eee352fdb2480af1c9cdfdb34b3b30a8e..d4fad3247b3fb1703a93165d9b3b2205fde206b3 100644 --- a/internal/gendoc.go +++ b/internal/gendoc.go @@ -15,7 +15,7 @@ import ( "github.com/traefik/paerser/flag" "github.com/traefik/paerser/generator" "github.com/traefik/paerser/parser" - "github.com/traefik/traefik/v2/cmd" + "github.com/traefik/traefik/v3/cmd" ) func main() { diff --git a/pkg/api/criterion.go b/pkg/api/criterion.go index d81a9f717844f7fd68ac9d5a76e5cae47c29501b..2e3d2f7e678e08c9a2775fb9787a9f8c7fb3df46 100644 --- a/pkg/api/criterion.go +++ b/pkg/api/criterion.go @@ -22,8 +22,10 @@ type pageInfo struct { } type searchCriterion struct { - Search string `url:"search"` - Status string `url:"status"` + Search string `url:"search"` + Status string `url:"status"` + ServiceName string `url:"serviceName"` + MiddlewareName string `url:"middlewareName"` } func newSearchCriterion(query url.Values) *searchCriterion { @@ -33,12 +35,19 @@ func newSearchCriterion(query url.Values) *searchCriterion { search := query.Get("search") status := query.Get("status") + serviceName := query.Get("serviceName") + middlewareName := query.Get("middlewareName") - if status == "" && search == "" { + if status == "" && search == "" && serviceName == "" && middlewareName == "" { return nil } - return &searchCriterion{Search: search, Status: status} + return &searchCriterion{ + Search: search, + Status: status, + ServiceName: serviceName, + MiddlewareName: middlewareName, + } } func (c *searchCriterion) withStatus(name string) bool { @@ -59,6 +68,34 @@ func (c *searchCriterion) searchIn(values ...string) bool { return false } +func (c *searchCriterion) filterService(name string) bool { + if c.ServiceName == "" { + return true + } + + if strings.Contains(name, "@") { + return c.ServiceName == name + } + + before, _, _ := strings.Cut(c.ServiceName, "@") + + return before == name +} + +func (c *searchCriterion) filterMiddleware(mns []string) bool { + if c.MiddlewareName == "" { + return true + } + + for _, mn := range mns { + if c.MiddlewareName == mn { + return true + } + } + + return false +} + func pagination(request *http.Request, max int) (pageInfo, error) { perPage, err := getIntParam(request, "per_page", defaultPerPage) if err != nil { diff --git a/pkg/api/dashboard/dashboard.go b/pkg/api/dashboard/dashboard.go index ebcaf315e2ae30e668e5180c5ab15e25a78b3644..b42d04247adb5c503f31453c7633c33c53b71763 100644 --- a/pkg/api/dashboard/dashboard.go +++ b/pkg/api/dashboard/dashboard.go @@ -6,7 +6,7 @@ import ( "net/url" "github.com/gorilla/mux" - "github.com/traefik/traefik/v2/webui" + "github.com/traefik/traefik/v3/webui" ) // Handler expose dashboard routes. @@ -34,6 +34,11 @@ func Append(router *mux.Router, customAssets fs.FS) { // allow iframes from our domains only // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src w.Header().Set("Content-Security-Policy", "frame-src 'self' https://traefik.io https://*.traefik.io;") + + // The content type must be guessed by the file server. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + w.Header().Del("Content-Type") + http.StripPrefix("/dashboard/", http.FileServer(http.FS(assets))).ServeHTTP(w, r) }) } @@ -46,6 +51,11 @@ func (g Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // allow iframes from our domains only // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/frame-src w.Header().Set("Content-Security-Policy", "frame-src 'self' https://traefik.io https://*.traefik.io;") + + // The content type must be guessed by the file server. + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + w.Header().Del("Content-Type") + http.FileServer(http.FS(assets)).ServeHTTP(w, r) } diff --git a/pkg/api/handler.go b/pkg/api/handler.go index 01ec203610bc36991289c962f1c3710a54c24c79..9c135546aef039239800f73bc8574e36601e91fa 100644 --- a/pkg/api/handler.go +++ b/pkg/api/handler.go @@ -8,10 +8,10 @@ import ( "github.com/gorilla/mux" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/version" ) type apiError struct { diff --git a/pkg/api/handler_entrypoint.go b/pkg/api/handler_entrypoint.go index 104ab385359c372a7f8e43773590dc82608d53cf..d21e83d0d9c27837cb8373705c412bdde80a5342 100644 --- a/pkg/api/handler_entrypoint.go +++ b/pkg/api/handler_entrypoint.go @@ -9,7 +9,7 @@ import ( "github.com/gorilla/mux" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/static" ) type entryPointRepresentation struct { diff --git a/pkg/api/handler_entrypoint_test.go b/pkg/api/handler_entrypoint_test.go index a3c31e583347eae612ec3cf3838e933981b1b846..f02821607bbd0ff60ed74755b18e4721d81d424d 100644 --- a/pkg/api/handler_entrypoint_test.go +++ b/pkg/api/handler_entrypoint_test.go @@ -12,8 +12,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" ) func TestHandler_EntryPoints(t *testing.T) { diff --git a/pkg/api/handler_http.go b/pkg/api/handler_http.go index ebf35d2062e7f722ce9530db64f9cd7f94e8fc2a..a0f25d4a60714f52b1bbd969ad039f38f756085e 100644 --- a/pkg/api/handler_http.go +++ b/pkg/api/handler_http.go @@ -4,14 +4,13 @@ import ( "encoding/json" "fmt" "net/http" - "sort" "strconv" "strings" "github.com/gorilla/mux" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/tls" ) type routerRepresentation struct { @@ -69,7 +68,8 @@ func newMiddlewareRepresentation(name string, mi *runtime.MiddlewareInfo) middle func (h Handler) getRouters(rw http.ResponseWriter, request *http.Request) { results := make([]routerRepresentation, 0, len(h.runtimeConfiguration.Routers)) - criterion := newSearchCriterion(request.URL.Query()) + query := request.URL.Query() + criterion := newSearchCriterion(query) for name, rt := range h.runtimeConfiguration.Routers { if keepRouter(name, rt, criterion) { @@ -77,9 +77,7 @@ func (h Handler) getRouters(rw http.ResponseWriter, request *http.Request) { } } - sort.Slice(results, func(i, j int) bool { - return results[i].Name < results[j].Name - }) + sortRouters(query, results) rw.Header().Set("Content-Type", "application/json") @@ -121,7 +119,8 @@ func (h Handler) getRouter(rw http.ResponseWriter, request *http.Request) { func (h Handler) getServices(rw http.ResponseWriter, request *http.Request) { results := make([]serviceRepresentation, 0, len(h.runtimeConfiguration.Services)) - criterion := newSearchCriterion(request.URL.Query()) + query := request.URL.Query() + criterion := newSearchCriterion(query) for name, si := range h.runtimeConfiguration.Services { if keepService(name, si, criterion) { @@ -129,9 +128,7 @@ func (h Handler) getServices(rw http.ResponseWriter, request *http.Request) { } } - sort.Slice(results, func(i, j int) bool { - return results[i].Name < results[j].Name - }) + sortServices(query, results) rw.Header().Set("Content-Type", "application/json") @@ -173,7 +170,8 @@ func (h Handler) getService(rw http.ResponseWriter, request *http.Request) { func (h Handler) getMiddlewares(rw http.ResponseWriter, request *http.Request) { results := make([]middlewareRepresentation, 0, len(h.runtimeConfiguration.Middlewares)) - criterion := newSearchCriterion(request.URL.Query()) + query := request.URL.Query() + criterion := newSearchCriterion(query) for name, mi := range h.runtimeConfiguration.Middlewares { if keepMiddleware(name, mi, criterion) { @@ -181,9 +179,7 @@ func (h Handler) getMiddlewares(rw http.ResponseWriter, request *http.Request) { } } - sort.Slice(results, func(i, j int) bool { - return results[i].Name < results[j].Name - }) + sortMiddlewares(query, results) rw.Header().Set("Content-Type", "application/json") @@ -227,7 +223,10 @@ func keepRouter(name string, item *runtime.RouterInfo, criterion *searchCriterio return true } - return criterion.withStatus(item.Status) && criterion.searchIn(item.Rule, name) + return criterion.withStatus(item.Status) && + criterion.searchIn(item.Rule, name) && + criterion.filterService(item.Service) && + criterion.filterMiddleware(item.Middlewares) } func keepService(name string, item *runtime.ServiceInfo, criterion *searchCriterion) bool { diff --git a/pkg/api/handler_http_test.go b/pkg/api/handler_http_test.go index f6137f202420b35fd661bef969f0563dfb2ad8a8..0a9cedc5c7fdb3f74b6b9364a6bb097b286044a2 100644 --- a/pkg/api/handler_http_test.go +++ b/pkg/api/handler_http_test.go @@ -13,9 +13,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" ) func Bool(v bool) *bool { return &v } @@ -202,6 +202,84 @@ func TestHandler_HTTP(t *testing.T) { jsonFile: "testdata/routers-filtered-search.json", }, }, + { + desc: "routers filtered by service", + path: "/api/http/routers?serviceName=fii-service@myprovider", + conf: runtime.Configuration{ + Routers: map[string]*runtime.RouterInfo{ + "test@myprovider": { + Router: &dynamic.Router{ + EntryPoints: []string{"web"}, + Service: "fii-service@myprovider", + Rule: "Host(`fii.bar.other`)", + Middlewares: []string{"addPrefixTest", "auth"}, + }, + Status: runtime.StatusEnabled, + }, + "foo@otherprovider": { + Router: &dynamic.Router{ + EntryPoints: []string{"web"}, + Service: "fii-service", + Rule: "Host(`fii.foo.other`)", + }, + Status: runtime.StatusEnabled, + }, + "bar@myprovider": { + Router: &dynamic.Router{ + EntryPoints: []string{"web"}, + Service: "foo-service@myprovider", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "addPrefixTest@anotherprovider"}, + }, + Status: runtime.StatusDisabled, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/routers-filtered-serviceName.json", + }, + }, + { + desc: "routers filtered by middleware", + path: "/api/http/routers?middlewareName=auth", + conf: runtime.Configuration{ + Routers: map[string]*runtime.RouterInfo{ + "test@myprovider": { + Router: &dynamic.Router{ + EntryPoints: []string{"web"}, + Service: "fii-service@myprovider", + Rule: "Host(`fii.bar.other`)", + Middlewares: []string{"addPrefixTest", "auth"}, + }, + Status: runtime.StatusEnabled, + }, + "foo@otherprovider": { + Router: &dynamic.Router{ + EntryPoints: []string{"web"}, + Service: "fii-service", + Rule: "Host(`fii.foo.other`)", + }, + Status: runtime.StatusEnabled, + }, + "bar@myprovider": { + Router: &dynamic.Router{ + EntryPoints: []string{"web"}, + Service: "foo-service@myprovider", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "addPrefixTest@anotherprovider"}, + }, + Status: runtime.StatusDisabled, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/routers-filtered-middlewareName.json", + }, + }, { desc: "one router by id", path: "/api/http/routers/bar@myprovider", diff --git a/pkg/api/handler_overview.go b/pkg/api/handler_overview.go index 7f423b09fbe1e2c6f835994462be6e2ac594fa94..0856f69fc073ac365753cdb457ad652c3a2e0c80 100644 --- a/pkg/api/handler_overview.go +++ b/pkg/api/handler_overview.go @@ -6,8 +6,8 @@ import ( "reflect" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" ) type schemeOverview struct { diff --git a/pkg/api/handler_overview_test.go b/pkg/api/handler_overview_test.go index b7f96c6b99ed3945025d7ff496017affd9456dc8..d76dd55e570f58cb371179c6ab2a58112dbc17e5 100644 --- a/pkg/api/handler_overview_test.go +++ b/pkg/api/handler_overview_test.go @@ -10,19 +10,17 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/provider/docker" - "github.com/traefik/traefik/v2/pkg/provider/file" - "github.com/traefik/traefik/v2/pkg/provider/hub" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/ingress" - "github.com/traefik/traefik/v2/pkg/provider/marathon" - "github.com/traefik/traefik/v2/pkg/provider/rancher" - "github.com/traefik/traefik/v2/pkg/provider/rest" - "github.com/traefik/traefik/v2/pkg/tracing/jaeger" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/provider/docker" + "github.com/traefik/traefik/v3/pkg/provider/file" + "github.com/traefik/traefik/v3/pkg/provider/hub" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/ingress" + "github.com/traefik/traefik/v3/pkg/provider/rest" + "github.com/traefik/traefik/v3/pkg/tracing/jaeger" + "github.com/traefik/traefik/v3/pkg/types" ) func TestHandler_Overview(t *testing.T) { @@ -238,11 +236,9 @@ func TestHandler_Overview(t *testing.T) { Providers: &static.Providers{ Docker: &docker.Provider{}, File: &file.Provider{}, - Marathon: &marathon.Provider{}, KubernetesIngress: &ingress.Provider{}, KubernetesCRD: &crd.Provider{}, Rest: &rest.Provider{}, - Rancher: &rancher.Provider{}, Plugin: map[string]static.PluginConf{ "test": map[string]interface{}{}, }, diff --git a/pkg/api/handler_tcp.go b/pkg/api/handler_tcp.go index 8efb130687a2384b1fe498ee1698e0eb8d4df7ee..7c6a6fe67f2a0b307f41be182bf05440d4aa6652 100644 --- a/pkg/api/handler_tcp.go +++ b/pkg/api/handler_tcp.go @@ -4,13 +4,12 @@ import ( "encoding/json" "fmt" "net/http" - "sort" "strconv" "strings" "github.com/gorilla/mux" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/runtime" ) type tcpRouterRepresentation struct { @@ -62,7 +61,8 @@ func newTCPMiddlewareRepresentation(name string, mi *runtime.TCPMiddlewareInfo) func (h Handler) getTCPRouters(rw http.ResponseWriter, request *http.Request) { results := make([]tcpRouterRepresentation, 0, len(h.runtimeConfiguration.TCPRouters)) - criterion := newSearchCriterion(request.URL.Query()) + query := request.URL.Query() + criterion := newSearchCriterion(query) for name, rt := range h.runtimeConfiguration.TCPRouters { if keepTCPRouter(name, rt, criterion) { @@ -70,9 +70,7 @@ func (h Handler) getTCPRouters(rw http.ResponseWriter, request *http.Request) { } } - sort.Slice(results, func(i, j int) bool { - return results[i].Name < results[j].Name - }) + sortRouters(query, results) rw.Header().Set("Content-Type", "application/json") @@ -114,7 +112,8 @@ func (h Handler) getTCPRouter(rw http.ResponseWriter, request *http.Request) { func (h Handler) getTCPServices(rw http.ResponseWriter, request *http.Request) { results := make([]tcpServiceRepresentation, 0, len(h.runtimeConfiguration.TCPServices)) - criterion := newSearchCriterion(request.URL.Query()) + query := request.URL.Query() + criterion := newSearchCriterion(query) for name, si := range h.runtimeConfiguration.TCPServices { if keepTCPService(name, si, criterion) { @@ -122,9 +121,7 @@ func (h Handler) getTCPServices(rw http.ResponseWriter, request *http.Request) { } } - sort.Slice(results, func(i, j int) bool { - return results[i].Name < results[j].Name - }) + sortServices(query, results) rw.Header().Set("Content-Type", "application/json") @@ -166,7 +163,8 @@ func (h Handler) getTCPService(rw http.ResponseWriter, request *http.Request) { func (h Handler) getTCPMiddlewares(rw http.ResponseWriter, request *http.Request) { results := make([]tcpMiddlewareRepresentation, 0, len(h.runtimeConfiguration.Middlewares)) - criterion := newSearchCriterion(request.URL.Query()) + query := request.URL.Query() + criterion := newSearchCriterion(query) for name, mi := range h.runtimeConfiguration.TCPMiddlewares { if keepTCPMiddleware(name, mi, criterion) { @@ -174,9 +172,7 @@ func (h Handler) getTCPMiddlewares(rw http.ResponseWriter, request *http.Request } } - sort.Slice(results, func(i, j int) bool { - return results[i].Name < results[j].Name - }) + sortMiddlewares(query, results) rw.Header().Set("Content-Type", "application/json") @@ -220,7 +216,10 @@ func keepTCPRouter(name string, item *runtime.TCPRouterInfo, criterion *searchCr return true } - return criterion.withStatus(item.Status) && criterion.searchIn(item.Rule, name) + return criterion.withStatus(item.Status) && + criterion.searchIn(item.Rule, name) && + criterion.filterService(item.Service) && + criterion.filterMiddleware(item.Middlewares) } func keepTCPService(name string, item *runtime.TCPServiceInfo, criterion *searchCriterion) bool { diff --git a/pkg/api/handler_tcp_test.go b/pkg/api/handler_tcp_test.go index 18ac7708c57e440806d7a46dfabd0c67763f6a71..f2fd35ad13dc97a3cb82160428e8d7ec5cc38446 100644 --- a/pkg/api/handler_tcp_test.go +++ b/pkg/api/handler_tcp_test.go @@ -11,9 +11,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" ) func TestHandler_TCP(t *testing.T) { @@ -193,6 +193,89 @@ func TestHandler_TCP(t *testing.T) { jsonFile: "testdata/tcprouters-filtered-search.json", }, }, + { + desc: "TCP routers filtered by service", + path: "/api/tcp/routers?serviceName=foo-service@myprovider", + conf: runtime.Configuration{ + TCPRouters: map[string]*runtime.TCPRouterInfo{ + "test@myprovider": { + TCPRouter: &dynamic.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service@myprovider", + Rule: "Host(`foo.bar.other`)", + TLS: &dynamic.RouterTCPTLSConfig{ + Passthrough: false, + }, + }, + Status: runtime.StatusEnabled, + }, + "bar@myprovider": { + TCPRouter: &dynamic.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`foo.bar`)", + }, + Status: runtime.StatusWarning, + }, + "foo@myprovider": { + TCPRouter: &dynamic.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "bar-service@myprovider", + Rule: "Host(`foo.bar`)", + }, + Status: runtime.StatusDisabled, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/tcprouters-filtered-serviceName.json", + }, + }, + { + desc: "TCP routers filtered by middleware", + path: "/api/tcp/routers?middlewareName=auth", + conf: runtime.Configuration{ + TCPRouters: map[string]*runtime.TCPRouterInfo{ + "test@myprovider": { + TCPRouter: &dynamic.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service@myprovider", + Rule: "Host(`foo.bar.other`)", + Middlewares: []string{"inflightconn@myprovider"}, + TLS: &dynamic.RouterTCPTLSConfig{ + Passthrough: false, + }, + }, + Status: runtime.StatusEnabled, + }, + "bar@myprovider": { + TCPRouter: &dynamic.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"auth", "inflightconn@myprovider"}, + }, + Status: runtime.StatusWarning, + }, + "foo@myprovider": { + TCPRouter: &dynamic.TCPRouter{ + EntryPoints: []string{"web"}, + Service: "bar-service@myprovider", + Rule: "Host(`foo.bar`)", + Middlewares: []string{"inflightconn@myprovider", "auth"}, + }, + Status: runtime.StatusDisabled, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/tcprouters-filtered-middlewareName.json", + }, + }, { desc: "one TCP router by id", path: "/api/tcp/routers/bar@myprovider", diff --git a/pkg/api/handler_test.go b/pkg/api/handler_test.go index 1dd55ebdbfa30771cc836b0e82f9f6108cab91ff..02889161bbe2e4cbd103ac829357a68982e6581e 100644 --- a/pkg/api/handler_test.go +++ b/pkg/api/handler_test.go @@ -11,9 +11,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" ) var updateExpected = flag.Bool("update_expected", false, "Update expected files in testdata") diff --git a/pkg/api/handler_udp.go b/pkg/api/handler_udp.go index 13adfafea779deb4c0c6e7de7aacd101abab520f..bf637ee72def50cfbbddb035628485b9d12e32f1 100644 --- a/pkg/api/handler_udp.go +++ b/pkg/api/handler_udp.go @@ -4,13 +4,12 @@ import ( "encoding/json" "fmt" "net/http" - "sort" "strconv" "strings" "github.com/gorilla/mux" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/runtime" ) type udpRouterRepresentation struct { @@ -46,7 +45,8 @@ func newUDPServiceRepresentation(name string, si *runtime.UDPServiceInfo) udpSer func (h Handler) getUDPRouters(rw http.ResponseWriter, request *http.Request) { results := make([]udpRouterRepresentation, 0, len(h.runtimeConfiguration.UDPRouters)) - criterion := newSearchCriterion(request.URL.Query()) + query := request.URL.Query() + criterion := newSearchCriterion(query) for name, rt := range h.runtimeConfiguration.UDPRouters { if keepUDPRouter(name, rt, criterion) { @@ -54,9 +54,7 @@ func (h Handler) getUDPRouters(rw http.ResponseWriter, request *http.Request) { } } - sort.Slice(results, func(i, j int) bool { - return results[i].Name < results[j].Name - }) + sortRouters(query, results) rw.Header().Set("Content-Type", "application/json") @@ -98,7 +96,8 @@ func (h Handler) getUDPRouter(rw http.ResponseWriter, request *http.Request) { func (h Handler) getUDPServices(rw http.ResponseWriter, request *http.Request) { results := make([]udpServiceRepresentation, 0, len(h.runtimeConfiguration.UDPServices)) - criterion := newSearchCriterion(request.URL.Query()) + query := request.URL.Query() + criterion := newSearchCriterion(query) for name, si := range h.runtimeConfiguration.UDPServices { if keepUDPService(name, si, criterion) { @@ -106,9 +105,7 @@ func (h Handler) getUDPServices(rw http.ResponseWriter, request *http.Request) { } } - sort.Slice(results, func(i, j int) bool { - return results[i].Name < results[j].Name - }) + sortServices(query, results) rw.Header().Set("Content-Type", "application/json") @@ -152,7 +149,9 @@ func keepUDPRouter(name string, item *runtime.UDPRouterInfo, criterion *searchCr return true } - return criterion.withStatus(item.Status) && criterion.searchIn(name) + return criterion.withStatus(item.Status) && + criterion.searchIn(name) && + criterion.filterService(item.Service) } func keepUDPService(name string, item *runtime.UDPServiceInfo, criterion *searchCriterion) bool { diff --git a/pkg/api/handler_udp_test.go b/pkg/api/handler_udp_test.go index 4a5c0116f2721ff47f23169c9aef3ca69337de3f..b875b2dc8a6bd0f8d15de05da7d70935e6c65c9b 100644 --- a/pkg/api/handler_udp_test.go +++ b/pkg/api/handler_udp_test.go @@ -11,9 +11,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" ) func TestHandler_UDP(t *testing.T) { @@ -172,6 +172,40 @@ func TestHandler_UDP(t *testing.T) { jsonFile: "testdata/udprouters-filtered-search.json", }, }, + { + desc: "UDP routers filtered by service", + path: "/api/udp/routers?serviceName=foo-service@myprovider", + conf: runtime.Configuration{ + UDPRouters: map[string]*runtime.UDPRouterInfo{ + "test@myprovider": { + UDPRouter: &dynamic.UDPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service@myprovider", + }, + Status: runtime.StatusEnabled, + }, + "bar@myprovider": { + UDPRouter: &dynamic.UDPRouter{ + EntryPoints: []string{"web"}, + Service: "foo-service", + }, + Status: runtime.StatusWarning, + }, + "foo@myprovider": { + UDPRouter: &dynamic.UDPRouter{ + EntryPoints: []string{"web"}, + Service: "bar-service@myprovider", + }, + Status: runtime.StatusDisabled, + }, + }, + }, + expected: expected{ + statusCode: http.StatusOK, + nextPage: "1", + jsonFile: "testdata/udprouters-filtered-serviceName.json", + }, + }, { desc: "one UDP router by id", path: "/api/udp/routers/bar@myprovider", diff --git a/pkg/api/sort.go b/pkg/api/sort.go new file mode 100644 index 0000000000000000000000000000000000000000..58e1cde28118e6c8bf858941660a15c98e0bbb56 --- /dev/null +++ b/pkg/api/sort.go @@ -0,0 +1,386 @@ +package api + +import ( + "net/url" + "sort" + + "golang.org/x/exp/constraints" +) + +const ( + sortByParam = "sortBy" + directionParam = "direction" +) + +const ( + ascendantSorting = "asc" + descendantSorting = "desc" +) + +type orderedWithName interface { + name() string +} + +type orderedRouter interface { + orderedWithName + + provider() string + priority() int + status() string + rule() string + service() string + entryPointsCount() int +} + +func sortRouters[T orderedRouter](values url.Values, routers []T) { + sortBy := values.Get(sortByParam) + + direction := values.Get(directionParam) + if direction == "" { + direction = ascendantSorting + } + + switch sortBy { + case "name": + sortByName(direction, routers) + + case "provider": + sortByFunc(direction, routers, func(i int) string { return routers[i].provider() }) + + case "priority": + sortByFunc(direction, routers, func(i int) int { return routers[i].priority() }) + + case "status": + sortByFunc(direction, routers, func(i int) string { return routers[i].status() }) + + case "rule": + sortByFunc(direction, routers, func(i int) string { return routers[i].rule() }) + + case "service": + sortByFunc(direction, routers, func(i int) string { return routers[i].service() }) + + case "entryPoints": + sortByFunc(direction, routers, func(i int) int { return routers[i].entryPointsCount() }) + + default: + sortByName(direction, routers) + } +} + +func (r routerRepresentation) name() string { + return r.Name +} + +func (r routerRepresentation) provider() string { + return r.Provider +} + +func (r routerRepresentation) priority() int { + return r.Priority +} + +func (r routerRepresentation) status() string { + return r.Status +} + +func (r routerRepresentation) rule() string { + return r.Rule +} + +func (r routerRepresentation) service() string { + return r.Service +} + +func (r routerRepresentation) entryPointsCount() int { + return len(r.EntryPoints) +} + +func (r tcpRouterRepresentation) name() string { + return r.Name +} + +func (r tcpRouterRepresentation) provider() string { + return r.Provider +} + +func (r tcpRouterRepresentation) priority() int { + return r.Priority +} + +func (r tcpRouterRepresentation) status() string { + return r.Status +} + +func (r tcpRouterRepresentation) rule() string { + return r.Rule +} + +func (r tcpRouterRepresentation) service() string { + return r.Service +} + +func (r tcpRouterRepresentation) entryPointsCount() int { + return len(r.EntryPoints) +} + +func (r udpRouterRepresentation) name() string { + return r.Name +} + +func (r udpRouterRepresentation) provider() string { + return r.Provider +} + +func (r udpRouterRepresentation) priority() int { + // noop + return 0 +} + +func (r udpRouterRepresentation) status() string { + return r.Status +} + +func (r udpRouterRepresentation) rule() string { + // noop + return "" +} + +func (r udpRouterRepresentation) service() string { + return r.Service +} + +func (r udpRouterRepresentation) entryPointsCount() int { + return len(r.EntryPoints) +} + +type orderedService interface { + orderedWithName + + resourceType() string + serversCount() int + provider() string + status() string +} + +func sortServices[T orderedService](values url.Values, services []T) { + sortBy := values.Get(sortByParam) + + direction := values.Get(directionParam) + if direction == "" { + direction = ascendantSorting + } + + switch sortBy { + case "name": + sortByName(direction, services) + + case "type": + sortByFunc(direction, services, func(i int) string { return services[i].resourceType() }) + + case "servers": + sortByFunc(direction, services, func(i int) int { return services[i].serversCount() }) + + case "provider": + sortByFunc(direction, services, func(i int) string { return services[i].provider() }) + + case "status": + sortByFunc(direction, services, func(i int) string { return services[i].status() }) + + default: + sortByName(direction, services) + } +} + +func (s serviceRepresentation) name() string { + return s.Name +} + +func (s serviceRepresentation) resourceType() string { + return s.Type +} + +func (s serviceRepresentation) serversCount() int { + // TODO: maybe disable that data point altogether, + // if we can't/won't compute a fully correct (recursive) result. + // Or "redefine" it as only the top-level count? + // Note: The current algo is equivalent to the webui one. + if s.LoadBalancer == nil { + return 0 + } + + return len(s.LoadBalancer.Servers) +} + +func (s serviceRepresentation) provider() string { + return s.Provider +} + +func (s serviceRepresentation) status() string { + return s.Status +} + +func (s tcpServiceRepresentation) name() string { + return s.Name +} + +func (s tcpServiceRepresentation) resourceType() string { + return s.Type +} + +func (s tcpServiceRepresentation) serversCount() int { + // TODO: maybe disable that data point altogether, + // if we can't/won't compute a fully correct (recursive) result. + // Or "redefine" it as only the top-level count? + // Note: The current algo is equivalent to the webui one. + if s.LoadBalancer == nil { + return 0 + } + + return len(s.LoadBalancer.Servers) +} + +func (s tcpServiceRepresentation) provider() string { + return s.Provider +} + +func (s tcpServiceRepresentation) status() string { + return s.Status +} + +func (s udpServiceRepresentation) name() string { + return s.Name +} + +func (s udpServiceRepresentation) resourceType() string { + return s.Type +} + +func (s udpServiceRepresentation) serversCount() int { + // TODO: maybe disable that data point altogether, + // if we can't/won't compute a fully correct (recursive) result. + // Or "redefine" it as only the top-level count? + // Note: The current algo is equivalent to the webui one. + if s.LoadBalancer == nil { + return 0 + } + + return len(s.LoadBalancer.Servers) +} + +func (s udpServiceRepresentation) provider() string { + return s.Provider +} + +func (s udpServiceRepresentation) status() string { + return s.Status +} + +type orderedMiddleware interface { + orderedWithName + + resourceType() string + provider() string + status() string +} + +func sortMiddlewares[T orderedMiddleware](values url.Values, middlewares []T) { + sortBy := values.Get(sortByParam) + + direction := values.Get(directionParam) + if direction == "" { + direction = ascendantSorting + } + + switch sortBy { + case "name": + sortByName(direction, middlewares) + + case "type": + sortByFunc(direction, middlewares, func(i int) string { return middlewares[i].resourceType() }) + + case "provider": + sortByFunc(direction, middlewares, func(i int) string { return middlewares[i].provider() }) + + case "status": + sortByFunc(direction, middlewares, func(i int) string { return middlewares[i].status() }) + + default: + sortByName(direction, middlewares) + } +} + +func (m middlewareRepresentation) name() string { + return m.Name +} + +func (m middlewareRepresentation) resourceType() string { + return m.Type +} + +func (m middlewareRepresentation) provider() string { + return m.Provider +} + +func (m middlewareRepresentation) status() string { + return m.Status +} + +func (m tcpMiddlewareRepresentation) name() string { + return m.Name +} + +func (m tcpMiddlewareRepresentation) resourceType() string { + return m.Type +} + +func (m tcpMiddlewareRepresentation) provider() string { + return m.Provider +} + +func (m tcpMiddlewareRepresentation) status() string { + return m.Status +} + +type orderedByName interface { + orderedWithName +} + +func sortByName[T orderedByName](direction string, results []T) { + // Ascending + if direction == ascendantSorting { + sort.Slice(results, func(i, j int) bool { + return results[i].name() < results[j].name() + }) + + return + } + + // Descending + sort.Slice(results, func(i, j int) bool { + return results[i].name() > results[j].name() + }) +} + +func sortByFunc[T orderedWithName, U constraints.Ordered](direction string, results []T, fn func(int) U) { + // Ascending + if direction == ascendantSorting { + sort.Slice(results, func(i, j int) bool { + if fn(i) == fn(j) { + return results[i].name() < results[j].name() + } + + return fn(i) < fn(j) + }) + + return + } + + // Descending + sort.Slice(results, func(i, j int) bool { + if fn(i) == fn(j) { + return results[i].name() > results[j].name() + } + + return fn(i) > fn(j) + }) +} diff --git a/pkg/api/sort_test.go b/pkg/api/sort_test.go new file mode 100644 index 0000000000000000000000000000000000000000..30a9c3a62a0bad61041bbe317bd70fbc01cf030b --- /dev/null +++ b/pkg/api/sort_test.go @@ -0,0 +1,1689 @@ +package api + +import ( + "fmt" + "net/url" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" +) + +func TestSortRouters(t *testing.T) { + testCases := []struct { + direction string + sortBy string + elements []orderedRouter + expected []orderedRouter + }{ + { + direction: ascendantSorting, + sortBy: "name", + elements: []orderedRouter{ + routerRepresentation{ + Name: "b", + }, + routerRepresentation{ + Name: "a", + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "a", + }, + routerRepresentation{ + Name: "b", + }, + }, + }, + { + direction: descendantSorting, + sortBy: "name", + elements: []orderedRouter{ + routerRepresentation{ + Name: "a", + }, + routerRepresentation{ + Name: "b", + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "b", + }, + routerRepresentation{ + Name: "a", + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "provider", + elements: []orderedRouter{ + routerRepresentation{ + Name: "b", + Provider: "b", + }, + routerRepresentation{ + Name: "b", + Provider: "a", + }, + routerRepresentation{ + Name: "a", + Provider: "b", + }, + routerRepresentation{ + Name: "a", + Provider: "a", + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "a", + Provider: "a", + }, + routerRepresentation{ + Name: "b", + Provider: "a", + }, + routerRepresentation{ + Name: "a", + Provider: "b", + }, + routerRepresentation{ + Name: "b", + Provider: "b", + }, + }, + }, + { + direction: descendantSorting, + sortBy: "provider", + elements: []orderedRouter{ + routerRepresentation{ + Name: "a", + Provider: "a", + }, + routerRepresentation{ + Name: "a", + Provider: "b", + }, + routerRepresentation{ + Name: "b", + Provider: "a", + }, + routerRepresentation{ + Name: "b", + Provider: "b", + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "b", + Provider: "b", + }, + routerRepresentation{ + Name: "a", + Provider: "b", + }, + routerRepresentation{ + Name: "b", + Provider: "a", + }, + routerRepresentation{ + Name: "a", + Provider: "a", + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "priority", + elements: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 2, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 2, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 1, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 1, + }, + }, + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 1, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 1, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 2, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 2, + }, + }, + }, + }, + }, + { + direction: descendantSorting, + sortBy: "priority", + elements: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 1, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 1, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 2, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 2, + }, + }, + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 2, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 2, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 1, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Priority: 1, + }, + }, + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "status", + elements: []orderedRouter{ + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Status: "b", + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Status: "b", + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Status: "a", + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Status: "a", + }, + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Status: "a", + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Status: "a", + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Status: "b", + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Status: "b", + }, + }, + }, + }, + { + direction: descendantSorting, + sortBy: "status", + elements: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Status: "a", + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Status: "a", + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Status: "b", + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Status: "b", + }, + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Status: "b", + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Status: "b", + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Status: "a", + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Status: "a", + }, + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "rule", + elements: []orderedRouter{ + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "b", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "b", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "a", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "a", + }, + }, + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "a", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "a", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "b", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "b", + }, + }, + }, + }, + }, + { + direction: descendantSorting, + sortBy: "rule", + elements: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "a", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "a", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "b", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "b", + }, + }, + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "b", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "b", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "a", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Rule: "a", + }, + }, + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "service", + elements: []orderedRouter{ + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "b", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "b", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "a", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "a", + }, + }, + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "a", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "a", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "b", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "b", + }, + }, + }, + }, + }, + { + direction: descendantSorting, + sortBy: "service", + elements: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "a", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "a", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "b", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "b", + }, + }, + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "b", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "b", + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "a", + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + Service: "a", + }, + }, + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "entryPoints", + elements: []orderedRouter{ + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a", "b"}, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a", "b"}, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a"}, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a"}, + }, + }, + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a"}, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a"}, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a", "b"}, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a", "b"}, + }, + }, + }, + }, + }, + { + direction: descendantSorting, + sortBy: "entryPoints", + elements: []orderedRouter{ + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a"}, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a"}, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a", "b"}, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a", "b"}, + }, + }, + }, + }, + expected: []orderedRouter{ + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a", "b"}, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a", "b"}, + }, + }, + }, + routerRepresentation{ + Name: "b", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a"}, + }, + }, + }, + routerRepresentation{ + Name: "a", + RouterInfo: &runtime.RouterInfo{ + Router: &dynamic.Router{ + EntryPoints: []string{"a"}, + }, + }, + }, + }, + }, + } + for _, test := range testCases { + test := test + t.Run(fmt.Sprintf("%s-%s", test.direction, test.sortBy), func(t *testing.T) { + t.Parallel() + + u, err := url.Parse(fmt.Sprintf("/?direction=%s&sortBy=%s", test.direction, test.sortBy)) + require.NoError(t, err) + + sortRouters(u.Query(), test.elements) + + assert.Equal(t, test.expected, test.elements) + }) + } +} + +func TestSortServices(t *testing.T) { + testCases := []struct { + direction string + sortBy string + elements []orderedService + expected []orderedService + }{ + { + direction: ascendantSorting, + sortBy: "name", + elements: []orderedService{ + serviceRepresentation{ + Name: "b", + }, + serviceRepresentation{ + Name: "a", + }, + }, + expected: []orderedService{ + serviceRepresentation{ + Name: "a", + }, + serviceRepresentation{ + Name: "b", + }, + }, + }, + { + direction: descendantSorting, + sortBy: "name", + elements: []orderedService{ + serviceRepresentation{ + Name: "a", + }, + serviceRepresentation{ + Name: "b", + }, + }, + expected: []orderedService{ + serviceRepresentation{ + Name: "b", + }, + serviceRepresentation{ + Name: "a", + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "type", + elements: []orderedService{ + serviceRepresentation{ + Name: "b", + Type: "b", + }, + serviceRepresentation{ + Name: "a", + Type: "b", + }, + serviceRepresentation{ + Name: "b", + Type: "a", + }, + serviceRepresentation{ + Name: "a", + Type: "a", + }, + }, + expected: []orderedService{ + serviceRepresentation{ + Name: "a", + Type: "a", + }, + serviceRepresentation{ + Name: "b", + Type: "a", + }, + serviceRepresentation{ + Name: "a", + Type: "b", + }, + serviceRepresentation{ + Name: "b", + Type: "b", + }, + }, + }, + { + direction: descendantSorting, + sortBy: "type", + elements: []orderedService{ + serviceRepresentation{ + Name: "a", + Type: "a", + }, + serviceRepresentation{ + Name: "b", + Type: "a", + }, + serviceRepresentation{ + Name: "a", + Type: "b", + }, + serviceRepresentation{ + Name: "b", + Type: "b", + }, + }, + expected: []orderedService{ + serviceRepresentation{ + Name: "b", + Type: "b", + }, + serviceRepresentation{ + Name: "a", + Type: "b", + }, + serviceRepresentation{ + Name: "b", + Type: "a", + }, + serviceRepresentation{ + Name: "a", + Type: "a", + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "servers", + elements: []orderedService{ + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 2), + }, + }, + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 2), + }, + }, + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 1), + }, + }, + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 1), + }, + }, + }, + }, + }, + expected: []orderedService{ + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 1), + }, + }, + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 1), + }, + }, + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 2), + }, + }, + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 2), + }, + }, + }, + }, + }, + }, + { + direction: descendantSorting, + sortBy: "servers", + elements: []orderedService{ + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 1), + }, + }, + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 1), + }, + }, + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 2), + }, + }, + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 2), + }, + }, + }, + }, + }, + expected: []orderedService{ + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 2), + }, + }, + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 2), + }, + }, + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 1), + }, + }, + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: make([]dynamic.Server, 1), + }, + }, + }, + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "provider", + elements: []orderedService{ + serviceRepresentation{ + Name: "b", + Provider: "b", + }, + serviceRepresentation{ + Name: "b", + Provider: "a", + }, + serviceRepresentation{ + Name: "a", + Provider: "b", + }, + serviceRepresentation{ + Name: "a", + Provider: "a", + }, + }, + expected: []orderedService{ + serviceRepresentation{ + Name: "a", + Provider: "a", + }, + serviceRepresentation{ + Name: "b", + Provider: "a", + }, + serviceRepresentation{ + Name: "a", + Provider: "b", + }, + serviceRepresentation{ + Name: "b", + Provider: "b", + }, + }, + }, + { + direction: descendantSorting, + sortBy: "provider", + elements: []orderedService{ + serviceRepresentation{ + Name: "a", + Provider: "a", + }, + serviceRepresentation{ + Name: "a", + Provider: "b", + }, + serviceRepresentation{ + Name: "b", + Provider: "a", + }, + serviceRepresentation{ + Name: "b", + Provider: "b", + }, + }, + expected: []orderedService{ + serviceRepresentation{ + Name: "b", + Provider: "b", + }, + serviceRepresentation{ + Name: "a", + Provider: "b", + }, + serviceRepresentation{ + Name: "b", + Provider: "a", + }, + serviceRepresentation{ + Name: "a", + Provider: "a", + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "status", + elements: []orderedService{ + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Status: "b", + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Status: "b", + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Status: "a", + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Status: "a", + }, + }, + }, + expected: []orderedService{ + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Status: "a", + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Status: "a", + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Status: "b", + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Status: "b", + }, + }, + }, + }, + { + direction: descendantSorting, + sortBy: "status", + elements: []orderedService{ + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Status: "a", + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Status: "a", + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Status: "b", + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Status: "b", + }, + }, + }, + expected: []orderedService{ + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Status: "b", + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Status: "b", + }, + }, + serviceRepresentation{ + Name: "b", + ServiceInfo: &runtime.ServiceInfo{ + Status: "a", + }, + }, + serviceRepresentation{ + Name: "a", + ServiceInfo: &runtime.ServiceInfo{ + Status: "a", + }, + }, + }, + }, + } + for _, test := range testCases { + test := test + t.Run(fmt.Sprintf("%s-%s", test.direction, test.sortBy), func(t *testing.T) { + t.Parallel() + + u, err := url.Parse(fmt.Sprintf("/?direction=%s&sortBy=%s", test.direction, test.sortBy)) + require.NoError(t, err) + + sortServices(u.Query(), test.elements) + + assert.Equal(t, test.expected, test.elements) + }) + } +} + +func TestSortMiddlewares(t *testing.T) { + testCases := []struct { + direction string + sortBy string + elements []orderedMiddleware + expected []orderedMiddleware + }{ + { + direction: ascendantSorting, + sortBy: "name", + elements: []orderedMiddleware{ + middlewareRepresentation{ + Name: "b", + }, + middlewareRepresentation{ + Name: "a", + }, + }, + expected: []orderedMiddleware{ + middlewareRepresentation{ + Name: "a", + }, + middlewareRepresentation{ + Name: "b", + }, + }, + }, + { + direction: descendantSorting, + sortBy: "name", + elements: []orderedMiddleware{ + middlewareRepresentation{ + Name: "a", + }, + middlewareRepresentation{ + Name: "b", + }, + }, + expected: []orderedMiddleware{ + middlewareRepresentation{ + Name: "b", + }, + middlewareRepresentation{ + Name: "a", + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "type", + elements: []orderedMiddleware{ + middlewareRepresentation{ + Name: "b", + Type: "b", + }, + middlewareRepresentation{ + Name: "a", + Type: "b", + }, + middlewareRepresentation{ + Name: "b", + Type: "a", + }, + middlewareRepresentation{ + Name: "a", + Type: "a", + }, + }, + expected: []orderedMiddleware{ + middlewareRepresentation{ + Name: "a", + Type: "a", + }, + middlewareRepresentation{ + Name: "b", + Type: "a", + }, + middlewareRepresentation{ + Name: "a", + Type: "b", + }, + middlewareRepresentation{ + Name: "b", + Type: "b", + }, + }, + }, + { + direction: descendantSorting, + sortBy: "type", + elements: []orderedMiddleware{ + middlewareRepresentation{ + Name: "a", + Type: "a", + }, + middlewareRepresentation{ + Name: "b", + Type: "a", + }, + middlewareRepresentation{ + Name: "a", + Type: "b", + }, + middlewareRepresentation{ + Name: "b", + Type: "b", + }, + }, + expected: []orderedMiddleware{ + middlewareRepresentation{ + Name: "b", + Type: "b", + }, + middlewareRepresentation{ + Name: "a", + Type: "b", + }, + middlewareRepresentation{ + Name: "b", + Type: "a", + }, + middlewareRepresentation{ + Name: "a", + Type: "a", + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "provider", + elements: []orderedMiddleware{ + middlewareRepresentation{ + Name: "b", + Provider: "b", + }, + middlewareRepresentation{ + Name: "b", + Provider: "a", + }, + middlewareRepresentation{ + Name: "a", + Provider: "b", + }, + middlewareRepresentation{ + Name: "a", + Provider: "a", + }, + }, + expected: []orderedMiddleware{ + middlewareRepresentation{ + Name: "a", + Provider: "a", + }, + middlewareRepresentation{ + Name: "b", + Provider: "a", + }, + middlewareRepresentation{ + Name: "a", + Provider: "b", + }, + middlewareRepresentation{ + Name: "b", + Provider: "b", + }, + }, + }, + { + direction: descendantSorting, + sortBy: "provider", + elements: []orderedMiddleware{ + middlewareRepresentation{ + Name: "a", + Provider: "a", + }, + middlewareRepresentation{ + Name: "a", + Provider: "b", + }, + middlewareRepresentation{ + Name: "b", + Provider: "a", + }, + middlewareRepresentation{ + Name: "b", + Provider: "b", + }, + }, + expected: []orderedMiddleware{ + middlewareRepresentation{ + Name: "b", + Provider: "b", + }, + middlewareRepresentation{ + Name: "a", + Provider: "b", + }, + middlewareRepresentation{ + Name: "b", + Provider: "a", + }, + middlewareRepresentation{ + Name: "a", + Provider: "a", + }, + }, + }, + { + direction: ascendantSorting, + sortBy: "status", + elements: []orderedMiddleware{ + middlewareRepresentation{ + Name: "b", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "b", + }, + }, + middlewareRepresentation{ + Name: "a", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "b", + }, + }, + middlewareRepresentation{ + Name: "b", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "a", + }, + }, + middlewareRepresentation{ + Name: "a", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "a", + }, + }, + }, + expected: []orderedMiddleware{ + middlewareRepresentation{ + Name: "a", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "a", + }, + }, + middlewareRepresentation{ + Name: "b", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "a", + }, + }, + middlewareRepresentation{ + Name: "a", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "b", + }, + }, + middlewareRepresentation{ + Name: "b", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "b", + }, + }, + }, + }, + { + direction: descendantSorting, + sortBy: "status", + elements: []orderedMiddleware{ + middlewareRepresentation{ + Name: "a", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "a", + }, + }, + middlewareRepresentation{ + Name: "b", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "a", + }, + }, + middlewareRepresentation{ + Name: "a", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "b", + }, + }, + middlewareRepresentation{ + Name: "b", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "b", + }, + }, + }, + expected: []orderedMiddleware{ + middlewareRepresentation{ + Name: "b", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "b", + }, + }, + middlewareRepresentation{ + Name: "a", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "b", + }, + }, + middlewareRepresentation{ + Name: "b", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "a", + }, + }, + middlewareRepresentation{ + Name: "a", + MiddlewareInfo: &runtime.MiddlewareInfo{ + Status: "a", + }, + }, + }, + }, + } + for _, test := range testCases { + test := test + t.Run(fmt.Sprintf("%s-%s", test.direction, test.sortBy), func(t *testing.T) { + t.Parallel() + + u, err := url.Parse(fmt.Sprintf("/?direction=%s&sortBy=%s", test.direction, test.sortBy)) + require.NoError(t, err) + + sortMiddlewares(u.Query(), test.elements) + + assert.Equal(t, test.expected, test.elements) + }) + } +} diff --git a/pkg/api/testdata/overview-providers.json b/pkg/api/testdata/overview-providers.json index 95d4d10d2ca6537653f479775c71517f9c789efa..20f1343542f8ec73e619d07457203fa3e649cbd8 100644 --- a/pkg/api/testdata/overview-providers.json +++ b/pkg/api/testdata/overview-providers.json @@ -25,11 +25,9 @@ "providers": [ "Docker", "File", - "Marathon", "KubernetesIngress", "KubernetesCRD", "Rest", - "Rancher", "plugin-test" ], "tcp": { diff --git a/pkg/api/testdata/routers-filtered-middlewareName.json b/pkg/api/testdata/routers-filtered-middlewareName.json new file mode 100644 index 0000000000000000000000000000000000000000..d227748c503586c3bf1aff6c50ace0e61ef1534f --- /dev/null +++ b/pkg/api/testdata/routers-filtered-middlewareName.json @@ -0,0 +1,36 @@ +[ + { + "entryPoints": [ + "web" + ], + "middlewares": [ + "auth", + "addPrefixTest@anotherprovider" + ], + "name": "bar@myprovider", + "provider": "myprovider", + "rule": "Host(`foo.bar`)", + "service": "foo-service@myprovider", + "status": "disabled", + "using": [ + "web" + ] + }, + { + "entryPoints": [ + "web" + ], + "middlewares": [ + "addPrefixTest", + "auth" + ], + "name": "test@myprovider", + "provider": "myprovider", + "rule": "Host(`fii.bar.other`)", + "service": "fii-service@myprovider", + "status": "enabled", + "using": [ + "web" + ] + } +] \ No newline at end of file diff --git a/pkg/api/testdata/routers-filtered-serviceName.json b/pkg/api/testdata/routers-filtered-serviceName.json new file mode 100644 index 0000000000000000000000000000000000000000..7d50bc03a4f5ba94c4adf86f8064ff186becfae8 --- /dev/null +++ b/pkg/api/testdata/routers-filtered-serviceName.json @@ -0,0 +1,32 @@ +[ + { + "entryPoints": [ + "web" + ], + "name": "foo@otherprovider", + "provider": "otherprovider", + "rule": "Host(`fii.foo.other`)", + "service": "fii-service", + "status": "enabled", + "using": [ + "web" + ] + }, + { + "entryPoints": [ + "web" + ], + "middlewares": [ + "addPrefixTest", + "auth" + ], + "name": "test@myprovider", + "provider": "myprovider", + "rule": "Host(`fii.bar.other`)", + "service": "fii-service@myprovider", + "status": "enabled", + "using": [ + "web" + ] + } +] \ No newline at end of file diff --git a/pkg/api/testdata/tcprouters-filtered-middlewareName.json b/pkg/api/testdata/tcprouters-filtered-middlewareName.json new file mode 100644 index 0000000000000000000000000000000000000000..e3f5352ecb3cd959f321c9706e3dfe1a91d21d68 --- /dev/null +++ b/pkg/api/testdata/tcprouters-filtered-middlewareName.json @@ -0,0 +1,36 @@ +[ + { + "entryPoints": [ + "web" + ], + "middlewares": [ + "auth", + "inflightconn@myprovider" + ], + "name": "bar@myprovider", + "provider": "myprovider", + "rule": "Host(`foo.bar`)", + "service": "foo-service", + "status": "warning", + "using": [ + "web" + ] + }, + { + "entryPoints": [ + "web" + ], + "middlewares": [ + "inflightconn@myprovider", + "auth" + ], + "name": "foo@myprovider", + "provider": "myprovider", + "rule": "Host(`foo.bar`)", + "service": "bar-service@myprovider", + "status": "disabled", + "using": [ + "web" + ] + } +] \ No newline at end of file diff --git a/pkg/api/testdata/tcprouters-filtered-serviceName.json b/pkg/api/testdata/tcprouters-filtered-serviceName.json new file mode 100644 index 0000000000000000000000000000000000000000..6bf20f9db2bd50535c41bb76680d765c7c4fe3d1 --- /dev/null +++ b/pkg/api/testdata/tcprouters-filtered-serviceName.json @@ -0,0 +1,31 @@ +[ + { + "entryPoints": [ + "web" + ], + "name": "bar@myprovider", + "provider": "myprovider", + "rule": "Host(`foo.bar`)", + "service": "foo-service", + "status": "warning", + "using": [ + "web" + ] + }, + { + "entryPoints": [ + "web" + ], + "name": "test@myprovider", + "provider": "myprovider", + "rule": "Host(`foo.bar.other`)", + "service": "foo-service@myprovider", + "status": "enabled", + "using": [ + "web" + ], + "tls": { + "passthrough": false + } + } +] \ No newline at end of file diff --git a/pkg/api/testdata/udprouters-filtered-serviceName.json b/pkg/api/testdata/udprouters-filtered-serviceName.json new file mode 100644 index 0000000000000000000000000000000000000000..bf387bfbc2e6c5697c6f391d15d5e7fd00cda59a --- /dev/null +++ b/pkg/api/testdata/udprouters-filtered-serviceName.json @@ -0,0 +1,26 @@ +[ + { + "entryPoints": [ + "web" + ], + "name": "bar@myprovider", + "provider": "myprovider", + "service": "foo-service", + "status": "warning", + "using": [ + "web" + ] + }, + { + "entryPoints": [ + "web" + ], + "name": "test@myprovider", + "provider": "myprovider", + "service": "foo-service@myprovider", + "status": "enabled", + "using": [ + "web" + ] + } +] \ No newline at end of file diff --git a/pkg/collector/collector.go b/pkg/collector/collector.go index 49f679a93a796bdc1f9ce4a622ea9c2d4a97d449..1de1934babd3d5063896764f312ca330bb23b5c1 100644 --- a/pkg/collector/collector.go +++ b/pkg/collector/collector.go @@ -11,15 +11,17 @@ import ( "github.com/mitchellh/hashstructure" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/redactor" - "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/redactor" + "github.com/traefik/traefik/v3/pkg/version" ) // collectorURL URL where the stats are sent. const collectorURL = "https://collect.traefik.io/9vxmmkcdmalbdi635d4jgc5p5rx0h7h8" // Collected data. +// +//nolint:musttag // cannot be changed for historical reasons. type data struct { Version string Codename string diff --git a/pkg/collector/collector_test.go b/pkg/collector/collector_test.go index b091f0c4f7adcc2374697676a853cdf374b31d5d..44c1ecef7871797a8c2c73ae6cf8a261f6efb78e 100644 --- a/pkg/collector/collector_test.go +++ b/pkg/collector/collector_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/config/static" ) func Test_createBody(t *testing.T) { diff --git a/pkg/config/dynamic/config.go b/pkg/config/dynamic/config.go index d23315d6b10c4aee86e0dc5497b547379b417989..af9f657af0bfbd002ba50b773ebafe94f9fcc020 100644 --- a/pkg/config/dynamic/config.go +++ b/pkg/config/dynamic/config.go @@ -1,7 +1,7 @@ package dynamic import ( - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/tls" ) // +k8s:deepcopy-gen=true diff --git a/pkg/config/dynamic/fixtures/sample.toml b/pkg/config/dynamic/fixtures/sample.toml index 6f5137f4cb56f24ad2b08311622023bc69cec37f..2cbbf5a60fcbc7e1f5218dff93037c15cf110b9b 100644 --- a/pkg/config/dynamic/fixtures/sample.toml +++ b/pkg/config/dynamic/fixtures/sample.toml @@ -54,28 +54,6 @@ watch = true filename = "foobar" debugLogGeneratedTemplate = true - [providers.marathon] - constraints = "foobar" - trace = true - watch = true - endpoint = "foobar" - defaultRule = "foobar" - exposedByDefault = true - dcosToken = "foobar" - dialerTimeout = 42 - responseHeaderTimeout = 42 - tlsHandshakeTimeout = 42 - keepAlive = 42 - forceTaskHostname = true - respectReadinessChecks = true - [providers.marathon.tls] - ca = "foobar" - cert = "foobar" - key = "foobar" - insecureSkipVerify = true - [providers.marathon.basic] - httpBasicAuthUser = "foobar" - httpBasicPassword = "foobar" [providers.kubernetesIngress] endpoint = "foobar" token = "foobar" @@ -96,15 +74,6 @@ ingressClass = "foobar" [providers.rest] entryPoint = "foobar" - [providers.rancher] - constraints = "foobar" - watch = true - defaultRule = "foobar" - exposedByDefault = true - enableServiceHealthFilter = true - refreshSeconds = 42 - intervalPoll = true - prefix = "foobar" [api] entryPoint = "foobar" @@ -124,14 +93,6 @@ [metrics.statsD] address = "foobar" pushInterval = "10s" - [metrics.influxDB] - address = "foobar" - protocol = "foobar" - pushInterval = "10s" - database = "foobar" - retentionPolicy = "foobar" - username = "foobar" - password = "foobar" [ping] entryPoint = "foobar" @@ -180,6 +141,7 @@ sampleRate = 42.0 [tracing.datadog] localAgentHostPort = "foobar" + localAgentSocket = "foobar" debug = true prioritySampling = true traceIDHeaderName = "foobar" diff --git a/pkg/config/dynamic/http_config.go b/pkg/config/dynamic/http_config.go index 746ced781d6b617c8de1c40c5381b042832700db..4f3df4d8a5aa170672719edbc31624832bec8254 100644 --- a/pkg/config/dynamic/http_config.go +++ b/pkg/config/dynamic/http_config.go @@ -5,8 +5,8 @@ import ( "time" ptypes "github.com/traefik/paerser/types" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" ) const ( @@ -264,15 +264,15 @@ type HealthCheck struct{} // ServersTransport options to configure communication between Traefik and the servers. type ServersTransport struct { - ServerName string `description:"ServerName used to contact the server." json:"serverName,omitempty" toml:"serverName,omitempty" yaml:"serverName,omitempty"` - InsecureSkipVerify bool `description:"Disable SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"` - RootCAs []traefiktls.FileOrContent `description:"Add cert file for self-signed certificate." json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"` - Certificates traefiktls.Certificates `description:"Certificates for mTLS." json:"certificates,omitempty" toml:"certificates,omitempty" yaml:"certificates,omitempty" export:"true"` + ServerName string `description:"Defines the serverName used to contact the server." json:"serverName,omitempty" toml:"serverName,omitempty" yaml:"serverName,omitempty"` + InsecureSkipVerify bool `description:"Disables SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"` + RootCAs []traefiktls.FileOrContent `description:"Defines a list of CA secret used to validate self-signed certificate" json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"` + Certificates traefiktls.Certificates `description:"Defines a list of secret storing client certificates for mTLS." json:"certificates,omitempty" toml:"certificates,omitempty" yaml:"certificates,omitempty" export:"true"` MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used" json:"maxIdleConnsPerHost,omitempty" toml:"maxIdleConnsPerHost,omitempty" yaml:"maxIdleConnsPerHost,omitempty" export:"true"` - ForwardingTimeouts *ForwardingTimeouts `description:"Timeouts for requests forwarded to the backend servers." json:"forwardingTimeouts,omitempty" toml:"forwardingTimeouts,omitempty" yaml:"forwardingTimeouts,omitempty" export:"true"` - DisableHTTP2 bool `description:"Disable HTTP/2 for connections with backend servers." json:"disableHTTP2,omitempty" toml:"disableHTTP2,omitempty" yaml:"disableHTTP2,omitempty" export:"true"` - PeerCertURI string `description:"URI used to match against SAN URI during the peer certificate verification." json:"peerCertURI,omitempty" toml:"peerCertURI,omitempty" yaml:"peerCertURI,omitempty" export:"true"` - Spiffe *Spiffe `description:"Define the SPIFFE configuration." json:"spiffe,omitempty" toml:"spiffe,omitempty" yaml:"spiffe,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` + ForwardingTimeouts *ForwardingTimeouts `description:"Defines the timeouts for requests forwarded to the backend servers." json:"forwardingTimeouts,omitempty" toml:"forwardingTimeouts,omitempty" yaml:"forwardingTimeouts,omitempty" export:"true"` + DisableHTTP2 bool `description:"Disables HTTP/2 for connections with backend servers." json:"disableHTTP2,omitempty" toml:"disableHTTP2,omitempty" yaml:"disableHTTP2,omitempty" export:"true"` + PeerCertURI string `description:"Defines the URI used to match against SAN URI during the peer certificate verification." json:"peerCertURI,omitempty" toml:"peerCertURI,omitempty" yaml:"peerCertURI,omitempty" export:"true"` + Spiffe *Spiffe `description:"Defines the SPIFFE configuration." json:"spiffe,omitempty" toml:"spiffe,omitempty" yaml:"spiffe,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` } // +k8s:deepcopy-gen=true diff --git a/pkg/config/dynamic/middlewares.go b/pkg/config/dynamic/middlewares.go index 97981ae8acf3e8f9745827f99e0a0f6e0785dd1a..748a205bc3835477d00a74445379f19518bf2551 100644 --- a/pkg/config/dynamic/middlewares.go +++ b/pkg/config/dynamic/middlewares.go @@ -4,8 +4,8 @@ import ( "time" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/ip" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/ip" + "github.com/traefik/traefik/v3/pkg/types" ) // +k8s:deepcopy-gen=true diff --git a/pkg/config/dynamic/tcp_config.go b/pkg/config/dynamic/tcp_config.go index 19007fa8c978c9e795845a76bc13bfb39d36b7ab..e4639a1eadd1933b204228c5a5c065b699480c99 100644 --- a/pkg/config/dynamic/tcp_config.go +++ b/pkg/config/dynamic/tcp_config.go @@ -2,17 +2,21 @@ package dynamic import ( "reflect" + "time" - "github.com/traefik/traefik/v2/pkg/types" + ptypes "github.com/traefik/paerser/types" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" ) // +k8s:deepcopy-gen=true // TCPConfiguration contains all the TCP configuration parameters. type TCPConfiguration struct { - Routers map[string]*TCPRouter `json:"routers,omitempty" toml:"routers,omitempty" yaml:"routers,omitempty" export:"true"` - Services map[string]*TCPService `json:"services,omitempty" toml:"services,omitempty" yaml:"services,omitempty" export:"true"` - Middlewares map[string]*TCPMiddleware `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"` + Routers map[string]*TCPRouter `json:"routers,omitempty" toml:"routers,omitempty" yaml:"routers,omitempty" export:"true"` + Services map[string]*TCPService `json:"services,omitempty" toml:"services,omitempty" yaml:"services,omitempty" export:"true"` + Middlewares map[string]*TCPMiddleware `json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"` + ServersTransports map[string]*TCPServersTransport `json:"serversTransports,omitempty" toml:"serversTransports,omitempty" yaml:"serversTransports,omitempty" label:"-" export:"true"` } // +k8s:deepcopy-gen=true @@ -70,20 +74,9 @@ type RouterTCPTLSConfig struct { // TCPServersLoadBalancer holds the LoadBalancerService configuration. type TCPServersLoadBalancer struct { - // TerminationDelay, corresponds to the deadline that the proxy sets, after one - // of its connected peers indicates it has closed the writing capability of its - // connection, to close the reading capability as well, hence fully terminating the - // connection. It is a duration in milliseconds, defaulting to 100. A negative value - // means an infinite deadline (i.e. the reading capability is never closed). - TerminationDelay *int `json:"terminationDelay,omitempty" toml:"terminationDelay,omitempty" yaml:"terminationDelay,omitempty" export:"true"` ProxyProtocol *ProxyProtocol `json:"proxyProtocol,omitempty" toml:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"` Servers []TCPServer `json:"servers,omitempty" toml:"servers,omitempty" yaml:"servers,omitempty" label-slice-as-struct:"server" export:"true"` -} - -// SetDefaults Default values for a TCPServersLoadBalancer. -func (l *TCPServersLoadBalancer) SetDefaults() { - defaultTerminationDelay := 100 // in milliseconds - l.TerminationDelay = &defaultTerminationDelay + ServersTransport string `json:"serversTransport,omitempty" toml:"serversTransport,omitempty" yaml:"serversTransport,omitempty" export:"true"` } // Mergeable tells if the given service is mergeable. @@ -109,6 +102,7 @@ func (l *TCPServersLoadBalancer) Mergeable(loadBalancer *TCPServersLoadBalancer) type TCPServer struct { Address string `json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty" label:"-"` Port string `toml:"-" json:"-" yaml:"-"` + TLS bool `json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty"` } // +k8s:deepcopy-gen=true @@ -124,3 +118,37 @@ type ProxyProtocol struct { func (p *ProxyProtocol) SetDefaults() { p.Version = 2 } + +// +k8s:deepcopy-gen=true + +// TCPServersTransport options to configure communication between Traefik and the servers. +type TCPServersTransport struct { + DialKeepAlive ptypes.Duration `description:"Defines the interval between keep-alive probes for an active network connection. If zero, keep-alive probes are sent with a default value (currently 15 seconds), if supported by the protocol and operating system. Network protocols or operating systems that do not support keep-alives ignore this field. If negative, keep-alive probes are disabled" json:"dialKeepAlive,omitempty" toml:"dialKeepAlive,omitempty" yaml:"dialKeepAlive,omitempty" export:"true"` + DialTimeout ptypes.Duration `description:"Defines the amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists." json:"dialTimeout,omitempty" toml:"dialTimeout,omitempty" yaml:"dialTimeout,omitempty" export:"true"` + // TerminationDelay, corresponds to the deadline that the proxy sets, after one + // of its connected peers indicates it has closed the writing capability of its + // connection, to close the reading capability as well, hence fully terminating the + // connection. It is a duration in milliseconds, defaulting to 100. A negative value + // means an infinite deadline (i.e. the reading capability is never closed). + TerminationDelay ptypes.Duration `description:"Defines the delay to wait before fully terminating the connection, after one connected peer has closed its writing capability." json:"terminationDelay,omitempty" toml:"terminationDelay,omitempty" yaml:"terminationDelay,omitempty" export:"true"` + TLS *TLSClientConfig `description:"Defines the TLS configuration." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"` +} + +// +k8s:deepcopy-gen=true + +// TLSClientConfig options to configure TLS communication between Traefik and the servers. +type TLSClientConfig struct { + ServerName string `description:"Defines the serverName used to contact the server." json:"serverName,omitempty" toml:"serverName,omitempty" yaml:"serverName,omitempty"` + InsecureSkipVerify bool `description:"Disables SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"` + RootCAs []traefiktls.FileOrContent `description:"Defines a list of CA secret used to validate self-signed certificate" json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"` + Certificates traefiktls.Certificates `description:"Defines a list of secret storing client certificates for mTLS." json:"certificates,omitempty" toml:"certificates,omitempty" yaml:"certificates,omitempty" export:"true"` + PeerCertURI string `description:"Defines the URI used to match against SAN URI during the peer certificate verification." json:"peerCertURI,omitempty" toml:"peerCertURI,omitempty" yaml:"peerCertURI,omitempty" export:"true"` + Spiffe *Spiffe `description:"Defines the SPIFFE TLS configuration." json:"spiffe,omitempty" toml:"spiffe,omitempty" yaml:"spiffe,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` +} + +// SetDefaults sets the default values for a TCPServersTransport. +func (t *TCPServersTransport) SetDefaults() { + t.DialTimeout = ptypes.Duration(30 * time.Second) + t.DialKeepAlive = ptypes.Duration(15 * time.Second) + t.TerminationDelay = ptypes.Duration(100 * time.Millisecond) +} diff --git a/pkg/config/dynamic/zz_generated.deepcopy.go b/pkg/config/dynamic/zz_generated.deepcopy.go index 1abb4727e4cfb5d42f3a2fc9671e74b3989e8e58..29251247e9af6b64561abda3fecca956b1f61f4d 100644 --- a/pkg/config/dynamic/zz_generated.deepcopy.go +++ b/pkg/config/dynamic/zz_generated.deepcopy.go @@ -4,7 +4,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,8 @@ THE SOFTWARE. package dynamic import ( - tls "github.com/traefik/traefik/v2/pkg/tls" - types "github.com/traefik/traefik/v2/pkg/types" + tls "github.com/traefik/traefik/v3/pkg/tls" + types "github.com/traefik/traefik/v3/pkg/types" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -1394,6 +1394,21 @@ func (in *TCPConfiguration) DeepCopyInto(out *TCPConfiguration) { (*out)[key] = outVal } } + if in.ServersTransports != nil { + in, out := &in.ServersTransports, &out.ServersTransports + *out = make(map[string]*TCPServersTransport, len(*in)) + for key, val := range *in { + var outVal *TCPServersTransport + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = new(TCPServersTransport) + (*in).DeepCopyInto(*out) + } + (*out)[key] = outVal + } + } return } @@ -1520,11 +1535,6 @@ func (in *TCPServer) DeepCopy() *TCPServer { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TCPServersLoadBalancer) DeepCopyInto(out *TCPServersLoadBalancer) { *out = *in - if in.TerminationDelay != nil { - in, out := &in.TerminationDelay, &out.TerminationDelay - *out = new(int) - **out = **in - } if in.ProxyProtocol != nil { in, out := &in.ProxyProtocol, &out.ProxyProtocol *out = new(ProxyProtocol) @@ -1548,6 +1558,27 @@ func (in *TCPServersLoadBalancer) DeepCopy() *TCPServersLoadBalancer { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TCPServersTransport) DeepCopyInto(out *TCPServersTransport) { + *out = *in + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLSClientConfig) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPServersTransport. +func (in *TCPServersTransport) DeepCopy() *TCPServersTransport { + if in == nil { + return nil + } + out := new(TCPServersTransport) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TCPService) DeepCopyInto(out *TCPService) { *out = *in @@ -1676,6 +1707,37 @@ func (in *TLSClientCertificateSubjectDNInfo) DeepCopy() *TLSClientCertificateSub return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSClientConfig) DeepCopyInto(out *TLSClientConfig) { + *out = *in + if in.RootCAs != nil { + in, out := &in.RootCAs, &out.RootCAs + *out = make([]tls.FileOrContent, len(*in)) + copy(*out, *in) + } + if in.Certificates != nil { + in, out := &in.Certificates, &out.Certificates + *out = make(tls.Certificates, len(*in)) + copy(*out, *in) + } + if in.Spiffe != nil { + in, out := &in.Spiffe, &out.Spiffe + *out = new(Spiffe) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSClientConfig. +func (in *TLSClientConfig) DeepCopy() *TLSClientConfig { + if in == nil { + return nil + } + out := new(TLSClientConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLSConfiguration) DeepCopyInto(out *TLSConfiguration) { *out = *in diff --git a/pkg/config/label/label.go b/pkg/config/label/label.go index 1791f735fb9b09212db08dacb9a3b9f757d5d4d5..f6089a23fa078544e353e2002244848456d37faa 100644 --- a/pkg/config/label/label.go +++ b/pkg/config/label/label.go @@ -3,7 +3,7 @@ package label import ( "github.com/traefik/paerser/parser" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) // DecodeConfiguration converts the labels to a configuration. diff --git a/pkg/config/label/label_test.go b/pkg/config/label/label_test.go index 820bea328fb19a1bb000a0a9eb28e623b902aa3a..334297edce8d1c40d80c074b88fb0e6477f82889 100644 --- a/pkg/config/label/label_test.go +++ b/pkg/config/label/label_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/types" ) func TestDecodeConfiguration(t *testing.T) { @@ -157,6 +157,7 @@ func TestDecodeConfiguration(t *testing.T) { "traefik.http.services.Service0.loadbalancer.server.port": "8080", "traefik.http.services.Service0.loadbalancer.sticky.cookie.name": "foobar", "traefik.http.services.Service0.loadbalancer.sticky.cookie.secure": "true", + "traefik.http.services.Service0.loadbalancer.serversTransport": "foobar", "traefik.http.services.Service1.loadbalancer.healthcheck.headers.name0": "foobar", "traefik.http.services.Service1.loadbalancer.healthcheck.headers.name1": "foobar", "traefik.http.services.Service1.loadbalancer.healthcheck.hostname": "foobar", @@ -175,6 +176,7 @@ func TestDecodeConfiguration(t *testing.T) { "traefik.http.services.Service1.loadbalancer.server.port": "8080", "traefik.http.services.Service1.loadbalancer.sticky": "false", "traefik.http.services.Service1.loadbalancer.sticky.cookie.name": "fui", + "traefik.http.services.Service1.loadbalancer.serversTransport": "foobar", "traefik.tcp.middlewares.Middleware0.ipallowlist.sourcerange": "foobar, fiibar", "traefik.tcp.middlewares.Middleware2.inflightconn.amount": "42", @@ -191,11 +193,11 @@ func TestDecodeConfiguration(t *testing.T) { "traefik.tcp.routers.Router1.tls.options": "foo", "traefik.tcp.routers.Router1.tls.passthrough": "false", "traefik.tcp.services.Service0.loadbalancer.server.Port": "42", - "traefik.tcp.services.Service0.loadbalancer.TerminationDelay": "42", "traefik.tcp.services.Service0.loadbalancer.proxyProtocol.version": "42", + "traefik.tcp.services.Service0.loadbalancer.serversTransport": "foo", "traefik.tcp.services.Service1.loadbalancer.server.Port": "42", - "traefik.tcp.services.Service1.loadbalancer.TerminationDelay": "42", "traefik.tcp.services.Service1.loadbalancer.proxyProtocol": "true", + "traefik.tcp.services.Service1.loadbalancer.serversTransport": "foo", "traefik.udp.routers.Router0.entrypoints": "foobar, fiibar", "traefik.udp.routers.Router0.service": "foobar", @@ -258,8 +260,8 @@ func TestDecodeConfiguration(t *testing.T) { Port: "42", }, }, - TerminationDelay: func(i int) *int { return &i }(42), ProxyProtocol: &dynamic.ProxyProtocol{Version: 42}, + ServersTransport: "foo", }, }, "Service1": { @@ -269,8 +271,8 @@ func TestDecodeConfiguration(t *testing.T) { Port: "42", }, }, - TerminationDelay: func(i int) *int { return &i }(42), ProxyProtocol: &dynamic.ProxyProtocol{Version: 2}, + ServersTransport: "foo", }, }, }, @@ -659,6 +661,7 @@ func TestDecodeConfiguration(t *testing.T) { ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: ptypes.Duration(time.Second), }, + ServersTransport: "foobar", }, }, "Service1": { @@ -689,6 +692,7 @@ func TestDecodeConfiguration(t *testing.T) { ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: ptypes.Duration(time.Second), }, + ServersTransport: "foobar", }, }, }, @@ -696,6 +700,7 @@ func TestDecodeConfiguration(t *testing.T) { } assert.Nil(t, configuration.HTTP.ServersTransports) + assert.Nil(t, configuration.TCP.ServersTransports) assert.Equal(t, expected, configuration) } @@ -750,7 +755,7 @@ func TestEncodeConfiguration(t *testing.T) { Port: "42", }, }, - TerminationDelay: func(i int) *int { return &i }(42), + ServersTransport: "foo", }, }, "Service1": { @@ -760,7 +765,7 @@ func TestEncodeConfiguration(t *testing.T) { Port: "42", }, }, - TerminationDelay: func(i int) *int { return &i }(42), + ServersTransport: "foo", }, }, }, @@ -1145,6 +1150,7 @@ func TestEncodeConfiguration(t *testing.T) { ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: ptypes.Duration(time.Second), }, + ServersTransport: "foobar", }, }, "Service1": { @@ -1173,6 +1179,7 @@ func TestEncodeConfiguration(t *testing.T) { ResponseForwarding: &dynamic.ResponseForwarding{ FlushInterval: ptypes.Duration(time.Second), }, + ServersTransport: "foobar", }, }, }, @@ -1309,6 +1316,7 @@ func TestEncodeConfiguration(t *testing.T) { "traefik.HTTP.Routers.Router1.Rule": "foobar", "traefik.HTTP.Routers.Router1.Service": "foobar", + "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name0": "foobar", "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name1": "foobar", "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Hostname": "foobar", "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Interval": "1000000000", @@ -1325,6 +1333,7 @@ func TestEncodeConfiguration(t *testing.T) { "traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.Name": "foobar", "traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.HTTPOnly": "true", "traefik.HTTP.Services.Service0.LoadBalancer.Sticky.Cookie.Secure": "false", + "traefik.HTTP.Services.Service0.LoadBalancer.ServersTransport": "foobar", "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name0": "foobar", "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Headers.name1": "foobar", "traefik.HTTP.Services.Service1.LoadBalancer.HealthCheck.Hostname": "foobar", @@ -1339,7 +1348,7 @@ func TestEncodeConfiguration(t *testing.T) { "traefik.HTTP.Services.Service1.LoadBalancer.ResponseForwarding.FlushInterval": "1000000000", "traefik.HTTP.Services.Service1.LoadBalancer.server.Port": "8080", "traefik.HTTP.Services.Service1.LoadBalancer.server.Scheme": "foobar", - "traefik.HTTP.Services.Service0.LoadBalancer.HealthCheck.Headers.name0": "foobar", + "traefik.HTTP.Services.Service1.LoadBalancer.ServersTransport": "foobar", "traefik.TCP.Middlewares.Middleware0.IPAllowList.SourceRange": "foobar, fiibar", "traefik.TCP.Middlewares.Middleware2.InFlightConn.Amount": "42", @@ -1356,9 +1365,11 @@ func TestEncodeConfiguration(t *testing.T) { "traefik.TCP.Routers.Router1.TLS.Passthrough": "false", "traefik.TCP.Routers.Router1.TLS.Options": "foo", "traefik.TCP.Services.Service0.LoadBalancer.server.Port": "42", - "traefik.TCP.Services.Service0.LoadBalancer.TerminationDelay": "42", + "traefik.TCP.Services.Service0.LoadBalancer.server.TLS": "false", + "traefik.TCP.Services.Service0.LoadBalancer.ServersTransport": "foo", "traefik.TCP.Services.Service1.LoadBalancer.server.Port": "42", - "traefik.TCP.Services.Service1.LoadBalancer.TerminationDelay": "42", + "traefik.TCP.Services.Service1.LoadBalancer.server.TLS": "false", + "traefik.TCP.Services.Service1.LoadBalancer.ServersTransport": "foo", "traefik.UDP.Routers.Router0.EntryPoints": "foobar, fiibar", "traefik.UDP.Routers.Router0.Service": "foobar", diff --git a/pkg/config/runtime/runtime.go b/pkg/config/runtime/runtime.go index 8420722792bb2b61e563b64784c39826f434baf9..2738b7c60636cd971fb2f7dce6a1d9a2b75cfbf7 100644 --- a/pkg/config/runtime/runtime.go +++ b/pkg/config/runtime/runtime.go @@ -5,8 +5,8 @@ import ( "strings" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" ) // Status of the router/service. diff --git a/pkg/config/runtime/runtime_http.go b/pkg/config/runtime/runtime_http.go index 788a23a26b39480b7c33ff68c86f787237bafe67..6b9a4a3fb8aff2369f8d21c8715c833d73010635 100644 --- a/pkg/config/runtime/runtime_http.go +++ b/pkg/config/runtime/runtime_http.go @@ -7,8 +7,8 @@ import ( "sync" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" ) // GetRoutersByEntryPoints returns all the http routers by entry points name and routers name. diff --git a/pkg/config/runtime/runtime_http_test.go b/pkg/config/runtime/runtime_http_test.go index 9ac028bfbad412a27dceb7836374c561c0f2fe03..6080e770fb91660e0c08bfc98488b8c825b1d9c6 100644 --- a/pkg/config/runtime/runtime_http_test.go +++ b/pkg/config/runtime/runtime_http_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestGetRoutersByEntryPoints(t *testing.T) { diff --git a/pkg/config/runtime/runtime_tcp.go b/pkg/config/runtime/runtime_tcp.go index 665da4525edd8118d04a9c75c3ea96c3c5d2e447..c188cd2d07a5bb364104dea55caa4abb21b93b56 100644 --- a/pkg/config/runtime/runtime_tcp.go +++ b/pkg/config/runtime/runtime_tcp.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" ) // GetTCPRoutersByEntryPoints returns all the tcp routers by entry points name and routers name. diff --git a/pkg/config/runtime/runtime_tcp_test.go b/pkg/config/runtime/runtime_tcp_test.go index 067e9ee0914133c07244c24c4d5f425bb98ab981..8263d56266356f8ece15bd66a21f6a99228b1bc5 100644 --- a/pkg/config/runtime/runtime_tcp_test.go +++ b/pkg/config/runtime/runtime_tcp_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestGetTCPRoutersByEntryPoints(t *testing.T) { diff --git a/pkg/config/runtime/runtime_test.go b/pkg/config/runtime/runtime_test.go index e952cb20c1ce578847d053f08a04646309c950ce..54e34e8549181bad50256aedcbfa847bbe8cbc03 100644 --- a/pkg/config/runtime/runtime_test.go +++ b/pkg/config/runtime/runtime_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" ) // all the Routers/Middlewares/Services are considered fully qualified. diff --git a/pkg/config/runtime/runtime_udp.go b/pkg/config/runtime/runtime_udp.go index ed9a4481474ff6cfbd45c01c0e3a83baf215c31e..b0eb30e50543585d1dedaa8d29f4a46a6a54db49 100644 --- a/pkg/config/runtime/runtime_udp.go +++ b/pkg/config/runtime/runtime_udp.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" ) // GetUDPRoutersByEntryPoints returns all the UDP routers by entry points name and routers name. diff --git a/pkg/config/runtime/runtime_udp_test.go b/pkg/config/runtime/runtime_udp_test.go index 87fe2476f7b5fcd38df000822100bd7c76b026ce..5e83dff05a508083e158f11c94320f9b5c440d05 100644 --- a/pkg/config/runtime/runtime_udp_test.go +++ b/pkg/config/runtime/runtime_udp_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestGetUDPRoutersByEntryPoints(t *testing.T) { diff --git a/pkg/config/static/entrypoints.go b/pkg/config/static/entrypoints.go index 7863f1bcb0cd50df1685344b7ec020428517c9cb..db3fb231e4256977292304a2b5f901b6b4c895f5 100644 --- a/pkg/config/static/entrypoints.go +++ b/pkg/config/static/entrypoints.go @@ -6,7 +6,7 @@ import ( "strings" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/types" ) // EntryPoint holds the entry point configuration. diff --git a/pkg/config/static/experimental.go b/pkg/config/static/experimental.go index 5f16f989867ab6928378784db2d44107a9d70ac8..7428f6a089461e519dc76bf5dd97d0f03da496f3 100644 --- a/pkg/config/static/experimental.go +++ b/pkg/config/static/experimental.go @@ -1,6 +1,6 @@ package static -import "github.com/traefik/traefik/v2/pkg/plugins" +import "github.com/traefik/traefik/v3/pkg/plugins" // Experimental experimental Traefik features. type Experimental struct { @@ -8,5 +8,4 @@ type Experimental struct { LocalPlugins map[string]plugins.LocalDescriptor `description:"Local plugins configuration." json:"localPlugins,omitempty" toml:"localPlugins,omitempty" yaml:"localPlugins,omitempty" export:"true"` KubernetesGateway bool `description:"Allow the Kubernetes gateway api provider usage." json:"kubernetesGateway,omitempty" toml:"kubernetesGateway,omitempty" yaml:"kubernetesGateway,omitempty" export:"true"` - Hub bool `description:"Enable the Traefik Hub provider." json:"hub,omitempty" toml:"hub,omitempty" yaml:"hub,omitempty" export:"true"` } diff --git a/pkg/config/static/hub.go b/pkg/config/static/hub.go index 5cf97ae32ca74389519ac100c3eee94fa86a9d9a..2a87b342ab16dad02b61bbd1b34da29435b7bb8a 100644 --- a/pkg/config/static/hub.go +++ b/pkg/config/static/hub.go @@ -4,16 +4,11 @@ import ( "errors" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider/hub" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider/hub" ) func (c *Configuration) initHubProvider() error { - // Hub provider is an experimental feature. It requires the experimental flag to be enabled before continuing. - if c.Experimental == nil || !c.Experimental.Hub { - return errors.New("the experimental flag for Hub is not set") - } - if _, ok := c.EntryPoints[hub.TunnelEntrypoint]; !ok { var ep EntryPoint ep.SetDefaults() diff --git a/pkg/config/static/static_config.go b/pkg/config/static/static_config.go index da32b76f97103d4b6562681510fb55bae8d9a64b..05051ff54758a7cf7bc99881d622383e3b63425c 100644 --- a/pkg/config/static/static_config.go +++ b/pkg/config/static/static_config.go @@ -9,35 +9,33 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/ping" - acmeprovider "github.com/traefik/traefik/v2/pkg/provider/acme" - "github.com/traefik/traefik/v2/pkg/provider/consulcatalog" - "github.com/traefik/traefik/v2/pkg/provider/docker" - "github.com/traefik/traefik/v2/pkg/provider/ecs" - "github.com/traefik/traefik/v2/pkg/provider/file" - "github.com/traefik/traefik/v2/pkg/provider/http" - "github.com/traefik/traefik/v2/pkg/provider/hub" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/gateway" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/ingress" - "github.com/traefik/traefik/v2/pkg/provider/kv/consul" - "github.com/traefik/traefik/v2/pkg/provider/kv/etcd" - "github.com/traefik/traefik/v2/pkg/provider/kv/redis" - "github.com/traefik/traefik/v2/pkg/provider/kv/zk" - "github.com/traefik/traefik/v2/pkg/provider/marathon" - "github.com/traefik/traefik/v2/pkg/provider/nomad" - "github.com/traefik/traefik/v2/pkg/provider/rancher" - "github.com/traefik/traefik/v2/pkg/provider/rest" - "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/tracing/datadog" - "github.com/traefik/traefik/v2/pkg/tracing/elastic" - "github.com/traefik/traefik/v2/pkg/tracing/haystack" - "github.com/traefik/traefik/v2/pkg/tracing/instana" - "github.com/traefik/traefik/v2/pkg/tracing/jaeger" - "github.com/traefik/traefik/v2/pkg/tracing/opentelemetry" - "github.com/traefik/traefik/v2/pkg/tracing/zipkin" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/ping" + acmeprovider "github.com/traefik/traefik/v3/pkg/provider/acme" + "github.com/traefik/traefik/v3/pkg/provider/consulcatalog" + "github.com/traefik/traefik/v3/pkg/provider/docker" + "github.com/traefik/traefik/v3/pkg/provider/ecs" + "github.com/traefik/traefik/v3/pkg/provider/file" + "github.com/traefik/traefik/v3/pkg/provider/http" + "github.com/traefik/traefik/v3/pkg/provider/hub" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/gateway" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/ingress" + "github.com/traefik/traefik/v3/pkg/provider/kv/consul" + "github.com/traefik/traefik/v3/pkg/provider/kv/etcd" + "github.com/traefik/traefik/v3/pkg/provider/kv/redis" + "github.com/traefik/traefik/v3/pkg/provider/kv/zk" + "github.com/traefik/traefik/v3/pkg/provider/nomad" + "github.com/traefik/traefik/v3/pkg/provider/rest" + "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/tracing/datadog" + "github.com/traefik/traefik/v3/pkg/tracing/elastic" + "github.com/traefik/traefik/v3/pkg/tracing/haystack" + "github.com/traefik/traefik/v3/pkg/tracing/instana" + "github.com/traefik/traefik/v3/pkg/tracing/jaeger" + "github.com/traefik/traefik/v3/pkg/tracing/opentelemetry" + "github.com/traefik/traefik/v3/pkg/tracing/zipkin" + "github.com/traefik/traefik/v3/pkg/types" ) const ( @@ -63,9 +61,10 @@ const ( type Configuration struct { Global *Global `description:"Global configuration options" json:"global,omitempty" toml:"global,omitempty" yaml:"global,omitempty" export:"true"` - ServersTransport *ServersTransport `description:"Servers default transport." json:"serversTransport,omitempty" toml:"serversTransport,omitempty" yaml:"serversTransport,omitempty" export:"true"` - EntryPoints EntryPoints `description:"Entry points definition." json:"entryPoints,omitempty" toml:"entryPoints,omitempty" yaml:"entryPoints,omitempty" export:"true"` - Providers *Providers `description:"Providers configuration." json:"providers,omitempty" toml:"providers,omitempty" yaml:"providers,omitempty" export:"true"` + ServersTransport *ServersTransport `description:"Servers default transport." json:"serversTransport,omitempty" toml:"serversTransport,omitempty" yaml:"serversTransport,omitempty" export:"true"` + TCPServersTransport *TCPServersTransport `description:"TCP servers default transport." json:"tcpServersTransport,omitempty" toml:"tcpServersTransport,omitempty" yaml:"tcpServersTransport,omitempty" export:"true"` + EntryPoints EntryPoints `description:"Entry points definition." json:"entryPoints,omitempty" toml:"entryPoints,omitempty" yaml:"entryPoints,omitempty" export:"true"` + Providers *Providers `description:"Providers configuration." json:"providers,omitempty" toml:"providers,omitempty" yaml:"providers,omitempty" export:"true"` API *API `description:"Enable api/dashboard." json:"api,omitempty" toml:"api,omitempty" yaml:"api,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Metrics *types.Metrics `description:"Enable a metrics exporter." json:"metrics,omitempty" toml:"metrics,omitempty" yaml:"metrics,omitempty" export:"true"` @@ -118,6 +117,26 @@ type Spiffe struct { TrustDomain string `description:"Defines the allowed SPIFFE trust domain." json:"trustDomain,omitempty" yaml:"trustDomain,omitempty" toml:"trustDomain,omitempty"` } +// TCPServersTransport options to configure communication between Traefik and the servers. +type TCPServersTransport struct { + DialKeepAlive ptypes.Duration `description:"Defines the interval between keep-alive probes for an active network connection. If zero, keep-alive probes are sent with a default value (currently 15 seconds), if supported by the protocol and operating system. Network protocols or operating systems that do not support keep-alives ignore this field. If negative, keep-alive probes are disabled" json:"dialKeepAlive,omitempty" toml:"dialKeepAlive,omitempty" yaml:"dialKeepAlive,omitempty" export:"true"` + DialTimeout ptypes.Duration `description:"Defines the amount of time to wait until a connection to a backend server can be established. If zero, no timeout exists." json:"dialTimeout,omitempty" toml:"dialTimeout,omitempty" yaml:"dialTimeout,omitempty" export:"true"` + // TerminationDelay, corresponds to the deadline that the proxy sets, after one + // of its connected peers indicates it has closed the writing capability of its + // connection, to close the reading capability as well, hence fully terminating the + // connection. It is a duration in milliseconds, defaulting to 100. A negative value + // means an infinite deadline (i.e. the reading capability is never closed). + TerminationDelay ptypes.Duration `description:"Defines the delay to wait before fully terminating the connection, after one connected peer has closed its writing capability." json:"terminationDelay,omitempty" toml:"terminationDelay,omitempty" yaml:"terminationDelay,omitempty" export:"true"` + TLS *TLSClientConfig `description:"Defines the TLS configuration." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty" file:"allowEmpty" kv:"allowEmpty" export:"true"` +} + +// TLSClientConfig options to configure TLS communication between Traefik and the servers. +type TLSClientConfig struct { + InsecureSkipVerify bool `description:"Disables SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"` + RootCAs []tls.FileOrContent `description:"Defines a list of CA secret used to validate self-signed certificate" json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"` + Spiffe *Spiffe `description:"Defines the SPIFFE TLS configuration." json:"spiffe,omitempty" toml:"spiffe,omitempty" yaml:"spiffe,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` +} + // API holds the API configuration. type API struct { Insecure bool `description:"Activate API directly on the entryPoint named traefik." json:"insecure,omitempty" toml:"insecure,omitempty" yaml:"insecure,omitempty" export:"true"` @@ -193,12 +212,10 @@ type Providers struct { Docker *docker.Provider `description:"Enable Docker backend with default settings." json:"docker,omitempty" toml:"docker,omitempty" yaml:"docker,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` File *file.Provider `description:"Enable File backend with default settings." json:"file,omitempty" toml:"file,omitempty" yaml:"file,omitempty" export:"true"` - Marathon *marathon.Provider `description:"Enable Marathon backend with default settings." json:"marathon,omitempty" toml:"marathon,omitempty" yaml:"marathon,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` KubernetesIngress *ingress.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesIngress,omitempty" toml:"kubernetesIngress,omitempty" yaml:"kubernetesIngress,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` KubernetesCRD *crd.Provider `description:"Enable Kubernetes backend with default settings." json:"kubernetesCRD,omitempty" toml:"kubernetesCRD,omitempty" yaml:"kubernetesCRD,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` KubernetesGateway *gateway.Provider `description:"Enable Kubernetes gateway api provider with default settings." json:"kubernetesGateway,omitempty" toml:"kubernetesGateway,omitempty" yaml:"kubernetesGateway,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` Rest *rest.Provider `description:"Enable Rest backend with default settings." json:"rest,omitempty" toml:"rest,omitempty" yaml:"rest,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` - Rancher *rancher.Provider `description:"Enable Rancher backend with default settings." json:"rancher,omitempty" toml:"rancher,omitempty" yaml:"rancher,omitempty" export:"true" label:"allowEmpty" file:"allowEmpty"` ConsulCatalog *consulcatalog.ProviderBuilder `description:"Enable ConsulCatalog backend with default settings." json:"consulCatalog,omitempty" toml:"consulCatalog,omitempty" yaml:"consulCatalog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Nomad *nomad.ProviderBuilder `description:"Enable Nomad backend with default settings." json:"nomad,omitempty" toml:"nomad,omitempty" yaml:"nomad,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Ecs *ecs.Provider `description:"Enable AWS ECS backend with default settings." json:"ecs,omitempty" toml:"ecs,omitempty" yaml:"ecs,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` @@ -243,7 +260,7 @@ func (c *Configuration) SetEffectiveConfiguration() { c.Hub = nil log.Error().Err(err).Msg("Unable to activate the Hub provider") } else { - log.Debug().Msg("Experimental Hub provider has been activated") + log.Debug().Msg("Hub provider has been activated") } } @@ -257,12 +274,6 @@ func (c *Configuration) SetEffectiveConfiguration() { } } - if c.Providers.Rancher != nil { - if c.Providers.Rancher.RefreshSeconds <= 0 { - c.Providers.Rancher.RefreshSeconds = 15 - } - } - // Disable Gateway API provider if not enabled in experimental. if c.Experimental == nil || !c.Experimental.KubernetesGateway { c.Providers.KubernetesGateway = nil diff --git a/pkg/config/static/static_config_test.go b/pkg/config/static/static_config_test.go index 9680233dd0c97108fa2230267330debfa0b99ee1..26b67fbd2b717f92ae74c79fe0bf46771f6d6d61 100644 --- a/pkg/config/static/static_config_test.go +++ b/pkg/config/static/static_config_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/provider/hub" + "github.com/traefik/traefik/v3/pkg/provider/hub" ) func TestHasEntrypoint(t *testing.T) { diff --git a/pkg/healthcheck/healthcheck.go b/pkg/healthcheck/healthcheck.go index 7a590d3f173f413cc624956ed31dac6631566407..1452bfa66514a151de78f7e7e9f8f55caa2f79cb 100644 --- a/pkg/healthcheck/healthcheck.go +++ b/pkg/healthcheck/healthcheck.go @@ -12,8 +12,8 @@ import ( gokitmetrics "github.com/go-kit/kit/metrics" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials/insecure" diff --git a/pkg/healthcheck/healthcheck_test.go b/pkg/healthcheck/healthcheck_test.go index 5bc08bb941405bb0bf702df8bee33088d3d5c37f..c7813fae0959adfcaeb6f08b65321918e3f28457 100644 --- a/pkg/healthcheck/healthcheck_test.go +++ b/pkg/healthcheck/healthcheck_test.go @@ -12,9 +12,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/testhelpers" healthpb "google.golang.org/grpc/health/grpc_health_v1" ) diff --git a/pkg/healthcheck/mock_test.go b/pkg/healthcheck/mock_test.go index d2a9b52e11ae3f5675d3d07fcf3a2a733fd543a8..ba288cc26e5887bbd49282ed5d236bbb69e7d299 100644 --- a/pkg/healthcheck/mock_test.go +++ b/pkg/healthcheck/mock_test.go @@ -12,8 +12,8 @@ import ( gokitmetrics "github.com/go-kit/kit/metrics" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/testhelpers" "google.golang.org/grpc" healthpb "google.golang.org/grpc/health/grpc_health_v1" ) diff --git a/pkg/metrics/datadog.go b/pkg/metrics/datadog.go index fce4c4cc4d184df37886b1d9c9e986f1a2507732..b09e3407aa4e3a5ad378fb8f6263f54c458b4d73 100644 --- a/pkg/metrics/datadog.go +++ b/pkg/metrics/datadog.go @@ -6,9 +6,9 @@ import ( "github.com/go-kit/kit/metrics/dogstatsd" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/types" ) var ( @@ -18,23 +18,21 @@ var ( // Metric names consistent with https://github.com/DataDog/integrations-extras/pull/64 const ( - ddConfigReloadsName = "config.reload.total" - ddConfigReloadsFailureTagName = "failure" - ddLastConfigReloadSuccessName = "config.reload.lastSuccessTimestamp" - ddLastConfigReloadFailureName = "config.reload.lastFailureTimestamp" + ddConfigReloadsName = "config.reload.total" + ddLastConfigReloadSuccessName = "config.reload.lastSuccessTimestamp" + ddOpenConnsName = "open.connections" + ddTLSCertsNotAfterTimestampName = "tls.certs.notAfterTimestamp" ddEntryPointReqsName = "entrypoint.request.total" ddEntryPointReqsTLSName = "entrypoint.request.tls.total" ddEntryPointReqDurationName = "entrypoint.request.duration" - ddEntryPointOpenConnsName = "entrypoint.connections.open" ddEntryPointReqsBytesName = "entrypoint.requests.bytes.total" ddEntryPointRespsBytesName = "entrypoint.responses.bytes.total" ddRouterReqsName = "router.request.total" ddRouterReqsTLSName = "router.request.tls.total" ddRouterReqsDurationName = "router.request.duration" - ddRouterOpenConnsName = "router.connections.open" ddRouterReqsBytesName = "router.requests.bytes.total" ddRouterRespsBytesName = "router.responses.bytes.total" @@ -42,7 +40,6 @@ const ( ddServiceReqsTLSName = "service.request.tls.total" ddServiceReqsDurationName = "service.request.duration" ddServiceRetriesName = "service.retries.total" - ddServiceOpenConnsName = "service.connections.open" ddServiceServerUpName = "service.server.up" ddServiceReqsBytesName = "service.requests.bytes.total" ddServiceRespsBytesName = "service.responses.bytes.total" @@ -64,39 +61,35 @@ func RegisterDatadog(ctx context.Context, config *types.Datadog) Registry { registry := &standardRegistry{ configReloadsCounter: datadogClient.NewCounter(ddConfigReloadsName, 1.0), - configReloadsFailureCounter: datadogClient.NewCounter(ddConfigReloadsName, 1.0).With(ddConfigReloadsFailureTagName, "true"), lastConfigReloadSuccessGauge: datadogClient.NewGauge(ddLastConfigReloadSuccessName), - lastConfigReloadFailureGauge: datadogClient.NewGauge(ddLastConfigReloadFailureName), + openConnectionsGauge: datadogClient.NewGauge(ddOpenConnsName), tlsCertsNotAfterTimestampGauge: datadogClient.NewGauge(ddTLSCertsNotAfterTimestampName), } if config.AddEntryPointsLabels { registry.epEnabled = config.AddEntryPointsLabels - registry.entryPointReqsCounter = datadogClient.NewCounter(ddEntryPointReqsName, 1.0) + registry.entryPointReqsCounter = NewCounterWithNoopHeaders(datadogClient.NewCounter(ddEntryPointReqsName, 1.0)) registry.entryPointReqsTLSCounter = datadogClient.NewCounter(ddEntryPointReqsTLSName, 1.0) registry.entryPointReqDurationHistogram, _ = NewHistogramWithScale(datadogClient.NewHistogram(ddEntryPointReqDurationName, 1.0), time.Second) - registry.entryPointOpenConnsGauge = datadogClient.NewGauge(ddEntryPointOpenConnsName) registry.entryPointReqsBytesCounter = datadogClient.NewCounter(ddEntryPointReqsBytesName, 1.0) registry.entryPointRespsBytesCounter = datadogClient.NewCounter(ddEntryPointRespsBytesName, 1.0) } if config.AddRoutersLabels { registry.routerEnabled = config.AddRoutersLabels - registry.routerReqsCounter = datadogClient.NewCounter(ddRouterReqsName, 1.0) + registry.routerReqsCounter = NewCounterWithNoopHeaders(datadogClient.NewCounter(ddRouterReqsName, 1.0)) registry.routerReqsTLSCounter = datadogClient.NewCounter(ddRouterReqsTLSName, 1.0) registry.routerReqDurationHistogram, _ = NewHistogramWithScale(datadogClient.NewHistogram(ddRouterReqsDurationName, 1.0), time.Second) - registry.routerOpenConnsGauge = datadogClient.NewGauge(ddRouterOpenConnsName) registry.routerReqsBytesCounter = datadogClient.NewCounter(ddRouterReqsBytesName, 1.0) registry.routerRespsBytesCounter = datadogClient.NewCounter(ddRouterRespsBytesName, 1.0) } if config.AddServicesLabels { registry.svcEnabled = config.AddServicesLabels - registry.serviceReqsCounter = datadogClient.NewCounter(ddServiceReqsName, 1.0) + registry.serviceReqsCounter = NewCounterWithNoopHeaders(datadogClient.NewCounter(ddServiceReqsName, 1.0)) registry.serviceReqsTLSCounter = datadogClient.NewCounter(ddServiceReqsTLSName, 1.0) registry.serviceReqDurationHistogram, _ = NewHistogramWithScale(datadogClient.NewHistogram(ddServiceReqsDurationName, 1.0), time.Second) registry.serviceRetriesCounter = datadogClient.NewCounter(ddServiceRetriesName, 1.0) - registry.serviceOpenConnsGauge = datadogClient.NewGauge(ddServiceOpenConnsName) registry.serviceServerUpGauge = datadogClient.NewGauge(ddServiceServerUpName) registry.serviceReqsBytesCounter = datadogClient.NewCounter(ddServiceReqsBytesName, 1.0) registry.serviceRespsBytesCounter = datadogClient.NewCounter(ddServiceRespsBytesName, 1.0) diff --git a/pkg/metrics/datadog_test.go b/pkg/metrics/datadog_test.go index 7a36c1d77ac86b5f98c5e3ee11c91a423382d8df..68e79ba71405d159667e1a6927b981f954410ea8 100644 --- a/pkg/metrics/datadog_test.go +++ b/pkg/metrics/datadog_test.go @@ -9,7 +9,7 @@ import ( "github.com/stvp/go-udp-testing" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/types" ) func TestDatadog(t *testing.T) { @@ -45,16 +45,14 @@ func testDatadogRegistry(t *testing.T, metricsPrefix string, datadogRegistry Reg expected := []string{ metricsPrefix + ".config.reload.total:1.000000|c\n", - metricsPrefix + ".config.reload.total:1.000000|c|#failure:true\n", metricsPrefix + ".config.reload.lastSuccessTimestamp:1.000000|g\n", - metricsPrefix + ".config.reload.lastFailureTimestamp:1.000000|g\n", + metricsPrefix + ".open.connections:1.000000|g|#entrypoint:test,protocol:TCP\n", metricsPrefix + ".tls.certs.notAfterTimestamp:1.000000|g|#key:value\n", metricsPrefix + ".entrypoint.request.total:1.000000|c|#entrypoint:test\n", metricsPrefix + ".entrypoint.request.tls.total:1.000000|c|#entrypoint:test,tls_version:foo,tls_cipher:bar\n", metricsPrefix + ".entrypoint.request.duration:10000.000000|h|#entrypoint:test\n", - metricsPrefix + ".entrypoint.connections.open:1.000000|g|#entrypoint:test\n", metricsPrefix + ".entrypoint.requests.bytes.total:1.000000|c|#entrypoint:test\n", metricsPrefix + ".entrypoint.responses.bytes.total:1.000000|c|#entrypoint:test\n", @@ -62,7 +60,6 @@ func testDatadogRegistry(t *testing.T, metricsPrefix string, datadogRegistry Reg metricsPrefix + ".router.request.total:1.000000|c|#router:demo,service:test,code:200,method:GET\n", metricsPrefix + ".router.request.tls.total:1.000000|c|#router:demo,service:test,tls_version:foo,tls_cipher:bar\n", metricsPrefix + ".router.request.duration:10000.000000|h|#router:demo,service:test,code:200\n", - metricsPrefix + ".router.connections.open:1.000000|g|#router:demo,service:test\n", metricsPrefix + ".router.requests.bytes.total:1.000000|c|#router:demo,service:test,code:200,method:GET\n", metricsPrefix + ".router.responses.bytes.total:1.000000|c|#router:demo,service:test,code:200,method:GET\n", @@ -70,7 +67,6 @@ func testDatadogRegistry(t *testing.T, metricsPrefix string, datadogRegistry Reg metricsPrefix + ".service.request.total:1.000000|c|#service:test,code:200,method:GET\n", metricsPrefix + ".service.request.tls.total:1.000000|c|#service:test,tls_version:foo,tls_cipher:bar\n", metricsPrefix + ".service.request.duration:10000.000000|h|#service:test,code:200\n", - metricsPrefix + ".service.connections.open:1.000000|g|#service:test\n", metricsPrefix + ".service.retries.total:2.000000|c|#service:test\n", metricsPrefix + ".service.request.duration:10000.000000|h|#service:test,code:200\n", metricsPrefix + ".service.server.up:1.000000|g|#service:test,url:http://127.0.0.1,one:two\n", @@ -80,32 +76,28 @@ func testDatadogRegistry(t *testing.T, metricsPrefix string, datadogRegistry Reg udp.ShouldReceiveAll(t, expected, func() { datadogRegistry.ConfigReloadsCounter().Add(1) - datadogRegistry.ConfigReloadsFailureCounter().Add(1) datadogRegistry.LastConfigReloadSuccessGauge().Add(1) - datadogRegistry.LastConfigReloadFailureGauge().Add(1) + datadogRegistry.OpenConnectionsGauge().With("entrypoint", "test", "protocol", "TCP").Add(1) datadogRegistry.TLSCertsNotAfterTimestampGauge().With("key", "value").Set(1) - datadogRegistry.EntryPointReqsCounter().With("entrypoint", "test").Add(1) + datadogRegistry.EntryPointReqsCounter().With(nil, "entrypoint", "test").Add(1) datadogRegistry.EntryPointReqsTLSCounter().With("entrypoint", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) datadogRegistry.EntryPointReqDurationHistogram().With("entrypoint", "test").Observe(10000) - datadogRegistry.EntryPointOpenConnsGauge().With("entrypoint", "test").Set(1) datadogRegistry.EntryPointReqsBytesCounter().With("entrypoint", "test").Add(1) datadogRegistry.EntryPointRespsBytesCounter().With("entrypoint", "test").Add(1) - datadogRegistry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - datadogRegistry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) + datadogRegistry.RouterReqsCounter().With(nil, "router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + datadogRegistry.RouterReqsCounter().With(nil, "router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) datadogRegistry.RouterReqsTLSCounter().With("router", "demo", "service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) datadogRegistry.RouterReqDurationHistogram().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - datadogRegistry.RouterOpenConnsGauge().With("router", "demo", "service", "test").Set(1) datadogRegistry.RouterReqsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) datadogRegistry.RouterRespsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - datadogRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - datadogRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) + datadogRegistry.ServiceReqsCounter().With(nil, "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + datadogRegistry.ServiceReqsCounter().With(nil, "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) datadogRegistry.ServiceReqsTLSCounter().With("service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) datadogRegistry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - datadogRegistry.ServiceOpenConnsGauge().With("service", "test").Set(1) datadogRegistry.ServiceRetriesCounter().With("service", "test").Add(1) datadogRegistry.ServiceRetriesCounter().With("service", "test").Add(1) datadogRegistry.ServiceServerUpGauge().With("service", "test", "url", "http://127.0.0.1", "one", "two").Set(1) diff --git a/pkg/metrics/headers.go b/pkg/metrics/headers.go new file mode 100644 index 0000000000000000000000000000000000000000..65443cd29170606780bfded4705ddb5d4a90d70c --- /dev/null +++ b/pkg/metrics/headers.go @@ -0,0 +1,57 @@ +package metrics + +import ( + "net/http" + + "github.com/go-kit/kit/metrics" +) + +// CounterWithHeaders represents a counter that can use http.Header values as label values. +type CounterWithHeaders interface { + Add(delta float64) + With(headers http.Header, labelValues ...string) CounterWithHeaders +} + +// MultiCounterWithHeaders collects multiple individual CounterWithHeaders and treats them as a unit. +type MultiCounterWithHeaders []CounterWithHeaders + +// NewMultiCounterWithHeaders returns a multi-counter, wrapping the passed CounterWithHeaders. +func NewMultiCounterWithHeaders(c ...CounterWithHeaders) MultiCounterWithHeaders { + return c +} + +// Add adds the given delta value to the counter value. +func (c MultiCounterWithHeaders) Add(delta float64) { + for _, counter := range c { + counter.Add(delta) + } +} + +// With creates a new counter by appending the given label values and http.Header as labels and returns it. +func (c MultiCounterWithHeaders) With(headers http.Header, labelValues ...string) CounterWithHeaders { + next := make(MultiCounterWithHeaders, len(c)) + for i := range c { + next[i] = c[i].With(headers, labelValues...) + } + return next +} + +// NewCounterWithNoopHeaders returns a CounterWithNoopHeaders. +func NewCounterWithNoopHeaders(counter metrics.Counter) CounterWithNoopHeaders { + return CounterWithNoopHeaders{counter: counter} +} + +// CounterWithNoopHeaders is a counter that satisfies CounterWithHeaders but ignores the given http.Header. +type CounterWithNoopHeaders struct { + counter metrics.Counter +} + +// Add adds the given delta value to the counter value. +func (c CounterWithNoopHeaders) Add(delta float64) { + c.counter.Add(delta) +} + +// With creates a new counter by appending the given label values and returns it. +func (c CounterWithNoopHeaders) With(_ http.Header, labelValues ...string) CounterWithHeaders { + return NewCounterWithNoopHeaders(c.counter.With(labelValues...)) +} diff --git a/pkg/metrics/influxdb.go b/pkg/metrics/influxdb.go deleted file mode 100644 index d90ec75fc23febb16fa3cd159a59681b230961ba..0000000000000000000000000000000000000000 --- a/pkg/metrics/influxdb.go +++ /dev/null @@ -1,249 +0,0 @@ -package metrics - -import ( - "bytes" - "context" - "fmt" - "net/url" - "regexp" - "time" - - "github.com/go-kit/kit/metrics/influx" - influxdb "github.com/influxdata/influxdb1-client/v2" - "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" -) - -var ( - influxDBClient *influx.Influx - influxDBTicker *time.Ticker -) - -const ( - influxDBConfigReloadsName = "traefik.config.reload.total" - influxDBConfigReloadsFailureName = influxDBConfigReloadsName + ".failure" - influxDBLastConfigReloadSuccessName = "traefik.config.reload.lastSuccessTimestamp" - influxDBLastConfigReloadFailureName = "traefik.config.reload.lastFailureTimestamp" - - influxDBTLSCertsNotAfterTimestampName = "traefik.tls.certs.notAfterTimestamp" - - influxDBEntryPointReqsName = "traefik.entrypoint.requests.total" - influxDBEntryPointReqsTLSName = "traefik.entrypoint.requests.tls.total" - influxDBEntryPointReqDurationName = "traefik.entrypoint.request.duration" - influxDBEntryPointOpenConnsName = "traefik.entrypoint.connections.open" - influxDBEntryPointReqsBytesName = "traefik.entrypoint.requests.bytes.total" - influxDBEntryPointRespsBytesName = "traefik.entrypoint.responses.bytes.total" - - influxDBRouterReqsName = "traefik.router.requests.total" - influxDBRouterReqsTLSName = "traefik.router.requests.tls.total" - influxDBRouterReqsDurationName = "traefik.router.request.duration" - influxDBORouterOpenConnsName = "traefik.router.connections.open" - influxDBRouterReqsBytesName = "traefik.router.requests.bytes.total" - influxDBRouterRespsBytesName = "traefik.router.responses.bytes.total" - - influxDBServiceReqsName = "traefik.service.requests.total" - influxDBServiceReqsTLSName = "traefik.service.requests.tls.total" - influxDBServiceReqsDurationName = "traefik.service.request.duration" - influxDBServiceRetriesTotalName = "traefik.service.retries.total" - influxDBServiceOpenConnsName = "traefik.service.connections.open" - influxDBServiceServerUpName = "traefik.service.server.up" - influxDBServiceReqsBytesName = "traefik.service.requests.bytes.total" - influxDBServiceRespsBytesName = "traefik.service.responses.bytes.total" -) - -const ( - protocolHTTP = "http" - protocolUDP = "udp" -) - -// RegisterInfluxDB registers the metrics pusher if this didn't happen yet and creates a InfluxDB Registry instance. -func RegisterInfluxDB(ctx context.Context, config *types.InfluxDB) Registry { - if influxDBClient == nil { - influxDBClient = initInfluxDBClient(ctx, config) - } - if influxDBTicker == nil { - influxDBTicker = initInfluxDBTicker(ctx, config) - } - - registry := &standardRegistry{ - configReloadsCounter: influxDBClient.NewCounter(influxDBConfigReloadsName), - configReloadsFailureCounter: influxDBClient.NewCounter(influxDBConfigReloadsFailureName), - lastConfigReloadSuccessGauge: influxDBClient.NewGauge(influxDBLastConfigReloadSuccessName), - lastConfigReloadFailureGauge: influxDBClient.NewGauge(influxDBLastConfigReloadFailureName), - tlsCertsNotAfterTimestampGauge: influxDBClient.NewGauge(influxDBTLSCertsNotAfterTimestampName), - } - - if config.AddEntryPointsLabels { - registry.epEnabled = config.AddEntryPointsLabels - registry.entryPointReqsCounter = influxDBClient.NewCounter(influxDBEntryPointReqsName) - registry.entryPointReqsTLSCounter = influxDBClient.NewCounter(influxDBEntryPointReqsTLSName) - registry.entryPointReqDurationHistogram, _ = NewHistogramWithScale(influxDBClient.NewHistogram(influxDBEntryPointReqDurationName), time.Second) - registry.entryPointOpenConnsGauge = influxDBClient.NewGauge(influxDBEntryPointOpenConnsName) - registry.entryPointReqsBytesCounter = influxDBClient.NewCounter(influxDBEntryPointReqsBytesName) - registry.entryPointRespsBytesCounter = influxDBClient.NewCounter(influxDBEntryPointRespsBytesName) - } - - if config.AddRoutersLabels { - registry.routerEnabled = config.AddRoutersLabels - registry.routerReqsCounter = influxDBClient.NewCounter(influxDBRouterReqsName) - registry.routerReqsTLSCounter = influxDBClient.NewCounter(influxDBRouterReqsTLSName) - registry.routerReqDurationHistogram, _ = NewHistogramWithScale(influxDBClient.NewHistogram(influxDBRouterReqsDurationName), time.Second) - registry.routerOpenConnsGauge = influxDBClient.NewGauge(influxDBORouterOpenConnsName) - registry.routerReqsBytesCounter = influxDBClient.NewCounter(influxDBRouterReqsBytesName) - registry.routerRespsBytesCounter = influxDBClient.NewCounter(influxDBRouterRespsBytesName) - } - - if config.AddServicesLabels { - registry.svcEnabled = config.AddServicesLabels - registry.serviceReqsCounter = influxDBClient.NewCounter(influxDBServiceReqsName) - registry.serviceReqsTLSCounter = influxDBClient.NewCounter(influxDBServiceReqsTLSName) - registry.serviceReqDurationHistogram, _ = NewHistogramWithScale(influxDBClient.NewHistogram(influxDBServiceReqsDurationName), time.Second) - registry.serviceRetriesCounter = influxDBClient.NewCounter(influxDBServiceRetriesTotalName) - registry.serviceOpenConnsGauge = influxDBClient.NewGauge(influxDBServiceOpenConnsName) - registry.serviceServerUpGauge = influxDBClient.NewGauge(influxDBServiceServerUpName) - registry.serviceReqsBytesCounter = influxDBClient.NewCounter(influxDBServiceReqsBytesName) - registry.serviceRespsBytesCounter = influxDBClient.NewCounter(influxDBServiceRespsBytesName) - } - - return registry -} - -// initInfluxDBClient creates a influxDBClient. -func initInfluxDBClient(ctx context.Context, config *types.InfluxDB) *influx.Influx { - logger := log.Ctx(ctx) - - // TODO deprecated: move this switch into configuration.SetEffectiveConfiguration when web provider will be removed. - switch config.Protocol { - case protocolUDP: - if len(config.Database) > 0 || len(config.RetentionPolicy) > 0 { - logger.Warn().Msg("Database and RetentionPolicy options have no effect with UDP.") - config.Database = "" - config.RetentionPolicy = "" - } - case protocolHTTP: - if u, err := url.Parse(config.Address); err == nil { - if u.Scheme != "http" && u.Scheme != "https" { - logger.Warn().Msgf("InfluxDB address %s should specify a scheme (http or https): falling back on HTTP.", config.Address) - config.Address = "http://" + config.Address - } - } else { - logger.Error().Err(err).Msg("Unable to parse the InfluxDB address: falling back on UDP.") - config.Protocol = protocolUDP - config.Database = "" - config.RetentionPolicy = "" - } - default: - logger.Warn().Msgf("Unsupported protocol %s: falling back on UDP.", config.Protocol) - config.Protocol = protocolUDP - config.Database = "" - config.RetentionPolicy = "" - } - - return influx.New( - config.AdditionalLabels, - influxdb.BatchPointsConfig{ - Database: config.Database, - RetentionPolicy: config.RetentionPolicy, - }, - logs.NewGoKitWrapper(*logger), - ) -} - -// initInfluxDBTicker initializes metrics pusher. -func initInfluxDBTicker(ctx context.Context, config *types.InfluxDB) *time.Ticker { - report := time.NewTicker(time.Duration(config.PushInterval)) - - safe.Go(func() { - var buf bytes.Buffer - influxDBClient.WriteLoop(ctx, report.C, &influxDBWriter{buf: buf, config: config}) - }) - - return report -} - -// StopInfluxDB stops internal influxDBTicker which controls the pushing of metrics to InfluxDB Agent and resets it to `nil`. -func StopInfluxDB() { - if influxDBTicker != nil { - influxDBTicker.Stop() - } - influxDBTicker = nil -} - -type influxDBWriter struct { - buf bytes.Buffer - config *types.InfluxDB -} - -// Write creates a http or udp client and attempts to write BatchPoints. -// If a "database not found" error is encountered, a CREATE DATABASE -// query is attempted when using protocol http. -func (w *influxDBWriter) Write(bp influxdb.BatchPoints) error { - c, err := w.initWriteClient() - if err != nil { - return err - } - - defer c.Close() - - if writeErr := c.Write(bp); writeErr != nil { - logger := log.With().Str(logs.MetricsProviderName, "influxdb").Logger() - logger.Error().Err(writeErr).Msg("Error while writing to InfluxDB") - - if handleErr := w.handleWriteError(logger.WithContext(context.Background()), c, writeErr); handleErr != nil { - return handleErr - } - // Retry write after successful handling of writeErr - return c.Write(bp) - } - return nil -} - -func (w *influxDBWriter) initWriteClient() (influxdb.Client, error) { - if w.config.Protocol == "http" { - return influxdb.NewHTTPClient(influxdb.HTTPConfig{ - Addr: w.config.Address, - Username: w.config.Username, - Password: w.config.Password, - }) - } - - return influxdb.NewUDPClient(influxdb.UDPConfig{ - Addr: w.config.Address, - }) -} - -func (w *influxDBWriter) handleWriteError(ctx context.Context, c influxdb.Client, writeErr error) error { - if w.config.Protocol != protocolHTTP { - return writeErr - } - - match, matchErr := regexp.MatchString("database not found", writeErr.Error()) - - if matchErr != nil || !match { - return writeErr - } - - qStr := fmt.Sprintf("CREATE DATABASE \"%s\"", w.config.Database) - if w.config.RetentionPolicy != "" { - qStr = fmt.Sprintf("%s WITH NAME \"%s\"", qStr, w.config.RetentionPolicy) - } - - logger := log.Ctx(ctx) - - logger.Debug().Msgf("InfluxDB database not found: attempting to create one with %s", qStr) - - q := influxdb.NewQuery(qStr, "", "") - response, queryErr := c.Query(q) - if queryErr == nil && response.Error() != nil { - queryErr = response.Error() - } - if queryErr != nil { - logger.Error().Err(queryErr).Msg("Error while creating the InfluxDB database") - return queryErr - } - - logger.Debug().Msgf("Successfully created the InfluxDB database %s", w.config.Database) - return nil -} diff --git a/pkg/metrics/influxdb2.go b/pkg/metrics/influxdb2.go index 6cf02e8f76ac3610a4004d810eb59a90a041cd7b..270ac03a906e511cd4584d064b6726c8e3449ce6 100644 --- a/pkg/metrics/influxdb2.go +++ b/pkg/metrics/influxdb2.go @@ -12,9 +12,9 @@ import ( influxdb2log "github.com/influxdata/influxdb-client-go/v2/log" influxdb "github.com/influxdata/influxdb1-client/v2" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/types" ) var ( @@ -23,6 +23,34 @@ var ( influxDB2Client influxdb2.Client ) +const ( + influxDBConfigReloadsName = "traefik.config.reload.total" + influxDBLastConfigReloadSuccessName = "traefik.config.reload.lastSuccessTimestamp" + influxDBOpenConnsName = "traefik.open.connections" + + influxDBTLSCertsNotAfterTimestampName = "traefik.tls.certs.notAfterTimestamp" + + influxDBEntryPointReqsName = "traefik.entrypoint.requests.total" + influxDBEntryPointReqsTLSName = "traefik.entrypoint.requests.tls.total" + influxDBEntryPointReqDurationName = "traefik.entrypoint.request.duration" + influxDBEntryPointReqsBytesName = "traefik.entrypoint.requests.bytes.total" + influxDBEntryPointRespsBytesName = "traefik.entrypoint.responses.bytes.total" + + influxDBRouterReqsName = "traefik.router.requests.total" + influxDBRouterReqsTLSName = "traefik.router.requests.tls.total" + influxDBRouterReqsDurationName = "traefik.router.request.duration" + influxDBRouterReqsBytesName = "traefik.router.requests.bytes.total" + influxDBRouterRespsBytesName = "traefik.router.responses.bytes.total" + + influxDBServiceReqsName = "traefik.service.requests.total" + influxDBServiceReqsTLSName = "traefik.service.requests.tls.total" + influxDBServiceReqsDurationName = "traefik.service.request.duration" + influxDBServiceRetriesTotalName = "traefik.service.retries.total" + influxDBServiceServerUpName = "traefik.service.server.up" + influxDBServiceReqsBytesName = "traefik.service.requests.bytes.total" + influxDBServiceRespsBytesName = "traefik.service.responses.bytes.total" +) + // RegisterInfluxDB2 creates metrics exporter for InfluxDB2. func RegisterInfluxDB2(ctx context.Context, config *types.InfluxDB2) Registry { logger := log.Ctx(ctx) @@ -52,39 +80,35 @@ func RegisterInfluxDB2(ctx context.Context, config *types.InfluxDB2) Registry { registry := &standardRegistry{ configReloadsCounter: influxDB2Store.NewCounter(influxDBConfigReloadsName), - configReloadsFailureCounter: influxDB2Store.NewCounter(influxDBConfigReloadsFailureName), lastConfigReloadSuccessGauge: influxDB2Store.NewGauge(influxDBLastConfigReloadSuccessName), - lastConfigReloadFailureGauge: influxDB2Store.NewGauge(influxDBLastConfigReloadFailureName), + openConnectionsGauge: influxDB2Store.NewGauge(influxDBOpenConnsName), tlsCertsNotAfterTimestampGauge: influxDB2Store.NewGauge(influxDBTLSCertsNotAfterTimestampName), } if config.AddEntryPointsLabels { registry.epEnabled = config.AddEntryPointsLabels - registry.entryPointReqsCounter = influxDB2Store.NewCounter(influxDBEntryPointReqsName) + registry.entryPointReqsCounter = NewCounterWithNoopHeaders(influxDB2Store.NewCounter(influxDBEntryPointReqsName)) registry.entryPointReqsTLSCounter = influxDB2Store.NewCounter(influxDBEntryPointReqsTLSName) registry.entryPointReqDurationHistogram, _ = NewHistogramWithScale(influxDB2Store.NewHistogram(influxDBEntryPointReqDurationName), time.Second) - registry.entryPointOpenConnsGauge = influxDB2Store.NewGauge(influxDBEntryPointOpenConnsName) registry.entryPointReqsBytesCounter = influxDB2Store.NewCounter(influxDBEntryPointReqsBytesName) registry.entryPointRespsBytesCounter = influxDB2Store.NewCounter(influxDBEntryPointRespsBytesName) } if config.AddRoutersLabels { registry.routerEnabled = config.AddRoutersLabels - registry.routerReqsCounter = influxDB2Store.NewCounter(influxDBRouterReqsName) + registry.routerReqsCounter = NewCounterWithNoopHeaders(influxDB2Store.NewCounter(influxDBRouterReqsName)) registry.routerReqsTLSCounter = influxDB2Store.NewCounter(influxDBRouterReqsTLSName) registry.routerReqDurationHistogram, _ = NewHistogramWithScale(influxDB2Store.NewHistogram(influxDBRouterReqsDurationName), time.Second) - registry.routerOpenConnsGauge = influxDB2Store.NewGauge(influxDBORouterOpenConnsName) registry.routerReqsBytesCounter = influxDB2Store.NewCounter(influxDBRouterReqsBytesName) registry.routerRespsBytesCounter = influxDB2Store.NewCounter(influxDBRouterRespsBytesName) } if config.AddServicesLabels { registry.svcEnabled = config.AddServicesLabels - registry.serviceReqsCounter = influxDB2Store.NewCounter(influxDBServiceReqsName) + registry.serviceReqsCounter = NewCounterWithNoopHeaders(influxDB2Store.NewCounter(influxDBServiceReqsName)) registry.serviceReqsTLSCounter = influxDB2Store.NewCounter(influxDBServiceReqsTLSName) registry.serviceReqDurationHistogram, _ = NewHistogramWithScale(influxDB2Store.NewHistogram(influxDBServiceReqsDurationName), time.Second) registry.serviceRetriesCounter = influxDB2Store.NewCounter(influxDBServiceRetriesTotalName) - registry.serviceOpenConnsGauge = influxDB2Store.NewGauge(influxDBServiceOpenConnsName) registry.serviceServerUpGauge = influxDB2Store.NewGauge(influxDBServiceServerUpName) registry.serviceReqsBytesCounter = influxDB2Store.NewCounter(influxDBServiceReqsBytesName) registry.serviceRespsBytesCounter = influxDB2Store.NewCounter(influxDBServiceRespsBytesName) diff --git a/pkg/metrics/influxdb2_test.go b/pkg/metrics/influxdb2_test.go index 3fc628d671c9f7bc0132e7c8bf8874640281cd0a..89b5580753cd30744aefd50b34d180efd658e878 100644 --- a/pkg/metrics/influxdb2_test.go +++ b/pkg/metrics/influxdb2_test.go @@ -6,13 +6,14 @@ import ( "io" "net/http" "net/http/httptest" + "regexp" "strconv" "testing" "time" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/types" ) func TestInfluxDB2(t *testing.T) { @@ -46,15 +47,13 @@ func TestInfluxDB2(t *testing.T) { expectedServer := []string{ `(traefik\.config\.reload\.total count=1) [\d]{19}`, - `(traefik\.config\.reload\.total\.failure count=1) [\d]{19}`, `(traefik\.config\.reload\.lastSuccessTimestamp value=1) [\d]{19}`, - `(traefik\.config\.reload\.lastFailureTimestamp value=1) [\d]{19}`, + `(traefik\.open\.connections,entrypoint=test,protocol=TCP value=1) [\d]{19}`, } influxDB2Registry.ConfigReloadsCounter().Add(1) - influxDB2Registry.ConfigReloadsFailureCounter().Add(1) influxDB2Registry.LastConfigReloadSuccessGauge().Set(1) - influxDB2Registry.LastConfigReloadFailureGauge().Set(1) + influxDB2Registry.OpenConnectionsGauge().With("entrypoint", "test", "protocol", "TCP").Set(1) msgServer := <-c assertMessage(t, *msgServer, expectedServer) @@ -72,15 +71,13 @@ func TestInfluxDB2(t *testing.T) { `(traefik\.entrypoint\.requests\.total,code=200,entrypoint=test,method=GET count=1) [\d]{19}`, `(traefik\.entrypoint\.requests\.tls\.total,entrypoint=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, `(traefik\.entrypoint\.request\.duration(?:,code=[\d]{3})?,entrypoint=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.entrypoint\.connections\.open,entrypoint=test value=1) [\d]{19}`, `(traefik\.entrypoint\.requests\.bytes\.total,code=200,entrypoint=test,method=GET count=1) [\d]{19}`, `(traefik\.entrypoint\.responses\.bytes\.total,code=200,entrypoint=test,method=GET count=1) [\d]{19}`, } - influxDB2Registry.EntryPointReqsCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + influxDB2Registry.EntryPointReqsCounter().With(nil, "entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) influxDB2Registry.EntryPointReqsTLSCounter().With("entrypoint", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) influxDB2Registry.EntryPointReqDurationHistogram().With("entrypoint", "test").Observe(10000) - influxDB2Registry.EntryPointOpenConnsGauge().With("entrypoint", "test").Set(1) influxDB2Registry.EntryPointReqsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) influxDB2Registry.EntryPointRespsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) msgEntrypoint := <-c @@ -92,16 +89,14 @@ func TestInfluxDB2(t *testing.T) { `(traefik\.router\.requests\.total,code=404,method=GET,router=demo,service=test count=1) [\d]{19}`, `(traefik\.router\.requests\.tls\.total,router=demo,service=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, `(traefik\.router\.request\.duration,code=200,router=demo,service=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.router\.connections\.open,router=demo,service=test value=1) [\d]{19}`, `(traefik\.router\.requests\.bytes\.total,code=200,method=GET,router=demo,service=test count=1) [\d]{19}`, `(traefik\.router\.responses\.bytes\.total,code=200,method=GET,router=demo,service=test count=1) [\d]{19}`, } - influxDB2Registry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - influxDB2Registry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + influxDB2Registry.RouterReqsCounter().With(nil, "router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) + influxDB2Registry.RouterReqsCounter().With(nil, "router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) influxDB2Registry.RouterReqsTLSCounter().With("router", "demo", "service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) influxDB2Registry.RouterReqDurationHistogram().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - influxDB2Registry.RouterOpenConnsGauge().With("router", "demo", "service", "test").Set(1) influxDB2Registry.RouterReqsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) influxDB2Registry.RouterRespsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) msgRouter := <-c @@ -118,8 +113,8 @@ func TestInfluxDB2(t *testing.T) { `(traefik\.service\.responses\.bytes\.total,code=200,method=GET,service=test count=1) [\d]{19}`, } - influxDB2Registry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDB2Registry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) + influxDB2Registry.ServiceReqsCounter().With(nil, "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + influxDB2Registry.ServiceReqsCounter().With(nil, "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) influxDB2Registry.ServiceReqsTLSCounter().With("service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) influxDB2Registry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) influxDB2Registry.ServiceServerUpGauge().With("service", "test", "url", "http://127.0.0.1").Set(1) @@ -141,17 +136,15 @@ func TestInfluxDB2(t *testing.T) { msgServiceRetries := <-c assertMessage(t, *msgServiceRetries, expectedServiceRetries) +} - expectedServiceOpenConns := []string{ - `(traefik\.service\.connections\.open,service=test value=2) [\d]{19}`, - `(traefik\.service\.connections\.open,service=foobar value=1) [\d]{19}`, +func assertMessage(t *testing.T, msg string, patterns []string) { + t.Helper() + for _, pattern := range patterns { + re := regexp.MustCompile(pattern) + match := re.FindStringSubmatch(msg) + if len(match) != 2 { + t.Errorf("Got %q %v, want %q", msg, match, pattern) + } } - - influxDB2Registry.ServiceOpenConnsGauge().With("service", "test").Add(1) - influxDB2Registry.ServiceOpenConnsGauge().With("service", "test").Add(1) - influxDB2Registry.ServiceOpenConnsGauge().With("service", "foobar").Add(1) - - msgServiceOpenConns := <-c - - assertMessage(t, *msgServiceOpenConns, expectedServiceOpenConns) } diff --git a/pkg/metrics/influxdb_test.go b/pkg/metrics/influxdb_test.go deleted file mode 100644 index 38a146697e7ab09aad4556848e04060d5796b1f0..0000000000000000000000000000000000000000 --- a/pkg/metrics/influxdb_test.go +++ /dev/null @@ -1,267 +0,0 @@ -package metrics - -import ( - "context" - "fmt" - "io" - "net/http" - "net/http/httptest" - "regexp" - "strconv" - "testing" - "time" - - "github.com/stretchr/testify/require" - "github.com/stvp/go-udp-testing" - ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/types" -) - -func TestInfluxDB(t *testing.T) { - udp.SetAddr(":8089") - // This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond - udp.Timeout = 5 * time.Second - - influxDBClient = nil - influxDBRegistry := RegisterInfluxDB(context.Background(), - &types.InfluxDB{ - Address: ":8089", - PushInterval: ptypes.Duration(time.Second), - AddEntryPointsLabels: true, - AddRoutersLabels: true, - AddServicesLabels: true, - AdditionalLabels: map[string]string{"tag1": "val1"}, - }) - defer StopInfluxDB() - - if !influxDBRegistry.IsEpEnabled() || !influxDBRegistry.IsRouterEnabled() || !influxDBRegistry.IsSvcEnabled() { - t.Fatalf("InfluxDBRegistry should return true for IsEnabled(), IsRouterEnabled() and IsSvcEnabled()") - } - - expectedServer := []string{ - `(traefik\.config\.reload\.total,tag1=val1 count=1) [\d]{19}`, - `(traefik\.config\.reload\.total\.failure,tag1=val1 count=1) [\d]{19}`, - `(traefik\.config\.reload\.lastSuccessTimestamp,tag1=val1 value=1) [\d]{19}`, - `(traefik\.config\.reload\.lastFailureTimestamp,tag1=val1 value=1) [\d]{19}`, - } - - msgServer := udp.ReceiveString(t, func() { - influxDBRegistry.ConfigReloadsCounter().Add(1) - influxDBRegistry.ConfigReloadsFailureCounter().Add(1) - influxDBRegistry.LastConfigReloadSuccessGauge().Set(1) - influxDBRegistry.LastConfigReloadFailureGauge().Set(1) - }) - - assertMessage(t, msgServer, expectedServer) - - expectedTLS := []string{ - `(traefik\.tls\.certs\.notAfterTimestamp,key=value,tag1=val1 value=1) [\d]{19}`, - } - - msgTLS := udp.ReceiveString(t, func() { - influxDBRegistry.TLSCertsNotAfterTimestampGauge().With("key", "value").Set(1) - }) - - assertMessage(t, msgTLS, expectedTLS) - - expectedEntrypoint := []string{ - `(traefik\.entrypoint\.requests\.total,code=200,entrypoint=test,method=GET,tag1=val1 count=1) [\d]{19}`, - `(traefik\.entrypoint\.requests\.tls\.total,entrypoint=test,tag1=val1,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.entrypoint\.request\.duration(?:,code=[\d]{3})?,entrypoint=test,tag1=val1 p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.entrypoint\.connections\.open,entrypoint=test,tag1=val1 value=1) [\d]{19}`, - `(traefik\.entrypoint\.requests\.bytes\.total,code=200,entrypoint=test,method=GET,tag1=val1 count=1) [\d]{19}`, - `(traefik\.entrypoint\.responses\.bytes\.total,code=200,entrypoint=test,method=GET,tag1=val1 count=1) [\d]{19}`, - } - - msgEntrypoint := udp.ReceiveString(t, func() { - influxDBRegistry.EntryPointReqsCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.EntryPointReqsTLSCounter().With("entrypoint", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.EntryPointReqDurationHistogram().With("entrypoint", "test").Observe(10000) - influxDBRegistry.EntryPointOpenConnsGauge().With("entrypoint", "test").Set(1) - influxDBRegistry.EntryPointReqsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.EntryPointRespsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - }) - - assertMessage(t, msgEntrypoint, expectedEntrypoint) - - expectedRouter := []string{ - `(traefik\.router\.requests\.total,code=200,method=GET,router=demo,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.router\.requests\.total,code=404,method=GET,router=demo,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.router\.requests\.tls\.total,router=demo,service=test,tag1=val1,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.router\.request\.duration,code=200,router=demo,service=test,tag1=val1 p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.router\.connections\.open,router=demo,service=test,tag1=val1 value=1) [\d]{19}`, - `(traefik\.router\.requests\.bytes\.total,code=200,method=GET,router=demo,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.router\.responses\.bytes\.total,code=200,method=GET,router=demo,service=test,tag1=val1 count=1) [\d]{19}`, - } - - msgRouter := udp.ReceiveString(t, func() { - influxDBRegistry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterReqsTLSCounter().With("router", "demo", "service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.RouterReqDurationHistogram().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - influxDBRegistry.RouterOpenConnsGauge().With("router", "demo", "service", "test").Set(1) - influxDBRegistry.RouterReqsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterRespsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - }) - - assertMessage(t, msgRouter, expectedRouter) - - expectedService := []string{ - `(traefik\.service\.requests\.total,code=200,method=GET,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.service\.requests\.total,code=404,method=GET,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.service\.requests\.tls\.total,service=test,tag1=val1,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.service\.request\.duration,code=200,service=test,tag1=val1 p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.service\.retries\.total(?:,code=[\d]{3},method=GET)?,service=test,tag1=val1 count=2) [\d]{19}`, - `(traefik\.service\.server\.up,service=test,tag1=val1,url=http://127.0.0.1 value=1) [\d]{19}`, - `(traefik\.service\.connections\.open,service=test,tag1=val1 value=1) [\d]{19}`, - `(traefik\.service\.requests\.bytes\.total,code=200,method=GET,service=test,tag1=val1 count=1) [\d]{19}`, - `(traefik\.service\.responses\.bytes\.total,code=200,method=GET,service=test,tag1=val1 count=1) [\d]{19}`, - } - - msgService := udp.ReceiveString(t, func() { - influxDBRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceReqsTLSCounter().With("service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - influxDBRegistry.ServiceOpenConnsGauge().With("service", "test").Set(1) - influxDBRegistry.ServiceRetriesCounter().With("service", "test").Add(1) - influxDBRegistry.ServiceRetriesCounter().With("service", "test").Add(1) - influxDBRegistry.ServiceServerUpGauge().With("service", "test", "url", "http://127.0.0.1").Set(1) - influxDBRegistry.ServiceReqsBytesCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceRespsBytesCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - }) - - assertMessage(t, msgService, expectedService) -} - -func TestInfluxDBHTTP(t *testing.T) { - c := make(chan *string) - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - body, err := io.ReadAll(r.Body) - require.NoError(t, err) - - bodyStr := string(body) - c <- &bodyStr - _, _ = fmt.Fprintln(w, "ok") - })) - defer ts.Close() - - influxDBClient = nil - influxDBRegistry := RegisterInfluxDB(context.Background(), - &types.InfluxDB{ - Address: ts.URL, - Protocol: "http", - PushInterval: ptypes.Duration(10 * time.Millisecond), - Database: "test", - RetentionPolicy: "autogen", - AddEntryPointsLabels: true, - AddServicesLabels: true, - AddRoutersLabels: true, - }) - defer StopInfluxDB() - - if !influxDBRegistry.IsEpEnabled() || !influxDBRegistry.IsRouterEnabled() || !influxDBRegistry.IsSvcEnabled() { - t.Fatalf("InfluxDB registry must be epEnabled") - } - - expectedServer := []string{ - `(traefik\.config\.reload\.total count=1) [\d]{19}`, - `(traefik\.config\.reload\.total\.failure count=1) [\d]{19}`, - `(traefik\.config\.reload\.lastSuccessTimestamp value=1) [\d]{19}`, - `(traefik\.config\.reload\.lastFailureTimestamp value=1) [\d]{19}`, - } - - influxDBRegistry.ConfigReloadsCounter().Add(1) - influxDBRegistry.ConfigReloadsFailureCounter().Add(1) - influxDBRegistry.LastConfigReloadSuccessGauge().Set(1) - influxDBRegistry.LastConfigReloadFailureGauge().Set(1) - msgServer := <-c - - assertMessage(t, *msgServer, expectedServer) - - expectedTLS := []string{ - `(traefik\.tls\.certs\.notAfterTimestamp,key=value value=1) [\d]{19}`, - } - - influxDBRegistry.TLSCertsNotAfterTimestampGauge().With("key", "value").Set(1) - msgTLS := <-c - - assertMessage(t, *msgTLS, expectedTLS) - - expectedEntrypoint := []string{ - `(traefik\.entrypoint\.requests\.total,code=200,entrypoint=test,method=GET count=1) [\d]{19}`, - `(traefik\.entrypoint\.requests\.tls\.total,entrypoint=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.entrypoint\.request\.duration(?:,code=[\d]{3})?,entrypoint=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.entrypoint\.connections\.open,entrypoint=test value=1) [\d]{19}`, - `(traefik\.entrypoint\.requests\.bytes\.total,code=200,entrypoint=test,method=GET count=1) [\d]{19}`, - `(traefik\.entrypoint\.responses\.bytes\.total,code=200,entrypoint=test,method=GET count=1) [\d]{19}`, - } - - influxDBRegistry.EntryPointReqsCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.EntryPointReqsTLSCounter().With("entrypoint", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.EntryPointReqDurationHistogram().With("entrypoint", "test").Observe(10000) - influxDBRegistry.EntryPointOpenConnsGauge().With("entrypoint", "test").Set(1) - influxDBRegistry.EntryPointReqsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.EntryPointRespsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - msgEntrypoint := <-c - - assertMessage(t, *msgEntrypoint, expectedEntrypoint) - - expectedRouter := []string{ - `(traefik\.router\.requests\.total,code=200,method=GET,router=demo,service=test count=1) [\d]{19}`, - `(traefik\.router\.requests\.total,code=404,method=GET,router=demo,service=test count=1) [\d]{19}`, - `(traefik\.router\.requests\.tls\.total,router=demo,service=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.router\.request\.duration,code=200,router=demo,service=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.router\.connections\.open,router=demo,service=test value=1) [\d]{19}`, - `(traefik\.router\.requests\.bytes\.total,code=200,method=GET,router=demo,service=test count=1) [\d]{19}`, - `(traefik\.router\.responses\.bytes\.total,code=200,method=GET,router=demo,service=test count=1) [\d]{19}`, - } - - influxDBRegistry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterReqsTLSCounter().With("router", "demo", "service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.RouterReqDurationHistogram().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - influxDBRegistry.RouterOpenConnsGauge().With("router", "demo", "service", "test").Set(1) - influxDBRegistry.RouterReqsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.RouterRespsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - msgRouter := <-c - - assertMessage(t, *msgRouter, expectedRouter) - - expectedService := []string{ - `(traefik\.service\.requests\.total,code=200,method=GET,service=test count=1) [\d]{19}`, - `(traefik\.service\.requests\.total,code=404,method=GET,service=test count=1) [\d]{19}`, - `(traefik\.service\.requests\.tls\.total,service=test,tls_cipher=bar,tls_version=foo count=1) [\d]{19}`, - `(traefik\.service\.request\.duration,code=200,service=test p50=10000,p90=10000,p95=10000,p99=10000) [\d]{19}`, - `(traefik\.service\.retries\.total(?:,code=[\d]{3},method=GET)?,service=test count=2) [\d]{19}`, - `(traefik\.service\.server\.up,service=test,url=http://127.0.0.1 value=1) [\d]{19}`, - `(traefik\.service\.connections\.open,service=test value=1) [\d]{19}`, - `(traefik\.service\.requests\.bytes\.total,code=200,method=GET,service=test count=1) [\d]{19}`, - `(traefik\.service\.responses\.bytes\.total,code=200,method=GET,service=test count=1) [\d]{19}`, - } - - influxDBRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceReqsTLSCounter().With("service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) - influxDBRegistry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - influxDBRegistry.ServiceOpenConnsGauge().With("service", "test").Set(1) - influxDBRegistry.ServiceRetriesCounter().With("service", "test").Add(1) - influxDBRegistry.ServiceRetriesCounter().With("service", "test").Add(1) - influxDBRegistry.ServiceServerUpGauge().With("service", "test", "url", "http://127.0.0.1").Set(1) - influxDBRegistry.ServiceReqsBytesCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - influxDBRegistry.ServiceRespsBytesCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - msgService := <-c - - assertMessage(t, *msgService, expectedService) -} - -func assertMessage(t *testing.T, msg string, patterns []string) { - t.Helper() - for _, pattern := range patterns { - re := regexp.MustCompile(pattern) - match := re.FindStringSubmatch(msg) - if len(match) != 2 { - t.Errorf("Got %q %v, want %q", msg, match, pattern) - } - } -} diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index ac49d389acc5be9b699a6a1558218b4f618e2dcc..e87af0277ea76f2395a3f4478bb4335c48b86a8e 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -22,9 +22,8 @@ type Registry interface { // server metrics ConfigReloadsCounter() metrics.Counter - ConfigReloadsFailureCounter() metrics.Counter LastConfigReloadSuccessGauge() metrics.Gauge - LastConfigReloadFailureGauge() metrics.Gauge + OpenConnectionsGauge() metrics.Gauge // TLS @@ -32,28 +31,25 @@ type Registry interface { // entry point metrics - EntryPointReqsCounter() metrics.Counter + EntryPointReqsCounter() CounterWithHeaders EntryPointReqsTLSCounter() metrics.Counter EntryPointReqDurationHistogram() ScalableHistogram - EntryPointOpenConnsGauge() metrics.Gauge EntryPointReqsBytesCounter() metrics.Counter EntryPointRespsBytesCounter() metrics.Counter // router metrics - RouterReqsCounter() metrics.Counter + RouterReqsCounter() CounterWithHeaders RouterReqsTLSCounter() metrics.Counter RouterReqDurationHistogram() ScalableHistogram - RouterOpenConnsGauge() metrics.Gauge RouterReqsBytesCounter() metrics.Counter RouterRespsBytesCounter() metrics.Counter // service metrics - ServiceReqsCounter() metrics.Counter + ServiceReqsCounter() CounterWithHeaders ServiceReqsTLSCounter() metrics.Counter ServiceReqDurationHistogram() ScalableHistogram - ServiceOpenConnsGauge() metrics.Gauge ServiceRetriesCounter() metrics.Counter ServiceServerUpGauge() metrics.Gauge ServiceReqsBytesCounter() metrics.Counter @@ -71,26 +67,22 @@ func NewVoidRegistry() Registry { // This allows for feature disparity between the different metric implementations. func NewMultiRegistry(registries []Registry) Registry { var configReloadsCounter []metrics.Counter - var configReloadsFailureCounter []metrics.Counter var lastConfigReloadSuccessGauge []metrics.Gauge - var lastConfigReloadFailureGauge []metrics.Gauge + var openConnectionsGauge []metrics.Gauge var tlsCertsNotAfterTimestampGauge []metrics.Gauge - var entryPointReqsCounter []metrics.Counter + var entryPointReqsCounter []CounterWithHeaders var entryPointReqsTLSCounter []metrics.Counter var entryPointReqDurationHistogram []ScalableHistogram - var entryPointOpenConnsGauge []metrics.Gauge var entryPointReqsBytesCounter []metrics.Counter var entryPointRespsBytesCounter []metrics.Counter - var routerReqsCounter []metrics.Counter + var routerReqsCounter []CounterWithHeaders var routerReqsTLSCounter []metrics.Counter var routerReqDurationHistogram []ScalableHistogram - var routerOpenConnsGauge []metrics.Gauge var routerReqsBytesCounter []metrics.Counter var routerRespsBytesCounter []metrics.Counter - var serviceReqsCounter []metrics.Counter + var serviceReqsCounter []CounterWithHeaders var serviceReqsTLSCounter []metrics.Counter var serviceReqDurationHistogram []ScalableHistogram - var serviceOpenConnsGauge []metrics.Gauge var serviceRetriesCounter []metrics.Counter var serviceServerUpGauge []metrics.Gauge var serviceReqsBytesCounter []metrics.Counter @@ -100,14 +92,11 @@ func NewMultiRegistry(registries []Registry) Registry { if r.ConfigReloadsCounter() != nil { configReloadsCounter = append(configReloadsCounter, r.ConfigReloadsCounter()) } - if r.ConfigReloadsFailureCounter() != nil { - configReloadsFailureCounter = append(configReloadsFailureCounter, r.ConfigReloadsFailureCounter()) - } if r.LastConfigReloadSuccessGauge() != nil { lastConfigReloadSuccessGauge = append(lastConfigReloadSuccessGauge, r.LastConfigReloadSuccessGauge()) } - if r.LastConfigReloadFailureGauge() != nil { - lastConfigReloadFailureGauge = append(lastConfigReloadFailureGauge, r.LastConfigReloadFailureGauge()) + if r.OpenConnectionsGauge() != nil { + openConnectionsGauge = append(openConnectionsGauge, r.OpenConnectionsGauge()) } if r.TLSCertsNotAfterTimestampGauge() != nil { tlsCertsNotAfterTimestampGauge = append(tlsCertsNotAfterTimestampGauge, r.TLSCertsNotAfterTimestampGauge()) @@ -121,9 +110,6 @@ func NewMultiRegistry(registries []Registry) Registry { if r.EntryPointReqDurationHistogram() != nil { entryPointReqDurationHistogram = append(entryPointReqDurationHistogram, r.EntryPointReqDurationHistogram()) } - if r.EntryPointOpenConnsGauge() != nil { - entryPointOpenConnsGauge = append(entryPointOpenConnsGauge, r.EntryPointOpenConnsGauge()) - } if r.EntryPointReqsBytesCounter() != nil { entryPointReqsBytesCounter = append(entryPointReqsBytesCounter, r.EntryPointReqsBytesCounter()) } @@ -139,9 +125,6 @@ func NewMultiRegistry(registries []Registry) Registry { if r.RouterReqDurationHistogram() != nil { routerReqDurationHistogram = append(routerReqDurationHistogram, r.RouterReqDurationHistogram()) } - if r.RouterOpenConnsGauge() != nil { - routerOpenConnsGauge = append(routerOpenConnsGauge, r.RouterOpenConnsGauge()) - } if r.RouterReqsBytesCounter() != nil { routerReqsBytesCounter = append(routerReqsBytesCounter, r.RouterReqsBytesCounter()) } @@ -157,9 +140,6 @@ func NewMultiRegistry(registries []Registry) Registry { if r.ServiceReqDurationHistogram() != nil { serviceReqDurationHistogram = append(serviceReqDurationHistogram, r.ServiceReqDurationHistogram()) } - if r.ServiceOpenConnsGauge() != nil { - serviceOpenConnsGauge = append(serviceOpenConnsGauge, r.ServiceOpenConnsGauge()) - } if r.ServiceRetriesCounter() != nil { serviceRetriesCounter = append(serviceRetriesCounter, r.ServiceRetriesCounter()) } @@ -175,30 +155,26 @@ func NewMultiRegistry(registries []Registry) Registry { } return &standardRegistry{ - epEnabled: len(entryPointReqsCounter) > 0 || len(entryPointReqDurationHistogram) > 0 || len(entryPointOpenConnsGauge) > 0, - svcEnabled: len(serviceReqsCounter) > 0 || len(serviceReqDurationHistogram) > 0 || len(serviceOpenConnsGauge) > 0 || len(serviceRetriesCounter) > 0 || len(serviceServerUpGauge) > 0, - routerEnabled: len(routerReqsCounter) > 0 || len(routerReqDurationHistogram) > 0 || len(routerOpenConnsGauge) > 0, + epEnabled: len(entryPointReqsCounter) > 0 || len(entryPointReqDurationHistogram) > 0, + svcEnabled: len(serviceReqsCounter) > 0 || len(serviceReqDurationHistogram) > 0 || len(serviceRetriesCounter) > 0 || len(serviceServerUpGauge) > 0, + routerEnabled: len(routerReqsCounter) > 0 || len(routerReqDurationHistogram) > 0, configReloadsCounter: multi.NewCounter(configReloadsCounter...), - configReloadsFailureCounter: multi.NewCounter(configReloadsFailureCounter...), lastConfigReloadSuccessGauge: multi.NewGauge(lastConfigReloadSuccessGauge...), - lastConfigReloadFailureGauge: multi.NewGauge(lastConfigReloadFailureGauge...), + openConnectionsGauge: multi.NewGauge(openConnectionsGauge...), tlsCertsNotAfterTimestampGauge: multi.NewGauge(tlsCertsNotAfterTimestampGauge...), - entryPointReqsCounter: multi.NewCounter(entryPointReqsCounter...), + entryPointReqsCounter: NewMultiCounterWithHeaders(entryPointReqsCounter...), entryPointReqsTLSCounter: multi.NewCounter(entryPointReqsTLSCounter...), entryPointReqDurationHistogram: MultiHistogram(entryPointReqDurationHistogram), - entryPointOpenConnsGauge: multi.NewGauge(entryPointOpenConnsGauge...), entryPointReqsBytesCounter: multi.NewCounter(entryPointReqsBytesCounter...), entryPointRespsBytesCounter: multi.NewCounter(entryPointRespsBytesCounter...), - routerReqsCounter: multi.NewCounter(routerReqsCounter...), + routerReqsCounter: NewMultiCounterWithHeaders(routerReqsCounter...), routerReqsTLSCounter: multi.NewCounter(routerReqsTLSCounter...), routerReqDurationHistogram: MultiHistogram(routerReqDurationHistogram), - routerOpenConnsGauge: multi.NewGauge(routerOpenConnsGauge...), routerReqsBytesCounter: multi.NewCounter(routerReqsBytesCounter...), routerRespsBytesCounter: multi.NewCounter(routerRespsBytesCounter...), - serviceReqsCounter: multi.NewCounter(serviceReqsCounter...), + serviceReqsCounter: NewMultiCounterWithHeaders(serviceReqsCounter...), serviceReqsTLSCounter: multi.NewCounter(serviceReqsTLSCounter...), serviceReqDurationHistogram: MultiHistogram(serviceReqDurationHistogram), - serviceOpenConnsGauge: multi.NewGauge(serviceOpenConnsGauge...), serviceRetriesCounter: multi.NewCounter(serviceRetriesCounter...), serviceServerUpGauge: multi.NewGauge(serviceServerUpGauge...), serviceReqsBytesCounter: multi.NewCounter(serviceReqsBytesCounter...), @@ -211,26 +187,22 @@ type standardRegistry struct { routerEnabled bool svcEnabled bool configReloadsCounter metrics.Counter - configReloadsFailureCounter metrics.Counter lastConfigReloadSuccessGauge metrics.Gauge - lastConfigReloadFailureGauge metrics.Gauge + openConnectionsGauge metrics.Gauge tlsCertsNotAfterTimestampGauge metrics.Gauge - entryPointReqsCounter metrics.Counter + entryPointReqsCounter CounterWithHeaders entryPointReqsTLSCounter metrics.Counter entryPointReqDurationHistogram ScalableHistogram - entryPointOpenConnsGauge metrics.Gauge entryPointReqsBytesCounter metrics.Counter entryPointRespsBytesCounter metrics.Counter - routerReqsCounter metrics.Counter + routerReqsCounter CounterWithHeaders routerReqsTLSCounter metrics.Counter routerReqDurationHistogram ScalableHistogram - routerOpenConnsGauge metrics.Gauge routerReqsBytesCounter metrics.Counter routerRespsBytesCounter metrics.Counter - serviceReqsCounter metrics.Counter + serviceReqsCounter CounterWithHeaders serviceReqsTLSCounter metrics.Counter serviceReqDurationHistogram ScalableHistogram - serviceOpenConnsGauge metrics.Gauge serviceRetriesCounter metrics.Counter serviceServerUpGauge metrics.Gauge serviceReqsBytesCounter metrics.Counter @@ -253,23 +225,19 @@ func (r *standardRegistry) ConfigReloadsCounter() metrics.Counter { return r.configReloadsCounter } -func (r *standardRegistry) ConfigReloadsFailureCounter() metrics.Counter { - return r.configReloadsFailureCounter -} - func (r *standardRegistry) LastConfigReloadSuccessGauge() metrics.Gauge { return r.lastConfigReloadSuccessGauge } -func (r *standardRegistry) LastConfigReloadFailureGauge() metrics.Gauge { - return r.lastConfigReloadFailureGauge +func (r *standardRegistry) OpenConnectionsGauge() metrics.Gauge { + return r.openConnectionsGauge } func (r *standardRegistry) TLSCertsNotAfterTimestampGauge() metrics.Gauge { return r.tlsCertsNotAfterTimestampGauge } -func (r *standardRegistry) EntryPointReqsCounter() metrics.Counter { +func (r *standardRegistry) EntryPointReqsCounter() CounterWithHeaders { return r.entryPointReqsCounter } @@ -281,10 +249,6 @@ func (r *standardRegistry) EntryPointReqDurationHistogram() ScalableHistogram { return r.entryPointReqDurationHistogram } -func (r *standardRegistry) EntryPointOpenConnsGauge() metrics.Gauge { - return r.entryPointOpenConnsGauge -} - func (r *standardRegistry) EntryPointReqsBytesCounter() metrics.Counter { return r.entryPointReqsBytesCounter } @@ -293,7 +257,7 @@ func (r *standardRegistry) EntryPointRespsBytesCounter() metrics.Counter { return r.entryPointRespsBytesCounter } -func (r *standardRegistry) RouterReqsCounter() metrics.Counter { +func (r *standardRegistry) RouterReqsCounter() CounterWithHeaders { return r.routerReqsCounter } @@ -305,10 +269,6 @@ func (r *standardRegistry) RouterReqDurationHistogram() ScalableHistogram { return r.routerReqDurationHistogram } -func (r *standardRegistry) RouterOpenConnsGauge() metrics.Gauge { - return r.routerOpenConnsGauge -} - func (r *standardRegistry) RouterReqsBytesCounter() metrics.Counter { return r.routerReqsBytesCounter } @@ -317,7 +277,7 @@ func (r *standardRegistry) RouterRespsBytesCounter() metrics.Counter { return r.routerRespsBytesCounter } -func (r *standardRegistry) ServiceReqsCounter() metrics.Counter { +func (r *standardRegistry) ServiceReqsCounter() CounterWithHeaders { return r.serviceReqsCounter } @@ -329,10 +289,6 @@ func (r *standardRegistry) ServiceReqDurationHistogram() ScalableHistogram { return r.serviceReqDurationHistogram } -func (r *standardRegistry) ServiceOpenConnsGauge() metrics.Gauge { - return r.serviceOpenConnsGauge -} - func (r *standardRegistry) ServiceRetriesCounter() metrics.Counter { return r.serviceRetriesCounter } diff --git a/pkg/metrics/metrics_test.go b/pkg/metrics/metrics_test.go index 7036335eaa1b346e59a94db3528bdc39536fbd4e..6871aa0a5fe401b4d3024b4af77a612de9239911 100644 --- a/pkg/metrics/metrics_test.go +++ b/pkg/metrics/metrics_test.go @@ -2,6 +2,7 @@ package metrics import ( "bytes" + "net/http" "strings" "testing" "time" @@ -37,12 +38,12 @@ func TestNewMultiRegistry(t *testing.T) { registries := []Registry{newCollectingRetryMetrics(), newCollectingRetryMetrics()} registry := NewMultiRegistry(registries) - registry.ServiceReqsCounter().With("key", "requests").Add(1) + registry.ServiceReqsCounter().With(nil, "key", "requests").Add(1) registry.ServiceReqDurationHistogram().With("key", "durations").Observe(float64(2)) registry.ServiceRetriesCounter().With("key", "retries").Add(3) for _, collectingRegistry := range registries { - cReqsCounter := collectingRegistry.ServiceReqsCounter().(*counterMock) + cReqsCounter := collectingRegistry.ServiceReqsCounter().(*counterWithHeadersMock) cReqDurationHistogram := collectingRegistry.ServiceReqDurationHistogram().(*histogramMock) cRetriesCounter := collectingRegistry.ServiceRetriesCounter().(*counterMock) @@ -67,7 +68,7 @@ func TestNewMultiRegistry(t *testing.T) { func newCollectingRetryMetrics() Registry { return &standardRegistry{ - serviceReqsCounter: &counterMock{}, + serviceReqsCounter: &counterWithHeadersMock{}, serviceReqDurationHistogram: &histogramMock{}, serviceRetriesCounter: &counterMock{}, } @@ -87,6 +88,20 @@ func (c *counterMock) Add(delta float64) { c.counterValue += delta } +type counterWithHeadersMock struct { + counterValue float64 + lastLabelValues []string +} + +func (c *counterWithHeadersMock) With(_ http.Header, labelValues ...string) CounterWithHeaders { + c.lastLabelValues = labelValues + return c +} + +func (c *counterWithHeadersMock) Add(delta float64) { + c.counterValue += delta +} + type histogramMock struct { lastHistogramValue float64 lastLabelValues []string diff --git a/pkg/metrics/opentelemetry.go b/pkg/metrics/opentelemetry.go index 328f6fc547fa97647bf444c599bb3b15fb52a657..5dda1d5d053ac798ac815b1cd1fb4eeb6fab1623 100644 --- a/pkg/metrics/opentelemetry.go +++ b/pkg/metrics/opentelemetry.go @@ -10,8 +10,8 @@ import ( "github.com/go-kit/kit/metrics" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/types" - "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/pkg/types" + "github.com/traefik/traefik/v3/pkg/version" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" @@ -23,7 +23,8 @@ import ( "go.opentelemetry.io/otel/metric/unit" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/metric/aggregation" - "go.opentelemetry.io/otel/sdk/metric/view" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.12.0" "google.golang.org/grpc/credentials" "google.golang.org/grpc/encoding/gzip" ) @@ -56,49 +57,39 @@ func RegisterOpenTelemetry(ctx context.Context, config *types.OpenTelemetry) Reg routerEnabled: config.AddRoutersLabels, svcEnabled: config.AddServicesLabels, configReloadsCounter: newOTLPCounterFrom(meter, configReloadsTotalName, "Config reloads"), - configReloadsFailureCounter: newOTLPCounterFrom(meter, configReloadsFailuresTotalName, "Config reload failures"), lastConfigReloadSuccessGauge: newOTLPGaugeFrom(meter, configLastReloadSuccessName, "Last config reload success", unit.Milliseconds), - lastConfigReloadFailureGauge: newOTLPGaugeFrom(meter, configLastReloadFailureName, "Last config reload failure", unit.Milliseconds), - tlsCertsNotAfterTimestampGauge: newOTLPGaugeFrom(meter, tlsCertsNotAfterTimestamp, "Certificate expiration timestamp", unit.Milliseconds), + openConnectionsGauge: newOTLPGaugeFrom(meter, openConnectionsName, "How many open connections exist, by entryPoint and protocol", unit.Dimensionless), + tlsCertsNotAfterTimestampGauge: newOTLPGaugeFrom(meter, tlsCertsNotAfterTimestampName, "Certificate expiration timestamp", unit.Milliseconds), } if config.AddEntryPointsLabels { - reg.entryPointReqsCounter = newOTLPCounterFrom(meter, entryPointReqsTotalName, - "How many HTTP requests processed on an entrypoint, partitioned by status code, protocol, and method.") + reg.entryPointReqsCounter = NewCounterWithNoopHeaders(newOTLPCounterFrom(meter, entryPointReqsTotalName, + "How many HTTP requests processed on an entrypoint, partitioned by status code, protocol, and method.")) reg.entryPointReqsTLSCounter = newOTLPCounterFrom(meter, entryPointReqsTLSTotalName, "How many HTTP requests with TLS processed on an entrypoint, partitioned by TLS Version and TLS cipher Used.") reg.entryPointReqDurationHistogram, _ = NewHistogramWithScale(newOTLPHistogramFrom(meter, entryPointReqDurationName, "How long it took to process the request on an entrypoint, partitioned by status code, protocol, and method.", unit.Milliseconds), time.Second) - reg.entryPointOpenConnsGauge = newOTLPGaugeFrom(meter, entryPointOpenConnsName, - "How many open connections exist on an entrypoint, partitioned by method and protocol.", - unit.Dimensionless) } if config.AddRoutersLabels { - reg.routerReqsCounter = newOTLPCounterFrom(meter, routerReqsTotalName, - "How many HTTP requests are processed on a router, partitioned by service, status code, protocol, and method.") + reg.routerReqsCounter = NewCounterWithNoopHeaders(newOTLPCounterFrom(meter, routerReqsTotalName, + "How many HTTP requests are processed on a router, partitioned by service, status code, protocol, and method.")) reg.routerReqsTLSCounter = newOTLPCounterFrom(meter, routerReqsTLSTotalName, "How many HTTP requests with TLS are processed on a router, partitioned by service, TLS Version, and TLS cipher Used.") reg.routerReqDurationHistogram, _ = NewHistogramWithScale(newOTLPHistogramFrom(meter, routerReqDurationName, "How long it took to process the request on a router, partitioned by service, status code, protocol, and method.", unit.Milliseconds), time.Second) - reg.routerOpenConnsGauge = newOTLPGaugeFrom(meter, routerOpenConnsName, - "How many open connections exist on a router, partitioned by service, method, and protocol.", - unit.Dimensionless) } if config.AddServicesLabels { - reg.serviceReqsCounter = newOTLPCounterFrom(meter, serviceReqsTotalName, - "How many HTTP requests processed on a service, partitioned by status code, protocol, and method.") + reg.serviceReqsCounter = NewCounterWithNoopHeaders(newOTLPCounterFrom(meter, serviceReqsTotalName, + "How many HTTP requests processed on a service, partitioned by status code, protocol, and method.")) reg.serviceReqsTLSCounter = newOTLPCounterFrom(meter, serviceReqsTLSTotalName, "How many HTTP requests with TLS processed on a service, partitioned by TLS version and TLS cipher.") reg.serviceReqDurationHistogram, _ = NewHistogramWithScale(newOTLPHistogramFrom(meter, serviceReqDurationName, "How long it took to process the request on a service, partitioned by status code, protocol, and method.", unit.Milliseconds), time.Second) - reg.serviceOpenConnsGauge = newOTLPGaugeFrom(meter, serviceOpenConnsName, - "How many open connections exist on a service, partitioned by method and protocol.", - unit.Dimensionless) reg.serviceRetriesCounter = newOTLPCounterFrom(meter, serviceRetriesTotalName, "How many request retries happened on a service.") reg.serviceServerUpGauge = newOTLPGaugeFrom(meter, serviceServerUpName, @@ -140,27 +131,31 @@ func newOpenTelemetryMeterProvider(ctx context.Context, config *types.OpenTeleme return nil, fmt.Errorf("creating exporter: %w", err) } + res, err := resource.New(ctx, + resource.WithAttributes(semconv.ServiceNameKey.String("traefik")), + resource.WithAttributes(semconv.ServiceVersionKey.String(version.Version)), + resource.WithFromEnv(), + resource.WithTelemetrySDK(), + ) + if err != nil { + return nil, fmt.Errorf("building resource: %w", err) + } + opts := []sdkmetric.PeriodicReaderOption{ sdkmetric.WithInterval(time.Duration(config.PushInterval)), } - // View to customize histogram buckets and rename a single histogram instrument. - customBucketsView, err := view.New( - // Match* to match instruments - view.MatchInstrumentName("traefik_*_request_duration_seconds"), - - view.WithSetAggregation(aggregation.ExplicitBucketHistogram{ - Boundaries: config.ExplicitBoundaries, - }), + meterProvider := sdkmetric.NewMeterProvider( + sdkmetric.WithResource(res), + sdkmetric.WithReader(sdkmetric.NewPeriodicReader(exporter, opts...)), + // View to customize histogram buckets and rename a single histogram instrument. + sdkmetric.WithView(sdkmetric.NewView( + sdkmetric.Instrument{Name: "traefik_*_request_duration_seconds"}, + sdkmetric.Stream{Aggregation: aggregation.ExplicitBucketHistogram{ + Boundaries: config.ExplicitBoundaries, + }}, + )), ) - if err != nil { - return nil, fmt.Errorf("creating histogram view: %w", err) - } - - meterProvider := sdkmetric.NewMeterProvider(sdkmetric.WithReader( - sdkmetric.NewPeriodicReader(exporter, opts...), - customBucketsView, - )) global.SetMeterProvider(meterProvider) diff --git a/pkg/metrics/opentelemetry_test.go b/pkg/metrics/opentelemetry_test.go index 16890b6ba1fe96c46d3039aac6c3597b9a954998..4f174700c51b215cb210d1a1d0578789b92240d2 100644 --- a/pkg/metrics/opentelemetry_test.go +++ b/pkg/metrics/opentelemetry_test.go @@ -4,7 +4,6 @@ import ( "compress/gzip" "context" "encoding/json" - "fmt" "io" "net/http" "net/http/httptest" @@ -16,7 +15,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/types" + "github.com/traefik/traefik/v3/pkg/version" "go.opentelemetry.io/collector/pdata/pmetric/pmetricotlp" "go.opentelemetry.io/otel/attribute" ) @@ -308,8 +308,7 @@ func TestOpenTelemetry(t *testing.T) { bodyStr := string(marshalledReq) c <- &bodyStr - _, err = fmt.Fprintln(w, "ok") - require.NoError(t, err) + w.WriteHeader(http.StatusOK) })) defer ts.Close() @@ -330,103 +329,96 @@ func TestOpenTelemetry(t *testing.T) { t.Fatalf("registry should return true for IsEnabled(), IsRouterEnabled() and IsSvcEnabled()") } + expected := []string{ + `({"key":"service.name","value":{"stringValue":"traefik"}})`, + `({"key":"service.version","value":{"stringValue":"` + version.Version + `"}})`, + } + msgMisc := <-c + + assertMessage(t, *msgMisc, expected) + // TODO: the len of startUnixNano is no supposed to be 20, it should be 19 - expectedServer := []string{ + expected = append(expected, `({"name":"traefik_config_reloads_total","description":"Config reloads","unit":"1","sum":{"dataPoints":\[{"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`, - `({"name":"traefik_config_reloads_failure_total","description":"Config reload failures","unit":"1","sum":{"dataPoints":\[{"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`, `({"name":"traefik_config_last_reload_success","description":"Last config reload success","unit":"ms","gauge":{"dataPoints":\[{"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`, - `({"name":"traefik_config_last_reload_failure","description":"Last config reload failure","unit":"ms","gauge":{"dataPoints":\[{"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`, - } + `({"name":"traefik_open_connections","description":"How many open connections exist, by entryPoint and protocol","unit":"1","gauge":{"dataPoints":\[{"attributes":\[{"key":"entrypoint","value":{"stringValue":"test"}},{"key":"protocol","value":{"stringValue":"TCP"}}\],"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`, + ) registry.ConfigReloadsCounter().Add(1) - registry.ConfigReloadsFailureCounter().Add(1) registry.LastConfigReloadSuccessGauge().Set(1) - registry.LastConfigReloadFailureGauge().Set(1) + registry.OpenConnectionsGauge().With("entrypoint", "test", "protocol", "TCP").Set(1) msgServer := <-c - assertMessage(t, *msgServer, expectedServer) + assertMessage(t, *msgServer, expected) - expectedTLS := []string{ + expected = append(expected, `({"name":"traefik_tls_certs_not_after","description":"Certificate expiration timestamp","unit":"ms","gauge":{"dataPoints":\[{"attributes":\[{"key":"key","value":{"stringValue":"value"}}\],"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`, - } + ) registry.TLSCertsNotAfterTimestampGauge().With("key", "value").Set(1) msgTLS := <-c - assertMessage(t, *msgTLS, expectedTLS) + assertMessage(t, *msgTLS, expected) - expectedEntrypoint := []string{ + expected = append(expected, `({"name":"traefik_entrypoint_requests_total","description":"How many HTTP requests processed on an entrypoint, partitioned by status code, protocol, and method.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"200"}},{"key":"entrypoint","value":{"stringValue":"test1"}},{"key":"method","value":{"stringValue":"GET"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`, `({"name":"traefik_entrypoint_requests_tls_total","description":"How many HTTP requests with TLS processed on an entrypoint, partitioned by TLS Version and TLS cipher Used.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"entrypoint","value":{"stringValue":"test2"}},{"key":"tls_cipher","value":{"stringValue":"bar"}},{"key":"tls_version","value":{"stringValue":"foo"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`, `({"name":"traefik_entrypoint_request_duration_seconds","description":"How long it took to process the request on an entrypoint, partitioned by status code, protocol, and method.","unit":"ms","histogram":{"dataPoints":\[{"attributes":\[{"key":"entrypoint","value":{"stringValue":"test3"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","count":"1","sum":10000,"bucketCounts":\["0","0","0","0","0","0","0","0","0","0","0","1"\],"explicitBounds":\[0.005,0.01,0.025,0.05,0.1,0.25,0.5,1,2.5,5,10\],"min":10000,"max":10000}\],"aggregationTemporality":2}})`, - `({"name":"traefik_entrypoint_open_connections","description":"How many open connections exist on an entrypoint, partitioned by method and protocol.","unit":"1","gauge":{"dataPoints":\[{"attributes":\[{"key":"entrypoint","value":{"stringValue":"test4"}}\],"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`, - } + ) - registry.EntryPointReqsCounter().With("entrypoint", "test1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + registry.EntryPointReqsCounter().With(nil, "entrypoint", "test1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) registry.EntryPointReqsTLSCounter().With("entrypoint", "test2", "tls_version", "foo", "tls_cipher", "bar").Add(1) registry.EntryPointReqDurationHistogram().With("entrypoint", "test3").Observe(10000) - registry.EntryPointOpenConnsGauge().With("entrypoint", "test4").Set(1) msgEntrypoint := <-c - assertMessage(t, *msgEntrypoint, expectedEntrypoint) + assertMessage(t, *msgEntrypoint, expected) - expectedRouter := []string{ + expected = append(expected, `({"name":"traefik_router_requests_total","description":"How many HTTP requests are processed on a router, partitioned by service, status code, protocol, and method.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"(?:200|404)"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"router","value":{"stringValue":"RouterReqsCounter"}},{"key":"service","value":{"stringValue":"test"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1},{"attributes":\[{"key":"code","value":{"stringValue":"(?:200|404)"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"router","value":{"stringValue":"RouterReqsCounter"}},{"key":"service","value":{"stringValue":"test"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`, `({"name":"traefik_router_requests_tls_total","description":"How many HTTP requests with TLS are processed on a router, partitioned by service, TLS Version, and TLS cipher Used.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"router","value":{"stringValue":"demo"}},{"key":"service","value":{"stringValue":"test"}},{"key":"tls_cipher","value":{"stringValue":"bar"}},{"key":"tls_version","value":{"stringValue":"foo"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`, `({"name":"traefik_router_request_duration_seconds","description":"How long it took to process the request on a router, partitioned by service, status code, protocol, and method.","unit":"ms","histogram":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"200"}},{"key":"router","value":{"stringValue":"demo"}},{"key":"service","value":{"stringValue":"test"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","count":"1","sum":10000,"bucketCounts":\["0","0","0","0","0","0","0","0","0","0","0","1"\],"explicitBounds":\[0.005,0.01,0.025,0.05,0.1,0.25,0.5,1,2.5,5,10\],"min":10000,"max":10000}\],"aggregationTemporality":2}})`, - `({"name":"traefik_router_open_connections","description":"How many open connections exist on a router, partitioned by service, method, and protocol.","unit":"1","gauge":{"dataPoints":\[{"attributes":\[{"key":"router","value":{"stringValue":"demo"}},{"key":"service","value":{"stringValue":"test"}}\],"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`, - } + ) - registry.RouterReqsCounter().With("router", "RouterReqsCounter", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - registry.RouterReqsCounter().With("router", "RouterReqsCounter", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + registry.RouterReqsCounter().With(nil, "router", "RouterReqsCounter", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) + registry.RouterReqsCounter().With(nil, "router", "RouterReqsCounter", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) registry.RouterReqsTLSCounter().With("router", "demo", "service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) registry.RouterReqDurationHistogram().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - registry.RouterOpenConnsGauge().With("router", "demo", "service", "test").Set(1) msgRouter := <-c - assertMessage(t, *msgRouter, expectedRouter) + assertMessage(t, *msgRouter, expected) - expectedService := []string{ + expected = append(expected, `({"name":"traefik_service_requests_total","description":"How many HTTP requests processed on a service, partitioned by status code, protocol, and method.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"(?:200|404)"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"service","value":{"stringValue":"ServiceReqsCounter"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1},{"attributes":\[{"key":"code","value":{"stringValue":"(?:200|404)"}},{"key":"method","value":{"stringValue":"GET"}},{"key":"service","value":{"stringValue":"ServiceReqsCounter"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`, `({"name":"traefik_service_requests_tls_total","description":"How many HTTP requests with TLS processed on a service, partitioned by TLS version and TLS cipher.","unit":"1","sum":{"dataPoints":\[{"attributes":\[{"key":"service","value":{"stringValue":"test"}},{"key":"tls_cipher","value":{"stringValue":"bar"}},{"key":"tls_version","value":{"stringValue":"foo"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1}\],"aggregationTemporality":2,"isMonotonic":true}})`, `({"name":"traefik_service_request_duration_seconds","description":"How long it took to process the request on a service, partitioned by status code, protocol, and method.","unit":"ms","histogram":{"dataPoints":\[{"attributes":\[{"key":"code","value":{"stringValue":"200"}},{"key":"service","value":{"stringValue":"test"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","count":"1","sum":10000,"bucketCounts":\["0","0","0","0","0","0","0","0","0","0","0","1"\],"explicitBounds":\[0.005,0.01,0.025,0.05,0.1,0.25,0.5,1,2.5,5,10\],"min":10000,"max":10000}\],"aggregationTemporality":2}})`, `({"name":"traefik_service_server_up","description":"service server is up, described by gauge value of 0 or 1.","unit":"1","gauge":{"dataPoints":\[{"attributes":\[{"key":"service","value":{"stringValue":"test"}},{"key":"url","value":{"stringValue":"http://127.0.0.1"}}\],"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1}\]}})`, - } + ) - registry.ServiceReqsCounter().With("service", "ServiceReqsCounter", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - registry.ServiceReqsCounter().With("service", "ServiceReqsCounter", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) + registry.ServiceReqsCounter().With(nil, "service", "ServiceReqsCounter", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + registry.ServiceReqsCounter().With(nil, "service", "ServiceReqsCounter", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) registry.ServiceReqsTLSCounter().With("service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) registry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) registry.ServiceServerUpGauge().With("service", "test", "url", "http://127.0.0.1").Set(1) msgService := <-c - assertMessage(t, *msgService, expectedService) + assertMessage(t, *msgService, expected) - expectedServiceRetries := []string{ + expected = append(expected, `({"attributes":\[{"key":"service","value":{"stringValue":"foobar"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":1})`, `({"attributes":\[{"key":"service","value":{"stringValue":"test"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","asDouble":2})`, - } + ) registry.ServiceRetriesCounter().With("service", "test").Add(1) registry.ServiceRetriesCounter().With("service", "test").Add(1) registry.ServiceRetriesCounter().With("service", "foobar").Add(1) msgServiceRetries := <-c - assertMessage(t, *msgServiceRetries, expectedServiceRetries) - - expectedServiceOpenConns := []string{ - `({"attributes":\[{"key":"service","value":{"stringValue":"test"}}\],"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":3})`, - `({"attributes":\[{"key":"service","value":{"stringValue":"foobar"}}\],"startTimeUnixNano":"[\d]{20}","timeUnixNano":"[\d]{19}","asDouble":1})`, - } - - registry.ServiceOpenConnsGauge().With("service", "test").Set(1) - registry.ServiceOpenConnsGauge().With("service", "test").Add(1) - registry.ServiceOpenConnsGauge().With("service", "test").Add(1) - registry.ServiceOpenConnsGauge().With("service", "foobar").Add(1) - msgServiceOpenConns := <-c - - assertMessage(t, *msgServiceOpenConns, expectedServiceOpenConns) + assertMessage(t, *msgServiceRetries, expected) + // We cannot rely on the previous expected pattern, + // because this pattern was for matching only one dataPoint in the histogram, + // and as soon as the EntryPointReqDurationHistogram.Observe is called, + // it adds a new dataPoint to the histogram. expectedEntryPointReqDuration := []string{ `({"attributes":\[{"key":"entrypoint","value":{"stringValue":"myEntrypoint"}}\],"startTimeUnixNano":"[\d]{19}","timeUnixNano":"[\d]{19}","count":"2","sum":30000,"bucketCounts":\["0","0","0","0","0","0","0","0","0","0","0","2"\],"explicitBounds":\[0.005,0.01,0.025,0.05,0.1,0.25,0.5,1,2.5,5,10\],"min":10000,"max":20000})`, } diff --git a/pkg/metrics/prometheus.go b/pkg/metrics/prometheus.go index edad9e6f748ad958eba377aad182a1d7ff1055d9..608acf16ad5cd546229a284e21ac08e6c4d6c33c 100644 --- a/pkg/metrics/prometheus.go +++ b/pkg/metrics/prometheus.go @@ -12,8 +12,8 @@ import ( "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/types" ) const ( @@ -21,22 +21,20 @@ const ( MetricNamePrefix = "traefik_" // server meta information. - metricConfigPrefix = MetricNamePrefix + "config_" - configReloadsTotalName = metricConfigPrefix + "reloads_total" - configReloadsFailuresTotalName = metricConfigPrefix + "reloads_failure_total" - configLastReloadSuccessName = metricConfigPrefix + "last_reload_success" - configLastReloadFailureName = metricConfigPrefix + "last_reload_failure" + metricConfigPrefix = MetricNamePrefix + "config_" + configReloadsTotalName = metricConfigPrefix + "reloads_total" + configLastReloadSuccessName = metricConfigPrefix + "last_reload_success" + openConnectionsName = MetricNamePrefix + "open_connections" // TLS. - metricsTLSPrefix = MetricNamePrefix + "tls_" - tlsCertsNotAfterTimestamp = metricsTLSPrefix + "certs_not_after" + metricsTLSPrefix = MetricNamePrefix + "tls_" + tlsCertsNotAfterTimestampName = metricsTLSPrefix + "certs_not_after" // entry point. metricEntryPointPrefix = MetricNamePrefix + "entrypoint_" entryPointReqsTotalName = metricEntryPointPrefix + "requests_total" entryPointReqsTLSTotalName = metricEntryPointPrefix + "requests_tls_total" entryPointReqDurationName = metricEntryPointPrefix + "request_duration_seconds" - entryPointOpenConnsName = metricEntryPointPrefix + "open_connections" entryPointReqsBytesTotalName = metricEntryPointPrefix + "requests_bytes_total" entryPointRespsBytesTotalName = metricEntryPointPrefix + "responses_bytes_total" @@ -45,7 +43,6 @@ const ( routerReqsTotalName = metricRouterPrefix + "requests_total" routerReqsTLSTotalName = metricRouterPrefix + "requests_tls_total" routerReqDurationName = metricRouterPrefix + "request_duration_seconds" - routerOpenConnsName = metricRouterPrefix + "open_connections" routerReqsBytesTotalName = metricRouterPrefix + "requests_bytes_total" routerRespsBytesTotalName = metricRouterPrefix + "responses_bytes_total" @@ -54,7 +51,6 @@ const ( serviceReqsTotalName = metricServicePrefix + "requests_total" serviceReqsTLSTotalName = metricServicePrefix + "requests_tls_total" serviceReqDurationName = metricServicePrefix + "request_duration_seconds" - serviceOpenConnsName = metricServicePrefix + "open_connections" serviceRetriesTotalName = metricServicePrefix + "retries_total" serviceServerUpName = metricServicePrefix + "server_up" serviceReqsBytesTotalName = metricServicePrefix + "requests_bytes_total" @@ -118,29 +114,24 @@ func initStandardRegistry(config *types.Prometheus) Registry { Name: configReloadsTotalName, Help: "Config reloads", }, []string{}) - configReloadsFailures := newCounterFrom(stdprometheus.CounterOpts{ - Name: configReloadsFailuresTotalName, - Help: "Config failure reloads", - }, []string{}) lastConfigReloadSuccess := newGaugeFrom(stdprometheus.GaugeOpts{ Name: configLastReloadSuccessName, Help: "Last config reload success", }, []string{}) - lastConfigReloadFailure := newGaugeFrom(stdprometheus.GaugeOpts{ - Name: configLastReloadFailureName, - Help: "Last config reload failure", - }, []string{}) tlsCertsNotAfterTimestamp := newGaugeFrom(stdprometheus.GaugeOpts{ - Name: tlsCertsNotAfterTimestamp, + Name: tlsCertsNotAfterTimestampName, Help: "Certificate expiration timestamp", }, []string{"cn", "serial", "sans"}) + openConnections := newGaugeFrom(stdprometheus.GaugeOpts{ + Name: openConnectionsName, + Help: "How many open connections exist, by entryPoint and protocol", + }, []string{"entrypoint", "protocol"}) promState.vectors = []vector{ configReloads.cv, - configReloadsFailures.cv, lastConfigReloadSuccess.gv, - lastConfigReloadFailure.gv, tlsCertsNotAfterTimestamp.gv, + openConnections.gv, } reg := &standardRegistry{ @@ -148,17 +139,16 @@ func initStandardRegistry(config *types.Prometheus) Registry { routerEnabled: config.AddRoutersLabels, svcEnabled: config.AddServicesLabels, configReloadsCounter: configReloads, - configReloadsFailureCounter: configReloadsFailures, lastConfigReloadSuccessGauge: lastConfigReloadSuccess, - lastConfigReloadFailureGauge: lastConfigReloadFailure, tlsCertsNotAfterTimestampGauge: tlsCertsNotAfterTimestamp, + openConnectionsGauge: openConnections, } if config.AddEntryPointsLabels { - entryPointReqs := newCounterFrom(stdprometheus.CounterOpts{ + entryPointReqs := newCounterWithHeadersFrom(stdprometheus.CounterOpts{ Name: entryPointReqsTotalName, Help: "How many HTTP requests processed on an entrypoint, partitioned by status code, protocol, and method.", - }, []string{"code", "method", "protocol", "entrypoint"}) + }, config.HeaderLabels, []string{"code", "method", "protocol", "entrypoint"}) entryPointReqsTLS := newCounterFrom(stdprometheus.CounterOpts{ Name: entryPointReqsTLSTotalName, Help: "How many HTTP requests with TLS processed on an entrypoint, partitioned by TLS Version and TLS cipher Used.", @@ -168,10 +158,6 @@ func initStandardRegistry(config *types.Prometheus) Registry { Help: "How long it took to process the request on an entrypoint, partitioned by status code, protocol, and method.", Buckets: buckets, }, []string{"code", "method", "protocol", "entrypoint"}) - entryPointOpenConns := newGaugeFrom(stdprometheus.GaugeOpts{ - Name: entryPointOpenConnsName, - Help: "How many open connections exist on an entrypoint, partitioned by method and protocol.", - }, []string{"method", "protocol", "entrypoint"}) entryPointReqsBytesTotal := newCounterFrom(stdprometheus.CounterOpts{ Name: entryPointReqsBytesTotalName, Help: "The total size of requests in bytes handled by an entrypoint, partitioned by status code, protocol, and method.", @@ -185,7 +171,6 @@ func initStandardRegistry(config *types.Prometheus) Registry { entryPointReqs.cv, entryPointReqsTLS.cv, entryPointReqDurations.hv, - entryPointOpenConns.gv, entryPointReqsBytesTotal.cv, entryPointRespsBytesTotal.cv, ) @@ -193,16 +178,15 @@ func initStandardRegistry(config *types.Prometheus) Registry { reg.entryPointReqsCounter = entryPointReqs reg.entryPointReqsTLSCounter = entryPointReqsTLS reg.entryPointReqDurationHistogram, _ = NewHistogramWithScale(entryPointReqDurations, time.Second) - reg.entryPointOpenConnsGauge = entryPointOpenConns reg.entryPointReqsBytesCounter = entryPointReqsBytesTotal reg.entryPointRespsBytesCounter = entryPointRespsBytesTotal } if config.AddRoutersLabels { - routerReqs := newCounterFrom(stdprometheus.CounterOpts{ + routerReqs := newCounterWithHeadersFrom(stdprometheus.CounterOpts{ Name: routerReqsTotalName, Help: "How many HTTP requests are processed on a router, partitioned by service, status code, protocol, and method.", - }, []string{"code", "method", "protocol", "router", "service"}) + }, config.HeaderLabels, []string{"code", "method", "protocol", "router", "service"}) routerReqsTLS := newCounterFrom(stdprometheus.CounterOpts{ Name: routerReqsTLSTotalName, Help: "How many HTTP requests with TLS are processed on a router, partitioned by service, TLS Version, and TLS cipher Used.", @@ -212,10 +196,6 @@ func initStandardRegistry(config *types.Prometheus) Registry { Help: "How long it took to process the request on a router, partitioned by service, status code, protocol, and method.", Buckets: buckets, }, []string{"code", "method", "protocol", "router", "service"}) - routerOpenConns := newGaugeFrom(stdprometheus.GaugeOpts{ - Name: routerOpenConnsName, - Help: "How many open connections exist on a router, partitioned by service, method, and protocol.", - }, []string{"method", "protocol", "router", "service"}) routerReqsBytesTotal := newCounterFrom(stdprometheus.CounterOpts{ Name: routerReqsBytesTotalName, Help: "The total size of requests in bytes handled by a router, partitioned by service, status code, protocol, and method.", @@ -229,23 +209,21 @@ func initStandardRegistry(config *types.Prometheus) Registry { routerReqs.cv, routerReqsTLS.cv, routerReqDurations.hv, - routerOpenConns.gv, routerReqsBytesTotal.cv, routerRespsBytesTotal.cv, ) reg.routerReqsCounter = routerReqs reg.routerReqsTLSCounter = routerReqsTLS reg.routerReqDurationHistogram, _ = NewHistogramWithScale(routerReqDurations, time.Second) - reg.routerOpenConnsGauge = routerOpenConns reg.routerReqsBytesCounter = routerReqsBytesTotal reg.routerRespsBytesCounter = routerRespsBytesTotal } if config.AddServicesLabels { - serviceReqs := newCounterFrom(stdprometheus.CounterOpts{ + serviceReqs := newCounterWithHeadersFrom(stdprometheus.CounterOpts{ Name: serviceReqsTotalName, Help: "How many HTTP requests processed on a service, partitioned by status code, protocol, and method.", - }, []string{"code", "method", "protocol", "service"}) + }, config.HeaderLabels, []string{"code", "method", "protocol", "service"}) serviceReqsTLS := newCounterFrom(stdprometheus.CounterOpts{ Name: serviceReqsTLSTotalName, Help: "How many HTTP requests with TLS processed on a service, partitioned by TLS version and TLS cipher.", @@ -255,10 +233,6 @@ func initStandardRegistry(config *types.Prometheus) Registry { Help: "How long it took to process the request on a service, partitioned by status code, protocol, and method.", Buckets: buckets, }, []string{"code", "method", "protocol", "service"}) - serviceOpenConns := newGaugeFrom(stdprometheus.GaugeOpts{ - Name: serviceOpenConnsName, - Help: "How many open connections exist on a service, partitioned by method and protocol.", - }, []string{"method", "protocol", "service"}) serviceRetries := newCounterFrom(stdprometheus.CounterOpts{ Name: serviceRetriesTotalName, Help: "How many request retries happened on a service.", @@ -280,7 +254,6 @@ func initStandardRegistry(config *types.Prometheus) Registry { serviceReqs.cv, serviceReqsTLS.cv, serviceReqDurations.hv, - serviceOpenConns.gv, serviceRetries.cv, serviceServerUp.gv, serviceReqsBytesTotal.cv, @@ -290,7 +263,6 @@ func initStandardRegistry(config *types.Prometheus) Registry { reg.serviceReqsCounter = serviceReqs reg.serviceReqsTLSCounter = serviceReqsTLS reg.serviceReqDurationHistogram, _ = NewHistogramWithScale(serviceReqDurations, time.Second) - reg.serviceOpenConnsGauge = serviceOpenConns reg.serviceRetriesCounter = serviceRetries reg.serviceServerUpGauge = serviceServerUp reg.serviceReqsBytesCounter = serviceReqsBytesTotal @@ -508,6 +480,55 @@ func (d *dynamicConfig) hasServerURL(serviceName, serverURL string) bool { return false } +func newCounterWithHeadersFrom(opts stdprometheus.CounterOpts, headers map[string]string, labelNames []string) *counterWithHeaders { + var headerLabels []string + for k := range headers { + headerLabels = append(headerLabels, k) + } + + cv := stdprometheus.NewCounterVec(opts, append(labelNames, headerLabels...)) + c := &counterWithHeaders{ + name: opts.Name, + headers: headers, + cv: cv, + } + if len(labelNames) == 0 && len(headerLabels) == 0 { + c.collector = cv.WithLabelValues() + c.Add(0) + } + return c +} + +type counterWithHeaders struct { + name string + cv *stdprometheus.CounterVec + labelNamesValues labelNamesValues + headers map[string]string + collector stdprometheus.Counter +} + +func (c *counterWithHeaders) With(headers http.Header, labelValues ...string) CounterWithHeaders { + for headerLabel, headerKey := range c.headers { + labelValues = append(labelValues, headerLabel, headers.Get(headerKey)) + } + lnv := c.labelNamesValues.With(labelValues...) + return &counterWithHeaders{ + name: c.name, + headers: c.headers, + cv: c.cv, + labelNamesValues: lnv, + collector: c.cv.With(lnv.ToLabels()), + } +} + +func (c *counterWithHeaders) Add(delta float64) { + c.collector.Add(delta) +} + +func (c *counterWithHeaders) Describe(ch chan<- *stdprometheus.Desc) { + c.cv.Describe(ch) +} + func newCounterFrom(opts stdprometheus.CounterOpts, labelNames []string) *counter { cv := stdprometheus.NewCounterVec(opts, labelNames) c := &counter{ diff --git a/pkg/metrics/prometheus_test.go b/pkg/metrics/prometheus_test.go index 744a7615d94be37342e66ff06177c0ac9ffdf81e..9a5bfeba7a0d3d375557d4f52aa7000858f8ecda 100644 --- a/pkg/metrics/prometheus_test.go +++ b/pkg/metrics/prometheus_test.go @@ -11,9 +11,9 @@ import ( "github.com/prometheus/client_golang/prometheus" dto "github.com/prometheus/client_model/go" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - th "github.com/traefik/traefik/v2/pkg/testhelpers" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + th "github.com/traefik/traefik/v3/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/types" ) func TestRegisterPromState(t *testing.T) { @@ -92,7 +92,12 @@ func TestPrometheus(t *testing.T) { promRegistry = prometheus.NewRegistry() t.Cleanup(promState.reset) - prometheusRegistry := RegisterPrometheus(context.Background(), &types.Prometheus{AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true}) + prometheusRegistry := RegisterPrometheus(context.Background(), &types.Prometheus{ + AddEntryPointsLabels: true, + AddRoutersLabels: true, + AddServicesLabels: true, + HeaderLabels: map[string]string{"useragent": "User-Agent"}, + }) defer promRegistry.Unregister(promState) if !prometheusRegistry.IsEpEnabled() || !prometheusRegistry.IsRouterEnabled() || !prometheusRegistry.IsSvcEnabled() { @@ -100,9 +105,11 @@ func TestPrometheus(t *testing.T) { } prometheusRegistry.ConfigReloadsCounter().Add(1) - prometheusRegistry.ConfigReloadsFailureCounter().Add(1) prometheusRegistry.LastConfigReloadSuccessGauge().Set(float64(time.Now().Unix())) - prometheusRegistry.LastConfigReloadFailureGauge().Set(float64(time.Now().Unix())) + prometheusRegistry. + OpenConnectionsGauge(). + With("entrypoint", "test", "protocol", "TCP"). + Set(1) prometheusRegistry. TLSCertsNotAfterTimestampGauge(). @@ -111,16 +118,12 @@ func TestPrometheus(t *testing.T) { prometheusRegistry. EntryPointReqsCounter(). - With("code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http", "entrypoint", "http"). + With(map[string][]string{"User-Agent": {"foobar"}}, "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http", "entrypoint", "http"). Add(1) prometheusRegistry. EntryPointReqDurationHistogram(). With("code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http", "entrypoint", "http"). Observe(1) - prometheusRegistry. - EntryPointOpenConnsGauge(). - With("method", http.MethodGet, "protocol", "http", "entrypoint", "http"). - Set(1) prometheusRegistry. EntryPointRespsBytesCounter(). With("code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http", "entrypoint", "http"). @@ -132,7 +135,7 @@ func TestPrometheus(t *testing.T) { prometheusRegistry. RouterReqsCounter(). - With("router", "demo", "service", "service1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). + With(nil, "router", "demo", "service", "service1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). Add(1) prometheusRegistry. RouterReqsTLSCounter(). @@ -142,10 +145,6 @@ func TestPrometheus(t *testing.T) { RouterReqDurationHistogram(). With("router", "demo", "service", "service1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). Observe(10000) - prometheusRegistry. - RouterOpenConnsGauge(). - With("router", "demo", "service", "service1", "method", http.MethodGet, "protocol", "http"). - Set(1) prometheusRegistry. RouterRespsBytesCounter(). With("router", "demo", "service", "service1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). @@ -157,7 +156,7 @@ func TestPrometheus(t *testing.T) { prometheusRegistry. ServiceReqsCounter(). - With("service", "service1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). + With(map[string][]string{"User-Agent": {"foobar"}}, "service", "service1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). Add(1) prometheusRegistry. ServiceReqsTLSCounter(). @@ -167,10 +166,6 @@ func TestPrometheus(t *testing.T) { ServiceReqDurationHistogram(). With("service", "service1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). Observe(10000) - prometheusRegistry. - ServiceOpenConnsGauge(). - With("service", "service1", "method", http.MethodGet, "protocol", "http"). - Set(1) prometheusRegistry. ServiceRetriesCounter(). With("service", "service1"). @@ -201,26 +196,26 @@ func TestPrometheus(t *testing.T) { name: configReloadsTotalName, assert: buildCounterAssert(t, configReloadsTotalName, 1), }, - { - name: configReloadsFailuresTotalName, - assert: buildCounterAssert(t, configReloadsFailuresTotalName, 1), - }, { name: configLastReloadSuccessName, assert: buildTimestampAssert(t, configLastReloadSuccessName), }, { - name: configLastReloadFailureName, - assert: buildTimestampAssert(t, configLastReloadFailureName), + name: openConnectionsName, + labels: map[string]string{ + "protocol": "TCP", + "entrypoint": "test", + }, + assert: buildGaugeAssert(t, openConnectionsName, 1), }, { - name: tlsCertsNotAfterTimestamp, + name: tlsCertsNotAfterTimestampName, labels: map[string]string{ "cn": "value", "serial": "value", "sans": "value", }, - assert: buildTimestampAssert(t, tlsCertsNotAfterTimestamp), + assert: buildTimestampAssert(t, tlsCertsNotAfterTimestampName), }, { name: entryPointReqsTotalName, @@ -229,6 +224,7 @@ func TestPrometheus(t *testing.T) { "method": http.MethodGet, "protocol": "http", "entrypoint": "http", + "useragent": "foobar", }, assert: buildCounterAssert(t, entryPointReqsTotalName, 1), }, @@ -242,15 +238,6 @@ func TestPrometheus(t *testing.T) { }, assert: buildHistogramAssert(t, entryPointReqDurationName, 1), }, - { - name: entryPointOpenConnsName, - labels: map[string]string{ - "method": http.MethodGet, - "protocol": "http", - "entrypoint": "http", - }, - assert: buildGaugeAssert(t, entryPointOpenConnsName, 1), - }, { name: entryPointReqsBytesTotalName, labels: map[string]string{ @@ -274,11 +261,12 @@ func TestPrometheus(t *testing.T) { { name: routerReqsTotalName, labels: map[string]string{ - "code": "200", - "method": http.MethodGet, - "protocol": "http", - "service": "service1", - "router": "demo", + "code": "200", + "method": http.MethodGet, + "protocol": "http", + "service": "service1", + "router": "demo", + "useragent": "", }, assert: buildCounterAssert(t, routerReqsTotalName, 1), }, @@ -303,16 +291,6 @@ func TestPrometheus(t *testing.T) { }, assert: buildHistogramAssert(t, routerReqDurationName, 1), }, - { - name: routerOpenConnsName, - labels: map[string]string{ - "method": http.MethodGet, - "protocol": "http", - "service": "service1", - "router": "demo", - }, - assert: buildGaugeAssert(t, routerOpenConnsName, 1), - }, { name: routerReqsBytesTotalName, labels: map[string]string{ @@ -338,10 +316,11 @@ func TestPrometheus(t *testing.T) { { name: serviceReqsTotalName, labels: map[string]string{ - "code": "200", - "method": http.MethodGet, - "protocol": "http", - "service": "service1", + "code": "200", + "method": http.MethodGet, + "protocol": "http", + "service": "service1", + "useragent": "foobar", }, assert: buildCounterAssert(t, serviceReqsTotalName, 1), }, @@ -364,15 +343,6 @@ func TestPrometheus(t *testing.T) { }, assert: buildHistogramAssert(t, serviceReqDurationName, 1), }, - { - name: serviceOpenConnsName, - labels: map[string]string{ - "method": http.MethodGet, - "protocol": "http", - "service": "service1", - }, - assert: buildGaugeAssert(t, serviceOpenConnsName, 1), - }, { name: serviceRetriesTotalName, labels: map[string]string{ @@ -476,15 +446,15 @@ func TestPrometheusMetricRemoval(t *testing.T) { // should be removed after that scrape. prometheusRegistry. EntryPointReqsCounter(). - With("entrypoint", "entrypoint2", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). + With(nil, "entrypoint", "entrypoint2", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). Add(1) prometheusRegistry. RouterReqsCounter(). - With("router", "router2", "service", "bar@providerName", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). + With(nil, "router", "router2", "service", "bar@providerName", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). Add(1) prometheusRegistry. ServiceReqsCounter(). - With("service", "service1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). + With(nil, "service", "service1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). Add(1) prometheusRegistry. ServiceServerUpGauge(). @@ -502,15 +472,15 @@ func TestPrometheusMetricRemoval(t *testing.T) { // here the counter examples. prometheusRegistry. EntryPointReqsCounter(). - With("entrypoint", "entrypoint1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). + With(nil, "entrypoint", "entrypoint1", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). Add(1) prometheusRegistry. RouterReqsCounter(). - With("router", "foo@providerName", "service", "bar", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). + With(nil, "router", "foo@providerName", "service", "bar", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). Add(1) prometheusRegistry. ServiceReqsCounter(). - With("service", "bar@providerName", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). + With(nil, "service", "bar@providerName", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet, "protocol", "http"). Add(1) prometheusRegistry. ServiceServerUpGauge(). @@ -588,7 +558,7 @@ func TestPrometheusRemovedMetricsReset(t *testing.T) { } prometheusRegistry. ServiceReqsCounter(). - With(labelNamesValues...). + With(nil, labelNamesValues...). Add(3) delayForTrackingCompletion() @@ -602,7 +572,7 @@ func TestPrometheusRemovedMetricsReset(t *testing.T) { prometheusRegistry. ServiceReqsCounter(). - With(labelNamesValues...). + With(nil, labelNamesValues...). Add(1) delayForTrackingCompletion() diff --git a/pkg/metrics/statsd.go b/pkg/metrics/statsd.go index 2a1c80a9ca513af8c422cb32be2fbe999c2399f5..871300ef6e3a441f499bfb4276714593ce8ee061 100644 --- a/pkg/metrics/statsd.go +++ b/pkg/metrics/statsd.go @@ -6,9 +6,9 @@ import ( "github.com/go-kit/kit/metrics/statsd" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/types" ) var ( @@ -18,23 +18,20 @@ var ( const ( statsdConfigReloadsName = "config.reload.total" - statsdConfigReloadsFailureName = statsdConfigReloadsName + ".failure" statsdLastConfigReloadSuccessName = "config.reload.lastSuccessTimestamp" - statsdLastConfigReloadFailureName = "config.reload.lastFailureTimestamp" + statsdOpenConnectionsName = "open.connections" statsdTLSCertsNotAfterTimestampName = "tls.certs.notAfterTimestamp" statsdEntryPointReqsName = "entrypoint.request.total" statsdEntryPointReqsTLSName = "entrypoint.request.tls.total" statsdEntryPointReqDurationName = "entrypoint.request.duration" - statsdEntryPointOpenConnsName = "entrypoint.connections.open" statsdEntryPointReqsBytesName = "entrypoint.requests.bytes.total" statsdEntryPointRespsBytesName = "entrypoint.responses.bytes.total" statsdRouterReqsName = "router.request.total" statsdRouterReqsTLSName = "router.request.tls.total" statsdRouterReqsDurationName = "router.request.duration" - statsdRouterOpenConnsName = "router.connections.open" statsdRouterReqsBytesName = "router.requests.bytes.total" statsdRouterRespsBytesName = "router.responses.bytes.total" @@ -43,7 +40,6 @@ const ( statsdServiceReqsDurationName = "service.request.duration" statsdServiceRetriesTotalName = "service.retries.total" statsdServiceServerUpName = "service.server.up" - statsdServiceOpenConnsName = "service.connections.open" statsdServiceReqsBytesName = "service.requests.bytes.total" statsdServiceRespsBytesName = "service.responses.bytes.total" ) @@ -63,39 +59,35 @@ func RegisterStatsd(ctx context.Context, config *types.Statsd) Registry { registry := &standardRegistry{ configReloadsCounter: statsdClient.NewCounter(statsdConfigReloadsName, 1.0), - configReloadsFailureCounter: statsdClient.NewCounter(statsdConfigReloadsFailureName, 1.0), lastConfigReloadSuccessGauge: statsdClient.NewGauge(statsdLastConfigReloadSuccessName), - lastConfigReloadFailureGauge: statsdClient.NewGauge(statsdLastConfigReloadFailureName), tlsCertsNotAfterTimestampGauge: statsdClient.NewGauge(statsdTLSCertsNotAfterTimestampName), + openConnectionsGauge: statsdClient.NewGauge(statsdOpenConnectionsName), } if config.AddEntryPointsLabels { registry.epEnabled = config.AddEntryPointsLabels - registry.entryPointReqsCounter = statsdClient.NewCounter(statsdEntryPointReqsName, 1.0) + registry.entryPointReqsCounter = NewCounterWithNoopHeaders(statsdClient.NewCounter(statsdEntryPointReqsName, 1.0)) registry.entryPointReqsTLSCounter = statsdClient.NewCounter(statsdEntryPointReqsTLSName, 1.0) registry.entryPointReqDurationHistogram, _ = NewHistogramWithScale(statsdClient.NewTiming(statsdEntryPointReqDurationName, 1.0), time.Millisecond) - registry.entryPointOpenConnsGauge = statsdClient.NewGauge(statsdEntryPointOpenConnsName) registry.entryPointReqsBytesCounter = statsdClient.NewCounter(statsdEntryPointReqsBytesName, 1.0) registry.entryPointRespsBytesCounter = statsdClient.NewCounter(statsdEntryPointRespsBytesName, 1.0) } if config.AddRoutersLabels { registry.routerEnabled = config.AddRoutersLabels - registry.routerReqsCounter = statsdClient.NewCounter(statsdRouterReqsName, 1.0) + registry.routerReqsCounter = NewCounterWithNoopHeaders(statsdClient.NewCounter(statsdRouterReqsName, 1.0)) registry.routerReqsTLSCounter = statsdClient.NewCounter(statsdRouterReqsTLSName, 1.0) registry.routerReqDurationHistogram, _ = NewHistogramWithScale(statsdClient.NewTiming(statsdRouterReqsDurationName, 1.0), time.Millisecond) - registry.routerOpenConnsGauge = statsdClient.NewGauge(statsdRouterOpenConnsName) registry.routerReqsBytesCounter = statsdClient.NewCounter(statsdRouterReqsBytesName, 1.0) registry.routerRespsBytesCounter = statsdClient.NewCounter(statsdRouterRespsBytesName, 1.0) } if config.AddServicesLabels { registry.svcEnabled = config.AddServicesLabels - registry.serviceReqsCounter = statsdClient.NewCounter(statsdServiceReqsName, 1.0) + registry.serviceReqsCounter = NewCounterWithNoopHeaders(statsdClient.NewCounter(statsdServiceReqsName, 1.0)) registry.serviceReqsTLSCounter = statsdClient.NewCounter(statsdServiceReqsTLSName, 1.0) registry.serviceReqDurationHistogram, _ = NewHistogramWithScale(statsdClient.NewTiming(statsdServiceReqsDurationName, 1.0), time.Millisecond) registry.serviceRetriesCounter = statsdClient.NewCounter(statsdServiceRetriesTotalName, 1.0) - registry.serviceOpenConnsGauge = statsdClient.NewGauge(statsdServiceOpenConnsName) registry.serviceServerUpGauge = statsdClient.NewGauge(statsdServiceServerUpName) registry.serviceReqsBytesCounter = statsdClient.NewCounter(statsdServiceReqsBytesName, 1.0) registry.serviceRespsBytesCounter = statsdClient.NewCounter(statsdServiceRespsBytesName, 1.0) diff --git a/pkg/metrics/statsd_test.go b/pkg/metrics/statsd_test.go index 3eb8e4705c42245a9237485696cec45f39915a0a..174081db4896376aabe6539b05f3d616958c319e 100644 --- a/pkg/metrics/statsd_test.go +++ b/pkg/metrics/statsd_test.go @@ -9,7 +9,7 @@ import ( "github.com/stvp/go-udp-testing" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/types" ) func TestStatsD(t *testing.T) { @@ -49,30 +49,26 @@ func testRegistry(t *testing.T, metricsPrefix string, registry Registry) { expected := []string{ metricsPrefix + ".config.reload.total:1.000000|c\n", - metricsPrefix + ".config.reload.total.failure:1.000000|c\n", metricsPrefix + ".config.reload.lastSuccessTimestamp:1.000000|g\n", - metricsPrefix + ".config.reload.lastFailureTimestamp:1.000000|g\n", + metricsPrefix + ".open.connections:1.000000|g\n", metricsPrefix + ".tls.certs.notAfterTimestamp:1.000000|g\n", metricsPrefix + ".entrypoint.request.total:1.000000|c\n", metricsPrefix + ".entrypoint.request.tls.total:1.000000|c\n", metricsPrefix + ".entrypoint.request.duration:10000.000000|ms", - metricsPrefix + ".entrypoint.connections.open:1.000000|g\n", metricsPrefix + ".entrypoint.requests.bytes.total:1.000000|c\n", metricsPrefix + ".entrypoint.responses.bytes.total:1.000000|c\n", metricsPrefix + ".router.request.total:2.000000|c\n", metricsPrefix + ".router.request.tls.total:1.000000|c\n", metricsPrefix + ".router.request.duration:10000.000000|ms", - metricsPrefix + ".router.connections.open:1.000000|g\n", metricsPrefix + ".router.requests.bytes.total:1.000000|c\n", metricsPrefix + ".router.responses.bytes.total:1.000000|c\n", metricsPrefix + ".service.request.total:2.000000|c\n", metricsPrefix + ".service.request.tls.total:1.000000|c\n", metricsPrefix + ".service.request.duration:10000.000000|ms", - metricsPrefix + ".service.connections.open:1.000000|g\n", metricsPrefix + ".service.retries.total:2.000000|c\n", metricsPrefix + ".service.server.up:1.000000|g\n", metricsPrefix + ".service.requests.bytes.total:1.000000|c\n", @@ -81,32 +77,28 @@ func testRegistry(t *testing.T, metricsPrefix string, registry Registry) { udp.ShouldReceiveAll(t, expected, func() { registry.ConfigReloadsCounter().Add(1) - registry.ConfigReloadsFailureCounter().Add(1) registry.LastConfigReloadSuccessGauge().Set(1) - registry.LastConfigReloadFailureGauge().Set(1) + registry.OpenConnectionsGauge().With("entrypoint", "test", "protocol", "TCP").Set(1) registry.TLSCertsNotAfterTimestampGauge().With("key", "value").Set(1) - registry.EntryPointReqsCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + registry.EntryPointReqsCounter().With(nil, "entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) registry.EntryPointReqsTLSCounter().With("entrypoint", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) registry.EntryPointReqDurationHistogram().With("entrypoint", "test").Observe(10000) - registry.EntryPointOpenConnsGauge().With("entrypoint", "test").Set(1) registry.EntryPointReqsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) registry.EntryPointRespsBytesCounter().With("entrypoint", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - registry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) - registry.RouterReqsCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + registry.RouterReqsCounter().With(nil, "router", "demo", "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) + registry.RouterReqsCounter().With(nil, "router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) registry.RouterReqsTLSCounter().With("router", "demo", "service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) registry.RouterReqDurationHistogram().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - registry.RouterOpenConnsGauge().With("router", "demo", "service", "test").Set(1) registry.RouterReqsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) registry.RouterRespsBytesCounter().With("router", "demo", "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - registry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) - registry.ServiceReqsCounter().With("service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) + registry.ServiceReqsCounter().With(nil, "service", "test", "code", strconv.Itoa(http.StatusOK), "method", http.MethodGet).Add(1) + registry.ServiceReqsCounter().With(nil, "service", "test", "code", strconv.Itoa(http.StatusNotFound), "method", http.MethodGet).Add(1) registry.ServiceReqsTLSCounter().With("service", "test", "tls_version", "foo", "tls_cipher", "bar").Add(1) registry.ServiceReqDurationHistogram().With("service", "test", "code", strconv.Itoa(http.StatusOK)).Observe(10000) - registry.ServiceOpenConnsGauge().With("service", "test").Set(1) registry.ServiceRetriesCounter().With("service", "test").Add(1) registry.ServiceRetriesCounter().With("service", "test").Add(1) registry.ServiceServerUpGauge().With("service:test", "url", "http://127.0.0.1").Set(1) diff --git a/pkg/middlewares/accesslog/field_middleware.go b/pkg/middlewares/accesslog/field_middleware.go index a7a63f683449aa2ff4e7046ad06aa93ebb42a21d..81f8cf606f9cb1bcfc87749bebc81130b4850186 100644 --- a/pkg/middlewares/accesslog/field_middleware.go +++ b/pkg/middlewares/accesslog/field_middleware.go @@ -5,8 +5,8 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/middlewares/capture" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/middlewares/capture" "github.com/vulcand/oxy/v2/utils" ) diff --git a/pkg/middlewares/accesslog/logger.go b/pkg/middlewares/accesslog/logger.go index 5c5b95dadf6d13e239a6d191af219d1b95522c39..20ee4659fa9c91ba0fa9529146797c81d2f3ca26 100644 --- a/pkg/middlewares/accesslog/logger.go +++ b/pkg/middlewares/accesslog/logger.go @@ -19,10 +19,10 @@ import ( "github.com/rs/zerolog/log" "github.com/sirupsen/logrus" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/middlewares/capture" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/middlewares/capture" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" ) type key string diff --git a/pkg/middlewares/accesslog/logger_test.go b/pkg/middlewares/accesslog/logger_test.go index 967070b7d703efbdab7120bda0977228616cacd2..0f3c63607575aa9f946675473a5fa83faf3ccae1 100644 --- a/pkg/middlewares/accesslog/logger_test.go +++ b/pkg/middlewares/accesslog/logger_test.go @@ -22,8 +22,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/middlewares/capture" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/middlewares/capture" + "github.com/traefik/traefik/v3/pkg/types" ) var ( diff --git a/pkg/middlewares/addprefix/add_prefix.go b/pkg/middlewares/addprefix/add_prefix.go index 83c4b0648eb9f1c4d5dad35bf1a72c169a79676a..4363da9b9a87b46457f91f46a35881631b24ebcb 100644 --- a/pkg/middlewares/addprefix/add_prefix.go +++ b/pkg/middlewares/addprefix/add_prefix.go @@ -6,9 +6,9 @@ import ( "net/http" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" ) const ( diff --git a/pkg/middlewares/addprefix/add_prefix_test.go b/pkg/middlewares/addprefix/add_prefix_test.go index 9ec4df5fa96b6436434d465727e133abfaded48b..b7bbeb697e39b083feb0960bb3098c1f11ee17a6 100644 --- a/pkg/middlewares/addprefix/add_prefix_test.go +++ b/pkg/middlewares/addprefix/add_prefix_test.go @@ -7,8 +7,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) func TestNewAddPrefix(t *testing.T) { diff --git a/pkg/middlewares/auth/basic_auth.go b/pkg/middlewares/auth/basic_auth.go index b67eaf643a289112ee320aa1fa5674dc383c2d06..70e25d3a12ad12ff1935952234219bf2747dec9b 100644 --- a/pkg/middlewares/auth/basic_auth.go +++ b/pkg/middlewares/auth/basic_auth.go @@ -9,10 +9,10 @@ import ( goauth "github.com/abbot/go-http-auth" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/middlewares/accesslog" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares/accesslog" + "github.com/traefik/traefik/v3/pkg/tracing" ) const ( diff --git a/pkg/middlewares/auth/basic_auth_test.go b/pkg/middlewares/auth/basic_auth_test.go index 9e1b92ad1381c86f1af5aafcb60843958c1380bd..4da9edcaea71eec2d32bfe1b4aa049f7dc0e7138 100644 --- a/pkg/middlewares/auth/basic_auth_test.go +++ b/pkg/middlewares/auth/basic_auth_test.go @@ -11,8 +11,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) func TestBasicAuthFail(t *testing.T) { diff --git a/pkg/middlewares/auth/digest_auth.go b/pkg/middlewares/auth/digest_auth.go index 214e968ee76e1c0106e1aa8d94506eac30cce4a5..ea772aeb5a918a9868fb008c569bfeac7e1a69df 100644 --- a/pkg/middlewares/auth/digest_auth.go +++ b/pkg/middlewares/auth/digest_auth.go @@ -9,10 +9,10 @@ import ( goauth "github.com/abbot/go-http-auth" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/middlewares/accesslog" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares/accesslog" + "github.com/traefik/traefik/v3/pkg/tracing" ) const ( diff --git a/pkg/middlewares/auth/digest_auth_test.go b/pkg/middlewares/auth/digest_auth_test.go index 066f80e0f1670715a9734e1e4ce156e0a5249463..46c0b74810c11cc273212ccedee6d3f2dd01f327 100644 --- a/pkg/middlewares/auth/digest_auth_test.go +++ b/pkg/middlewares/auth/digest_auth_test.go @@ -11,8 +11,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) func TestDigestAuthError(t *testing.T) { diff --git a/pkg/middlewares/auth/forward.go b/pkg/middlewares/auth/forward.go index b6adb3cb10aed4c6febb266c300fa282a09029a7..6ad5f628fcdcc894ffd114c61328f922583746f5 100644 --- a/pkg/middlewares/auth/forward.go +++ b/pkg/middlewares/auth/forward.go @@ -12,10 +12,10 @@ import ( "time" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/middlewares/connectionheader" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares/connectionheader" + "github.com/traefik/traefik/v3/pkg/tracing" "github.com/vulcand/oxy/v2/forward" "github.com/vulcand/oxy/v2/utils" ) diff --git a/pkg/middlewares/auth/forward_test.go b/pkg/middlewares/auth/forward_test.go index 4e17f7ff5df74705673e842f5824648e3685a742..0f300fc71e3a44d9782d4c5d0df372f3fdbb8062 100644 --- a/pkg/middlewares/auth/forward_test.go +++ b/pkg/middlewares/auth/forward_test.go @@ -12,10 +12,10 @@ import ( "github.com/opentracing/opentracing-go/mocktracer" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - tracingMiddleware "github.com/traefik/traefik/v2/pkg/middlewares/tracing" - "github.com/traefik/traefik/v2/pkg/testhelpers" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + tracingMiddleware "github.com/traefik/traefik/v3/pkg/middlewares/tracing" + "github.com/traefik/traefik/v3/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/tracing" "github.com/vulcand/oxy/v2/forward" ) diff --git a/pkg/middlewares/buffering/buffering.go b/pkg/middlewares/buffering/buffering.go index 300052460654c8e8283352e12024bfa3e111eaa1..6aa2ed562d12a039a72b69cd6d57f674849e890d 100644 --- a/pkg/middlewares/buffering/buffering.go +++ b/pkg/middlewares/buffering/buffering.go @@ -6,10 +6,10 @@ import ( "github.com/opentracing/opentracing-go/ext" "github.com/rs/zerolog" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" oxybuffer "github.com/vulcand/oxy/v2/buffer" ) diff --git a/pkg/middlewares/buffering/buffering_test.go b/pkg/middlewares/buffering/buffering_test.go index 22477785a5c68f1f10c7ff5974b953df77cc098a..3d40aee5fca91ee91a93512e2df3b54a7ddc94d7 100644 --- a/pkg/middlewares/buffering/buffering_test.go +++ b/pkg/middlewares/buffering/buffering_test.go @@ -3,20 +3,20 @@ package buffering import ( "bytes" "context" + "crypto/rand" "math" - "math/rand" "net/http" "net/http/httptest" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestBuffering(t *testing.T) { payload := make([]byte, math.MaxInt8) - rand.Read(payload) + _, _ = rand.Read(payload) testCases := []struct { desc string diff --git a/pkg/middlewares/capture/capture.go b/pkg/middlewares/capture/capture.go index 3608945b82ce0ed5747c84cbc249d1daed8a00ac..b7e1821170b5d1de569d1815ecdd714703b28a66 100644 --- a/pkg/middlewares/capture/capture.go +++ b/pkg/middlewares/capture/capture.go @@ -32,7 +32,7 @@ import ( "net" "net/http" - "github.com/traefik/traefik/v2/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares" ) type key string diff --git a/pkg/middlewares/capture/capture_test.go b/pkg/middlewares/capture/capture_test.go index 7705aa6b61dac611dd9c1bdd9762097499618257..b3cfff1deea6c51905004ebc75a4710accf74ce1 100644 --- a/pkg/middlewares/capture/capture_test.go +++ b/pkg/middlewares/capture/capture_test.go @@ -58,7 +58,7 @@ func TestCapture(t *testing.T) { // $ go test -bench=. ./pkg/middlewares/capture/ // goos: linux // goarch: amd64 -// pkg: github.com/traefik/traefik/v2/pkg/middlewares/capture +// pkg: github.com/traefik/traefik/v3/pkg/middlewares/capture // cpu: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz // BenchmarkCapture/2k-12 280507 4015 ns/op 510.03 MB/s 5072 B/op 14 allocs/op // BenchmarkCapture/20k-12 135726 8301 ns/op 2467.26 MB/s 41936 B/op 14 allocs/op diff --git a/pkg/middlewares/chain/chain.go b/pkg/middlewares/chain/chain.go index e5fd9aa93c3af6cb4c0e83ef57bf2bbca2c137bf..d87596b429c89b4a09f98d8e63b3c57f5863b065 100644 --- a/pkg/middlewares/chain/chain.go +++ b/pkg/middlewares/chain/chain.go @@ -5,8 +5,8 @@ import ( "net/http" "github.com/containous/alice" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" ) const ( diff --git a/pkg/middlewares/circuitbreaker/circuit_breaker.go b/pkg/middlewares/circuitbreaker/circuit_breaker.go index 8e3f3339b0d4158cf4bc2a631b1945478216c0f4..8445b45b811965275228f7bd18f413fd93c95519 100644 --- a/pkg/middlewares/circuitbreaker/circuit_breaker.go +++ b/pkg/middlewares/circuitbreaker/circuit_breaker.go @@ -8,10 +8,10 @@ import ( "github.com/opentracing/opentracing-go/ext" "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" "github.com/vulcand/oxy/v2/cbreaker" ) diff --git a/pkg/middlewares/compress/compress.go b/pkg/middlewares/compress/compress.go index 4db054d6567132d802a7a0e6b652bf0816c7390c..ab9bdc71b13ab998252856ee1f2d3126bf7abade 100644 --- a/pkg/middlewares/compress/compress.go +++ b/pkg/middlewares/compress/compress.go @@ -9,10 +9,10 @@ import ( "github.com/klauspost/compress/gzhttp" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/middlewares/compress/brotli" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares/compress/brotli" + "github.com/traefik/traefik/v3/pkg/tracing" ) const typeName = "Compress" diff --git a/pkg/middlewares/compress/compress_test.go b/pkg/middlewares/compress/compress_test.go index b3eb0e03c05001af2ea70aaaf2f6f6b0981491c2..fb7f95a69001c10f7ab734d2433b8d20c086105f 100644 --- a/pkg/middlewares/compress/compress_test.go +++ b/pkg/middlewares/compress/compress_test.go @@ -12,8 +12,8 @@ import ( "github.com/klauspost/compress/gzhttp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) const ( @@ -173,6 +173,60 @@ func TestShouldCompressWhenNoAcceptEncodingHeader(t *testing.T) { assert.Equal(t, got, fakeBody) } +func TestShouldNotCompressWhenIdentityAcceptEncodingHeader(t *testing.T) { + req := testhelpers.MustNewRequest(http.MethodGet, "http://localhost", nil) + req.Header.Set(acceptEncodingHeader, "identity") + + fakeBody := generateBytes(gzhttp.DefaultMinSize) + next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + if r.Header.Get(acceptEncodingHeader) != "identity" { + http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + + _, err := rw.Write(fakeBody) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + } + }) + handler, err := New(context.Background(), next, dynamic.Compress{}, "testing") + require.NoError(t, err) + + rw := httptest.NewRecorder() + handler.ServeHTTP(rw, req) + + assert.Empty(t, rw.Header().Get(contentEncodingHeader)) + assert.Empty(t, rw.Header().Get(varyHeader)) + assert.EqualValues(t, rw.Body.Bytes(), fakeBody) +} + +func TestShouldNotCompressWhenEmptyAcceptEncodingHeader(t *testing.T) { + req := testhelpers.MustNewRequest(http.MethodGet, "http://localhost", nil) + req.Header.Set(acceptEncodingHeader, "") + + fakeBody := generateBytes(gzhttp.DefaultMinSize) + next := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { + if r.Header.Get(acceptEncodingHeader) != "" { + http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) + return + } + + _, err := rw.Write(fakeBody) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + } + }) + handler, err := New(context.Background(), next, dynamic.Compress{}, "testing") + require.NoError(t, err) + + rw := httptest.NewRecorder() + handler.ServeHTTP(rw, req) + + assert.Empty(t, rw.Header().Get(contentEncodingHeader)) + assert.Empty(t, rw.Header().Get(varyHeader)) + assert.EqualValues(t, rw.Body.Bytes(), fakeBody) +} + func TestShouldNotCompressHeadRequest(t *testing.T) { req := testhelpers.MustNewRequest(http.MethodHead, "http://localhost", nil) req.Header.Add(acceptEncodingHeader, gzipValue) diff --git a/pkg/middlewares/contenttype/content_type.go b/pkg/middlewares/contenttype/content_type.go index bfe5a5c4822b55a6fb2a04e2d6c1f48c259841cd..763f7587e19bca5f0c8b19568e1ad2a53348734a 100644 --- a/pkg/middlewares/contenttype/content_type.go +++ b/pkg/middlewares/contenttype/content_type.go @@ -4,7 +4,7 @@ import ( "context" "net/http" - "github.com/traefik/traefik/v2/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares" ) const ( diff --git a/pkg/middlewares/contenttype/content_type_test.go b/pkg/middlewares/contenttype/content_type_test.go index f134994c0542103990d8272f269bfdd98a7aafbd..24facb0d2bc7f42326b907f1b2e6d09b8c7d07c9 100644 --- a/pkg/middlewares/contenttype/content_type_test.go +++ b/pkg/middlewares/contenttype/content_type_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) func TestAutoDetection(t *testing.T) { diff --git a/pkg/middlewares/customerrors/custom_errors.go b/pkg/middlewares/customerrors/custom_errors.go index 55684f82ec161f0a475811a3236c9a78254a0883..945552456038fb90d692b9c2ff2209708fb76cfa 100644 --- a/pkg/middlewares/customerrors/custom_errors.go +++ b/pkg/middlewares/customerrors/custom_errors.go @@ -11,10 +11,10 @@ import ( "strings" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/types" "github.com/vulcand/oxy/v2/utils" ) @@ -209,6 +209,15 @@ func (cc *codeCatcher) Flush() { // Otherwise, cc.code is actually a 200 here. cc.WriteHeader(cc.code) + // We don't care about the contents of the response, + // since we want to serve the ones from the error page, + // so we just don't flush. + // (e.g., To prevent superfluous WriteHeader on request with a + // `Transfert-Encoding: chunked` header). + if cc.caughtFilteredCode { + return + } + if flusher, ok := cc.responseWriter.(http.Flusher); ok { flusher.Flush() } diff --git a/pkg/middlewares/customerrors/custom_errors_test.go b/pkg/middlewares/customerrors/custom_errors_test.go index c0de064c7b64c58317ad3d885f87d0425cc9ca06..e066be29ab07fac08777034b1c1f677037cea907 100644 --- a/pkg/middlewares/customerrors/custom_errors_test.go +++ b/pkg/middlewares/customerrors/custom_errors_test.go @@ -9,8 +9,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) func TestHandler(t *testing.T) { diff --git a/pkg/middlewares/extractor.go b/pkg/middlewares/extractor.go index 6766132c96a6e4325b35031ec1017daebdb0c248..9fca2a1cea25b5403689f02a3043946994552944 100644 --- a/pkg/middlewares/extractor.go +++ b/pkg/middlewares/extractor.go @@ -7,7 +7,7 @@ import ( "net/http" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/vulcand/oxy/v2/utils" ) diff --git a/pkg/middlewares/forwardedheaders/forwarded_header.go b/pkg/middlewares/forwardedheaders/forwarded_header.go index 19881ad748f2a824e4f5b1e59ab7f66b8e71e57b..3f4e32301a4612b7a8f9481024db50e947decd8d 100644 --- a/pkg/middlewares/forwardedheaders/forwarded_header.go +++ b/pkg/middlewares/forwardedheaders/forwarded_header.go @@ -6,7 +6,7 @@ import ( "os" "strings" - "github.com/traefik/traefik/v2/pkg/ip" + "github.com/traefik/traefik/v3/pkg/ip" ) const ( diff --git a/pkg/middlewares/grpcweb/grpcweb.go b/pkg/middlewares/grpcweb/grpcweb.go index e0813fed9c72d71658426bbdc0b5bc3bbc313a0b..896ac7148f0518aaa94a77d6460f64acb98d7091 100644 --- a/pkg/middlewares/grpcweb/grpcweb.go +++ b/pkg/middlewares/grpcweb/grpcweb.go @@ -5,8 +5,8 @@ import ( "net/http" "github.com/improbable-eng/grpc-web/go/grpcweb" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" ) const typeName = "grpc-web" diff --git a/pkg/middlewares/handler_switcher.go b/pkg/middlewares/handler_switcher.go index 7c8c775fc01d70530087f2f5e35acbdd57040cf1..d5b465b608fa5565d76bc820803593cd8ecac23a 100644 --- a/pkg/middlewares/handler_switcher.go +++ b/pkg/middlewares/handler_switcher.go @@ -3,7 +3,7 @@ package middlewares import ( "net/http" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/safe" ) // HTTPHandlerSwitcher allows hot switching of http.ServeMux. diff --git a/pkg/middlewares/headers/header.go b/pkg/middlewares/headers/header.go index 88d788bf62c1f12535f0530e7a12aa44a1a5b90f..a62fc097e69fba7d45bd822510207581b8983e82 100644 --- a/pkg/middlewares/headers/header.go +++ b/pkg/middlewares/headers/header.go @@ -7,7 +7,7 @@ import ( "strconv" "strings" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) // Header is a middleware that helps setup a few basic security features. diff --git a/pkg/middlewares/headers/header_test.go b/pkg/middlewares/headers/header_test.go index fa21fe311fc6ec1c45207143977f6d385e2c2774..269756b4655df002c78d6aca6c06f6a010f10b02 100644 --- a/pkg/middlewares/headers/header_test.go +++ b/pkg/middlewares/headers/header_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestNewHeader_customRequestHeader(t *testing.T) { diff --git a/pkg/middlewares/headers/headers.go b/pkg/middlewares/headers/headers.go index 07ad06224954d93dccde4ef9ac54ea31800869e0..1210f6711e2e0fefcdcc5212444e20ba9620c954 100644 --- a/pkg/middlewares/headers/headers.go +++ b/pkg/middlewares/headers/headers.go @@ -7,10 +7,10 @@ import ( "net/http" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/middlewares/connectionheader" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares/connectionheader" + "github.com/traefik/traefik/v3/pkg/tracing" ) const ( diff --git a/pkg/middlewares/headers/headers_test.go b/pkg/middlewares/headers/headers_test.go index efbcdb0b2ba3ebf083841e66d0a14fd61a793b38..13c6dd37734ba2faf65f8b56950c69c52f54a5c1 100644 --- a/pkg/middlewares/headers/headers_test.go +++ b/pkg/middlewares/headers/headers_test.go @@ -10,8 +10,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/tracing" ) func TestNew_withoutOptions(t *testing.T) { diff --git a/pkg/middlewares/headers/secure.go b/pkg/middlewares/headers/secure.go index e5fcd9cd4c98cc22ba152dd38fd4e8bcbd4c5d1d..99b03a489720e0c91c26e344b4daf21401b579e9 100644 --- a/pkg/middlewares/headers/secure.go +++ b/pkg/middlewares/headers/secure.go @@ -3,7 +3,7 @@ package headers import ( "net/http" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" "github.com/unrolled/secure" ) diff --git a/pkg/middlewares/headers/secure_test.go b/pkg/middlewares/headers/secure_test.go index 6ed22f1e397a0aedf1a002b14c3cb607051863ad..24e38564ecc13dbc7cbcab124661b26cd4b41f42 100644 --- a/pkg/middlewares/headers/secure_test.go +++ b/pkg/middlewares/headers/secure_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) // Middleware tests based on https://github.com/unrolled/secure diff --git a/pkg/middlewares/inflightreq/inflight_req.go b/pkg/middlewares/inflightreq/inflight_req.go index c34982befc9821838a92e181c1b0bc9dae175a7b..a6fcdf101a760dd041cb6b56616619be0a0bfe90 100644 --- a/pkg/middlewares/inflightreq/inflight_req.go +++ b/pkg/middlewares/inflightreq/inflight_req.go @@ -7,10 +7,10 @@ import ( "github.com/opentracing/opentracing-go/ext" "github.com/rs/zerolog" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" "github.com/vulcand/oxy/v2/connlimit" ) diff --git a/pkg/middlewares/ipallowlist/ip_allowlist.go b/pkg/middlewares/ipallowlist/ip_allowlist.go index b9ddaf94b9bbc06d64f7ef7a84890de756d98f03..e888d5d92ff5141de7fd3b54b6469718eda3e3d2 100644 --- a/pkg/middlewares/ipallowlist/ip_allowlist.go +++ b/pkg/middlewares/ipallowlist/ip_allowlist.go @@ -8,10 +8,10 @@ import ( "github.com/opentracing/opentracing-go/ext" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/ip" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/ip" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" ) const ( diff --git a/pkg/middlewares/ipallowlist/ip_allowlist_test.go b/pkg/middlewares/ipallowlist/ip_allowlist_test.go index df2e49835a6c4cef5b83dc5f775a8dd028843510..8bd26b3eb5c10642ee03ff9acfdd1b9238339e6b 100644 --- a/pkg/middlewares/ipallowlist/ip_allowlist_test.go +++ b/pkg/middlewares/ipallowlist/ip_allowlist_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestNewIPAllowLister(t *testing.T) { diff --git a/pkg/middlewares/metrics/metrics.go b/pkg/middlewares/metrics/metrics.go index b04a49c85d81b8ad77bbd4f3dc0d14898e4ab58c..64a09db17113748dab6c1bb7325fb50d94d123d5 100644 --- a/pkg/middlewares/metrics/metrics.go +++ b/pkg/middlewares/metrics/metrics.go @@ -11,11 +11,11 @@ import ( "github.com/containous/alice" gokitmetrics "github.com/go-kit/kit/metrics" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/metrics" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/middlewares/capture" - "github.com/traefik/traefik/v2/pkg/middlewares/retry" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares/capture" + "github.com/traefik/traefik/v3/pkg/middlewares/retry" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" "google.golang.org/grpc/codes" ) @@ -33,10 +33,9 @@ const ( type metricsMiddleware struct { next http.Handler - reqsCounter gokitmetrics.Counter + reqsCounter metrics.CounterWithHeaders reqsTLSCounter gokitmetrics.Counter reqDurationHistogram metrics.ScalableHistogram - openConnsGauge gokitmetrics.Gauge reqsBytesCounter gokitmetrics.Counter respsBytesCounter gokitmetrics.Counter baseLabels []string @@ -51,7 +50,6 @@ func NewEntryPointMiddleware(ctx context.Context, next http.Handler, registry me reqsCounter: registry.EntryPointReqsCounter(), reqsTLSCounter: registry.EntryPointReqsTLSCounter(), reqDurationHistogram: registry.EntryPointReqDurationHistogram(), - openConnsGauge: registry.EntryPointOpenConnsGauge(), reqsBytesCounter: registry.EntryPointReqsBytesCounter(), respsBytesCounter: registry.EntryPointRespsBytesCounter(), baseLabels: []string{"entrypoint", entryPointName}, @@ -67,7 +65,6 @@ func NewRouterMiddleware(ctx context.Context, next http.Handler, registry metric reqsCounter: registry.RouterReqsCounter(), reqsTLSCounter: registry.RouterReqsTLSCounter(), reqDurationHistogram: registry.RouterReqDurationHistogram(), - openConnsGauge: registry.RouterOpenConnsGauge(), reqsBytesCounter: registry.RouterReqsBytesCounter(), respsBytesCounter: registry.RouterRespsBytesCounter(), baseLabels: []string{"router", routerName, "service", serviceName}, @@ -83,7 +80,6 @@ func NewServiceMiddleware(ctx context.Context, next http.Handler, registry metri reqsCounter: registry.ServiceReqsCounter(), reqsTLSCounter: registry.ServiceReqsTLSCounter(), reqDurationHistogram: registry.ServiceReqDurationHistogram(), - openConnsGauge: registry.ServiceOpenConnsGauge(), reqsBytesCounter: registry.ServiceReqsBytesCounter(), respsBytesCounter: registry.ServiceRespsBytesCounter(), baseLabels: []string{"service", serviceName}, @@ -112,10 +108,6 @@ func (m *metricsMiddleware) ServeHTTP(rw http.ResponseWriter, req *http.Request) labels = append(labels, "method", getMethod(req)) labels = append(labels, "protocol", proto) - openConnsGauge := m.openConnsGauge.With(labels...) - openConnsGauge.Add(1) - defer openConnsGauge.Add(-1) - // TLS metrics if req.TLS != nil { var tlsLabels []string @@ -153,7 +145,7 @@ func (m *metricsMiddleware) ServeHTTP(rw http.ResponseWriter, req *http.Request) labels = append(labels, "code", strconv.Itoa(code)) m.reqDurationHistogram.With(labels...).ObserveFromStart(start) - m.reqsCounter.With(labels...).Add(1) + m.reqsCounter.With(req.Header, labels...).Add(1) m.respsBytesCounter.With(labels...).Add(float64(capt.ResponseSize())) m.reqsBytesCounter.With(labels...).Add(float64(capt.RequestSize())) } diff --git a/pkg/middlewares/middleware.go b/pkg/middlewares/middleware.go index 32aadf29a6d470d830c8fad0e7fbca80a748f57a..928a9982e65f8cc607bf0f99f208497d976c110e 100644 --- a/pkg/middlewares/middleware.go +++ b/pkg/middlewares/middleware.go @@ -5,7 +5,7 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/logs" ) // GetLogger creates a logger with the middleware fields. diff --git a/pkg/middlewares/passtlsclientcert/pass_tls_client_cert.go b/pkg/middlewares/passtlsclientcert/pass_tls_client_cert.go index 3f0f8042399cee8bc146a251581a6c2348af490a..94367ce289c6202f45482b11ca6d4d4cf6c3063d 100644 --- a/pkg/middlewares/passtlsclientcert/pass_tls_client_cert.go +++ b/pkg/middlewares/passtlsclientcert/pass_tls_client_cert.go @@ -13,9 +13,9 @@ import ( "github.com/opentracing/opentracing-go/ext" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" ) const typeName = "PassClientTLSCert" diff --git a/pkg/middlewares/passtlsclientcert/pass_tls_client_cert_test.go b/pkg/middlewares/passtlsclientcert/pass_tls_client_cert_test.go index 96c1bdffa76ce630da097dbb8c5514ed7be61386..47f6b451f0fe62c7b38a3cc9adade39d54cced02 100644 --- a/pkg/middlewares/passtlsclientcert/pass_tls_client_cert_test.go +++ b/pkg/middlewares/passtlsclientcert/pass_tls_client_cert_test.go @@ -15,8 +15,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) const ( diff --git a/pkg/middlewares/ratelimiter/rate_limiter.go b/pkg/middlewares/ratelimiter/rate_limiter.go index 303b20e8ec92c83a757f032102e7a5af01344441..1c3582c4e452d00fb1daeb2d26868f084dde4c7c 100644 --- a/pkg/middlewares/ratelimiter/rate_limiter.go +++ b/pkg/middlewares/ratelimiter/rate_limiter.go @@ -11,9 +11,9 @@ import ( "github.com/mailgun/ttlmap" "github.com/opentracing/opentracing-go/ext" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" "github.com/vulcand/oxy/v2/utils" "golang.org/x/time/rate" ) @@ -81,10 +81,12 @@ func New(ctx context.Context, next http.Handler, config dynamic.RateLimit, name period = time.Second } - // if config.Average == 0, in that case, - // the value of maxDelay does not matter since the reservation will (buggily) give us a delay of 0 anyway. + // Initialized at rate.Inf to enforce no rate limiting when config.Average == 0 + rtl := float64(rate.Inf) + // No need to set any particular value for maxDelay as the reservation's delay + // will be <= 0 in the Inf case (i.e. the average == 0 case). var maxDelay time.Duration - var rtl float64 + if config.Average > 0 { rtl = float64(config.Average*int64(time.Second)) / float64(period) // maxDelay does not scale well for rates below 1, @@ -155,10 +157,6 @@ func (rl *rateLimiter) ServeHTTP(rw http.ResponseWriter, req *http.Request) { return } - // time/rate is bugged, since a rate.Limiter with a 0 Limit not only allows a Reservation to take place, - // but also gives a 0 delay below (because of a division by zero, followed by a multiplication that flips into the negatives), - // regardless of the current load. - // However, for now we take advantage of this behavior to provide the no-limit ratelimiter when config.Average is 0. res := bucket.Reserve() if !res.OK() { http.Error(rw, "No bursty traffic allowed", http.StatusTooManyRequests) diff --git a/pkg/middlewares/ratelimiter/rate_limiter_test.go b/pkg/middlewares/ratelimiter/rate_limiter_test.go index ac73fc2eccffe75f1ba1d253687a98d3a0847c04..5187d5d635910365d62762abd9fc9cabb1ad68f9 100644 --- a/pkg/middlewares/ratelimiter/rate_limiter_test.go +++ b/pkg/middlewares/ratelimiter/rate_limiter_test.go @@ -12,9 +12,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/testhelpers" "github.com/vulcand/oxy/v2/utils" + "golang.org/x/time/rate" ) func TestNewRateLimiter(t *testing.T) { @@ -25,7 +26,16 @@ func TestNewRateLimiter(t *testing.T) { expectedSourceIP string requestHeader string expectedError string + expectedRTL rate.Limit }{ + { + desc: "no ratelimit on Average == 0", + config: dynamic.RateLimit{ + Average: 0, + Burst: 10, + }, + expectedRTL: rate.Inf, + }, { desc: "maxDelay computation", config: dynamic.RateLimit{ @@ -120,6 +130,9 @@ func TestNewRateLimiter(t *testing.T) { assert.NoError(t, err) assert.Equal(t, test.requestHeader, hd) } + if test.expectedRTL != 0 { + assert.Equal(t, test.expectedRTL, rtl.rate) + } }) } } diff --git a/pkg/middlewares/recovery/recovery.go b/pkg/middlewares/recovery/recovery.go index 90e0b3659543539499bcaf64a05f49016e0c00e8..ebd3edcb5dc93761f3a545484a1461921cae9ef6 100644 --- a/pkg/middlewares/recovery/recovery.go +++ b/pkg/middlewares/recovery/recovery.go @@ -5,7 +5,7 @@ import ( "net/http" "runtime" - "github.com/traefik/traefik/v2/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares" ) const ( diff --git a/pkg/middlewares/redirect/redirect.go b/pkg/middlewares/redirect/redirect.go index a48053f8a935129cb7ed14f5c1d7cf9f1a7b3c4f..d64d8cd70e3ac0a5605ec0275e96b8e3e8cd0048 100644 --- a/pkg/middlewares/redirect/redirect.go +++ b/pkg/middlewares/redirect/redirect.go @@ -6,7 +6,7 @@ import ( "regexp" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/tracing" "github.com/vulcand/oxy/v2/utils" ) diff --git a/pkg/middlewares/redirect/redirect_regex.go b/pkg/middlewares/redirect/redirect_regex.go index 62e5dc98662f2746543a2911d3d531b757fdfe01..f684932052ec86ce1ce33734fcb6e064eb3b542e 100644 --- a/pkg/middlewares/redirect/redirect_regex.go +++ b/pkg/middlewares/redirect/redirect_regex.go @@ -5,8 +5,8 @@ import ( "net/http" "strings" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" ) const typeRegexName = "RedirectRegex" diff --git a/pkg/middlewares/redirect/redirect_regex_test.go b/pkg/middlewares/redirect/redirect_regex_test.go index d6346cf75e1b52012409d93b8f885f86ca5a6c56..a93c7884427ad836ac6da8fb826b3a3ae3b6abb2 100644 --- a/pkg/middlewares/redirect/redirect_regex_test.go +++ b/pkg/middlewares/redirect/redirect_regex_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestRedirectRegexHandler(t *testing.T) { diff --git a/pkg/middlewares/redirect/redirect_scheme.go b/pkg/middlewares/redirect/redirect_scheme.go index b828ff287bb207ebbb0fcce12549f1c82bf04060..b0d8146c7db42ea7f1c3a50b6d6385ab9bfcccef 100644 --- a/pkg/middlewares/redirect/redirect_scheme.go +++ b/pkg/middlewares/redirect/redirect_scheme.go @@ -7,8 +7,8 @@ import ( "net/http" "strings" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" ) const ( @@ -17,6 +17,12 @@ const ( xForwardedProto = "X-Forwarded-Proto" ) +type redirectScheme struct { + http.Handler + + name string +} + // NewRedirectScheme creates a new RedirectScheme middleware. func NewRedirectScheme(ctx context.Context, next http.Handler, conf dynamic.RedirectScheme, name string) (http.Handler, error) { logger := middlewares.GetLogger(ctx, name, typeSchemeName) @@ -32,10 +38,19 @@ func NewRedirectScheme(ctx context.Context, next http.Handler, conf dynamic.Redi port = ":" + conf.Port } - return newRedirect(next, uriPattern, conf.Scheme+"://${2}"+port+"${4}", conf.Permanent, clientRequestURL, name) + rs := &redirectScheme{name: name} + + handler, err := newRedirect(next, uriPattern, conf.Scheme+"://${2}"+port+"${4}", conf.Permanent, rs.clientRequestURL, name) + if err != nil { + return nil, err + } + + rs.Handler = handler + + return rs, nil } -func clientRequestURL(req *http.Request) string { +func (r *redirectScheme) clientRequestURL(req *http.Request) string { scheme := schemeHTTP host, port, err := net.SplitHostPort(req.Host) if err != nil { @@ -70,12 +85,12 @@ func clientRequestURL(req *http.Request) string { // Given that we're in a middleware that is only used in the context of HTTP(s) requests, // the only possible valid schemes are one of "http" or "https", so we convert back to them. switch { - case strings.EqualFold(xProto, "ws"): + case strings.EqualFold(xProto, schemeHTTP), strings.EqualFold(xProto, "ws"): scheme = schemeHTTP - case strings.EqualFold(xProto, "wss"): + case strings.EqualFold(xProto, schemeHTTPS), strings.EqualFold(xProto, "wss"): scheme = schemeHTTPS default: - scheme = xProto + middlewares.GetLogger(req.Context(), r.name, typeSchemeName).Debug().Msgf("Invalid X-Forwarded-Proto: %s", xProto) } } diff --git a/pkg/middlewares/redirect/redirect_scheme_test.go b/pkg/middlewares/redirect/redirect_scheme_test.go index dea1d6265e64ab2e753dcd67a87fc177186bf9d8..7ef53f252728557c70e7a599e0f4b4dc57089342 100644 --- a/pkg/middlewares/redirect/redirect_scheme_test.go +++ b/pkg/middlewares/redirect/redirect_scheme_test.go @@ -10,7 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestRedirectSchemeHandler(t *testing.T) { @@ -72,7 +72,7 @@ func TestRedirectSchemeHandler(t *testing.T) { headers: map[string]string{ "X-Forwarded-Proto": "bar", }, - expectedURL: "https://bar://foo", + expectedURL: "https://foo", expectedStatus: http.StatusFound, }, { diff --git a/pkg/middlewares/replacepath/replace_path.go b/pkg/middlewares/replacepath/replace_path.go index e1936105643445ca9af650282a9a86c8585666d5..9f6fea4431132f29667f6291241bc1eda1171410 100644 --- a/pkg/middlewares/replacepath/replace_path.go +++ b/pkg/middlewares/replacepath/replace_path.go @@ -6,9 +6,9 @@ import ( "net/url" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" ) const ( diff --git a/pkg/middlewares/replacepath/replace_path_test.go b/pkg/middlewares/replacepath/replace_path_test.go index 782733bc09b0d5df08907339a7becf449a61b4b2..5998579d1ec5487fcbe9fc513454868b4bdc902f 100644 --- a/pkg/middlewares/replacepath/replace_path_test.go +++ b/pkg/middlewares/replacepath/replace_path_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestReplacePath(t *testing.T) { diff --git a/pkg/middlewares/replacepathregex/replace_path_regex.go b/pkg/middlewares/replacepathregex/replace_path_regex.go index 2f2621b8c662c5422f3a3253a146fb75a6b1d76f..1fffb6bd475c3e38c90fced0f8ffe3b530fcdef0 100644 --- a/pkg/middlewares/replacepathregex/replace_path_regex.go +++ b/pkg/middlewares/replacepathregex/replace_path_regex.go @@ -9,10 +9,10 @@ import ( "strings" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/middlewares/replacepath" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares/replacepath" + "github.com/traefik/traefik/v3/pkg/tracing" ) const typeName = "ReplacePathRegex" diff --git a/pkg/middlewares/replacepathregex/replace_path_regex_test.go b/pkg/middlewares/replacepathregex/replace_path_regex_test.go index 59018d784129ec9611e684303e9102fa594c5a2a..7e83f386241d8517994bda52e816f5e04b5942d0 100644 --- a/pkg/middlewares/replacepathregex/replace_path_regex_test.go +++ b/pkg/middlewares/replacepathregex/replace_path_regex_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares/replacepath" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares/replacepath" ) func TestReplacePathRegex(t *testing.T) { diff --git a/pkg/middlewares/requestdecorator/request_decorator.go b/pkg/middlewares/requestdecorator/request_decorator.go index 013cb12c3875f350efc824d85d87b3ddcc0e5757..e2a82395caa101e993566388e41ccad5e5dd0174 100644 --- a/pkg/middlewares/requestdecorator/request_decorator.go +++ b/pkg/middlewares/requestdecorator/request_decorator.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/containous/alice" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/types" ) const ( diff --git a/pkg/middlewares/requestdecorator/request_decorator_test.go b/pkg/middlewares/requestdecorator/request_decorator_test.go index 03c8f401892e62ad02522cead023491b4247ea82..75ccc0139ee4fd58829c6d5225d99ae5b1e013bc 100644 --- a/pkg/middlewares/requestdecorator/request_decorator_test.go +++ b/pkg/middlewares/requestdecorator/request_decorator_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/testhelpers" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/types" ) func TestRequestHost(t *testing.T) { diff --git a/pkg/middlewares/retry/retry.go b/pkg/middlewares/retry/retry.go index b9f3b6af780765f5c67329ea5148f564fc97cfdf..310164bd33d15949046a3fb37b27c7759142e12d 100644 --- a/pkg/middlewares/retry/retry.go +++ b/pkg/middlewares/retry/retry.go @@ -13,9 +13,9 @@ import ( "github.com/cenkalti/backoff/v4" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" ) // Compile time validation that the response writer implements http interfaces correctly. diff --git a/pkg/middlewares/retry/retry_test.go b/pkg/middlewares/retry/retry_test.go index 4622093afa454073cb7a35f6699681b40cb5d81a..a2d96b3ce3097e6ee3b7bc0dce31329ce5f5a0cc 100644 --- a/pkg/middlewares/retry/retry_test.go +++ b/pkg/middlewares/retry/retry_test.go @@ -15,8 +15,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) func TestRetry(t *testing.T) { diff --git a/pkg/middlewares/snicheck/snicheck.go b/pkg/middlewares/snicheck/snicheck.go index 27f8148d12f1ae8e18d64b3da649b3ce4b06e6bf..89f817fcbc4b4e2e8fe50c0a79ccfff02f81954c 100644 --- a/pkg/middlewares/snicheck/snicheck.go +++ b/pkg/middlewares/snicheck/snicheck.go @@ -6,8 +6,8 @@ import ( "strings" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/middlewares/requestdecorator" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/middlewares/requestdecorator" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" ) // SNICheck is an HTTP handler that checks whether the TLS configuration for the server name is the same as for the host header. diff --git a/pkg/middlewares/stripprefix/strip_prefix.go b/pkg/middlewares/stripprefix/strip_prefix.go index 8338ee2eda97f3f14fd64c04dfaf5bb3c898b9d8..a017c051f0900106c44775dfde5777b20fc252a8 100644 --- a/pkg/middlewares/stripprefix/strip_prefix.go +++ b/pkg/middlewares/stripprefix/strip_prefix.go @@ -6,9 +6,9 @@ import ( "strings" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" ) const ( diff --git a/pkg/middlewares/stripprefix/strip_prefix_test.go b/pkg/middlewares/stripprefix/strip_prefix_test.go index 7f2717bd34d3b06687d0e3d7833b1034046e9e97..612a282f1f7391f0c1f51a40d220126bae044452 100644 --- a/pkg/middlewares/stripprefix/strip_prefix_test.go +++ b/pkg/middlewares/stripprefix/strip_prefix_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) func TestStripPrefix(t *testing.T) { diff --git a/pkg/middlewares/stripprefixregex/strip_prefix_regex.go b/pkg/middlewares/stripprefixregex/strip_prefix_regex.go index debeba16dda5a8780b4644ad2dfbf85e3b4c7195..383ce1f01ee29defd650dab682dce37c28ccfc4e 100644 --- a/pkg/middlewares/stripprefixregex/strip_prefix_regex.go +++ b/pkg/middlewares/stripprefixregex/strip_prefix_regex.go @@ -7,10 +7,10 @@ import ( "strings" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/middlewares/stripprefix" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares/stripprefix" + "github.com/traefik/traefik/v3/pkg/tracing" ) const ( diff --git a/pkg/middlewares/stripprefixregex/strip_prefix_regex_test.go b/pkg/middlewares/stripprefixregex/strip_prefix_regex_test.go index 763985ba941d2db6d36ada5a9b09eab85c88693c..64db6b8421df142b7647fe1488366312e8461ced 100644 --- a/pkg/middlewares/stripprefixregex/strip_prefix_regex_test.go +++ b/pkg/middlewares/stripprefixregex/strip_prefix_regex_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares/stripprefix" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares/stripprefix" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) func TestStripPrefixRegex(t *testing.T) { diff --git a/pkg/middlewares/tcp/inflightconn/inflight_conn.go b/pkg/middlewares/tcp/inflightconn/inflight_conn.go index 6213d4e426c1438517caec5f2b48f153f1fd6163..b8663efc59ffcf588e1f5b9f768a1a33c03b0e4b 100644 --- a/pkg/middlewares/tcp/inflightconn/inflight_conn.go +++ b/pkg/middlewares/tcp/inflightconn/inflight_conn.go @@ -6,9 +6,9 @@ import ( "net" "sync" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tcp" ) const typeName = "InFlightConnTCP" diff --git a/pkg/middlewares/tcp/inflightconn/inflight_conn_test.go b/pkg/middlewares/tcp/inflightconn/inflight_conn_test.go index 138e92b41348f930b1cd383365a3a4050d993d28..28fca80df236b2477239ac15f6fc5b963484e484 100644 --- a/pkg/middlewares/tcp/inflightconn/inflight_conn_test.go +++ b/pkg/middlewares/tcp/inflightconn/inflight_conn_test.go @@ -7,8 +7,8 @@ import ( "time" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/tcp" ) func TestInFlightConn_ServeTCP(t *testing.T) { diff --git a/pkg/middlewares/tcp/ipallowlist/ip_allowlist.go b/pkg/middlewares/tcp/ipallowlist/ip_allowlist.go index e2a513cf0574cd3b9ea09a84051396515b406f78..0ebe2fab7ad35ad39cde1cf972d61eefdcfdc064 100644 --- a/pkg/middlewares/tcp/ipallowlist/ip_allowlist.go +++ b/pkg/middlewares/tcp/ipallowlist/ip_allowlist.go @@ -5,10 +5,10 @@ import ( "errors" "fmt" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/ip" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/ip" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tcp" ) const ( diff --git a/pkg/middlewares/tcp/ipallowlist/ip_allowlist_test.go b/pkg/middlewares/tcp/ipallowlist/ip_allowlist_test.go index 4f3b59e15b390828ecd1b113b7e03ff1acc39571..8da65c1ad67533d1a9533347feb081614d0998a9 100644 --- a/pkg/middlewares/tcp/ipallowlist/ip_allowlist_test.go +++ b/pkg/middlewares/tcp/ipallowlist/ip_allowlist_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/tcp" ) func TestNewIPAllowLister(t *testing.T) { diff --git a/pkg/middlewares/tracing/entrypoint.go b/pkg/middlewares/tracing/entrypoint.go index d665823a22cfddfa96eff09a9411a3e055c5f7dd..b17d8c2ce294cf10efbf5b20ebf87fb8a7ca70aa 100644 --- a/pkg/middlewares/tracing/entrypoint.go +++ b/pkg/middlewares/tracing/entrypoint.go @@ -7,8 +7,8 @@ import ( "github.com/containous/alice" "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" ) const ( diff --git a/pkg/middlewares/tracing/entrypoint_test.go b/pkg/middlewares/tracing/entrypoint_test.go index 604c8c012e6295ede2b6980d01e1b58ee155b5b3..e8528e048410e68c80bfcdb26acb298267c035b0 100644 --- a/pkg/middlewares/tracing/entrypoint_test.go +++ b/pkg/middlewares/tracing/entrypoint_test.go @@ -9,7 +9,7 @@ import ( "github.com/opentracing/opentracing-go/ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/tracing" ) func TestEntryPointMiddleware(t *testing.T) { diff --git a/pkg/middlewares/tracing/forwarder.go b/pkg/middlewares/tracing/forwarder.go index 2ebf5fe779f28f8beefb6ae79077c524bae47b4f..e2ee76a105041f0df9062fbba32618b5607f29c7 100644 --- a/pkg/middlewares/tracing/forwarder.go +++ b/pkg/middlewares/tracing/forwarder.go @@ -5,9 +5,9 @@ import ( "net/http" "github.com/opentracing/opentracing-go/ext" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/tracing" ) const ( diff --git a/pkg/middlewares/tracing/forwarder_test.go b/pkg/middlewares/tracing/forwarder_test.go index 1253412d347352c00bfff5e1782be1b0f80f5924..785e729cb34038ba5588b4b719aa0a723719b755 100644 --- a/pkg/middlewares/tracing/forwarder_test.go +++ b/pkg/middlewares/tracing/forwarder_test.go @@ -9,7 +9,7 @@ import ( "github.com/opentracing/opentracing-go/ext" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/tracing" ) func TestNewForwarder(t *testing.T) { diff --git a/pkg/middlewares/tracing/wrapper.go b/pkg/middlewares/tracing/wrapper.go index e13209d548a432edfd573121a1701d3b37b353fc..1fa3cfcdd8e18afabfc4a82873a40e85df711081 100644 --- a/pkg/middlewares/tracing/wrapper.go +++ b/pkg/middlewares/tracing/wrapper.go @@ -7,8 +7,8 @@ import ( "github.com/containous/alice" "github.com/opentracing/opentracing-go/ext" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/tracing" ) // Traceable embeds tracing information. diff --git a/pkg/muxer/http/matcher.go b/pkg/muxer/http/matcher.go index d30e6df61d59b8fdfef3170def4e2e6c1837d94a..9b6861d2f5a9265648c49c60d25dd085ff4151be 100644 --- a/pkg/muxer/http/matcher.go +++ b/pkg/muxer/http/matcher.go @@ -7,14 +7,13 @@ import ( "strings" "unicode/utf8" - "github.com/gorilla/mux" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/ip" - "github.com/traefik/traefik/v2/pkg/middlewares/requestdecorator" + "github.com/traefik/traefik/v3/pkg/ip" + "github.com/traefik/traefik/v3/pkg/middlewares/requestdecorator" "golang.org/x/exp/slices" ) -var httpFuncs = map[string]func(*mux.Route, ...string) error{ +var httpFuncs = map[string]func(*matchersTree, ...string) error{ "ClientIP": expectNParameters(clientIP, 1), "Method": expectNParameters(method, 1), "Host": expectNParameters(host, 1), @@ -28,17 +27,17 @@ var httpFuncs = map[string]func(*mux.Route, ...string) error{ "QueryRegexp": expectNParameters(queryRegexp, 1, 2), } -func expectNParameters(fn func(*mux.Route, ...string) error, n ...int) func(*mux.Route, ...string) error { - return func(route *mux.Route, s ...string) error { +func expectNParameters(fn func(*matchersTree, ...string) error, n ...int) func(*matchersTree, ...string) error { + return func(tree *matchersTree, s ...string) error { if !slices.Contains(n, len(s)) { return fmt.Errorf("unexpected number of parameters; got %d, expected one of %v", len(s), n) } - return fn(route, s...) + return fn(tree, s...) } } -func clientIP(route *mux.Route, clientIP ...string) error { +func clientIP(tree *matchersTree, clientIP ...string) error { checker, err := ip.NewChecker(clientIP) if err != nil { return fmt.Errorf("initializing IP checker for ClientIP matcher: %w", err) @@ -46,7 +45,7 @@ func clientIP(route *mux.Route, clientIP ...string) error { strategy := ip.RemoteAddrStrategy{} - route.MatcherFunc(func(req *http.Request, _ *mux.RouteMatch) bool { + tree.matcher = func(req *http.Request) bool { ok, err := checker.Contains(strategy.GetIP(req)) if err != nil { log.Ctx(req.Context()).Warn().Err(err).Msg("ClientIP matcher: could not match remote address") @@ -54,16 +53,22 @@ func clientIP(route *mux.Route, clientIP ...string) error { } return ok - }) + } return nil } -func method(route *mux.Route, methods ...string) error { - return route.Methods(methods...).GetError() +func method(tree *matchersTree, methods ...string) error { + method := strings.ToUpper(methods[0]) + + tree.matcher = func(req *http.Request) bool { + return method == req.Method + } + + return nil } -func host(route *mux.Route, hosts ...string) error { +func host(tree *matchersTree, hosts ...string) error { host := hosts[0] if !IsASCII(host) { @@ -72,7 +77,7 @@ func host(route *mux.Route, hosts ...string) error { host = strings.ToLower(host) - route.MatcherFunc(func(req *http.Request, _ *mux.RouteMatch) bool { + tree.matcher = func(req *http.Request) bool { reqHost := requestdecorator.GetCanonizedHost(req.Context()) if len(reqHost) == 0 { return false @@ -104,12 +109,12 @@ func host(route *mux.Route, hosts ...string) error { } return false - }) + } return nil } -func hostRegexp(route *mux.Route, hosts ...string) error { +func hostRegexp(tree *matchersTree, hosts ...string) error { host := hosts[0] if !IsASCII(host) { @@ -121,29 +126,29 @@ func hostRegexp(route *mux.Route, hosts ...string) error { return fmt.Errorf("compiling HostRegexp matcher: %w", err) } - route.MatcherFunc(func(req *http.Request, _ *mux.RouteMatch) bool { + tree.matcher = func(req *http.Request) bool { return re.MatchString(requestdecorator.GetCanonizedHost(req.Context())) || re.MatchString(requestdecorator.GetCNAMEFlatten(req.Context())) - }) + } return nil } -func path(route *mux.Route, paths ...string) error { +func path(tree *matchersTree, paths ...string) error { path := paths[0] if !strings.HasPrefix(path, "/") { return fmt.Errorf("path %q does not start with a '/'", path) } - route.MatcherFunc(func(req *http.Request, _ *mux.RouteMatch) bool { + tree.matcher = func(req *http.Request) bool { return req.URL.Path == path - }) + } return nil } -func pathRegexp(route *mux.Route, paths ...string) error { +func pathRegexp(tree *matchersTree, paths ...string) error { path := paths[0] re, err := regexp.Compile(path) @@ -151,36 +156,65 @@ func pathRegexp(route *mux.Route, paths ...string) error { return fmt.Errorf("compiling PathPrefix matcher: %w", err) } - route.MatcherFunc(func(req *http.Request, _ *mux.RouteMatch) bool { + tree.matcher = func(req *http.Request) bool { return re.MatchString(req.URL.Path) - }) + } return nil } -func pathPrefix(route *mux.Route, paths ...string) error { +func pathPrefix(tree *matchersTree, paths ...string) error { path := paths[0] if !strings.HasPrefix(path, "/") { return fmt.Errorf("path %q does not start with a '/'", path) } - route.MatcherFunc(func(req *http.Request, _ *mux.RouteMatch) bool { + tree.matcher = func(req *http.Request) bool { return strings.HasPrefix(req.URL.Path, path) - }) + } return nil } -func header(route *mux.Route, headers ...string) error { - return route.Headers(headers...).GetError() +func header(tree *matchersTree, headers ...string) error { + key, value := http.CanonicalHeaderKey(headers[0]), headers[1] + + tree.matcher = func(req *http.Request) bool { + for _, headerValue := range req.Header[key] { + if headerValue == value { + return true + } + } + + return false + } + + return nil } -func headerRegexp(route *mux.Route, headers ...string) error { - return route.HeadersRegexp(headers...).GetError() +func headerRegexp(tree *matchersTree, headers ...string) error { + key, value := http.CanonicalHeaderKey(headers[0]), headers[1] + + re, err := regexp.Compile(value) + if err != nil { + return fmt.Errorf("compiling HeaderRegexp matcher: %w", err) + } + + tree.matcher = func(req *http.Request) bool { + for _, headerValue := range req.Header[key] { + if re.MatchString(headerValue) { + return true + } + } + + return false + } + + return nil } -func query(route *mux.Route, queries ...string) error { +func query(tree *matchersTree, queries ...string) error { key := queries[0] var value string @@ -188,21 +222,21 @@ func query(route *mux.Route, queries ...string) error { value = queries[1] } - route.MatcherFunc(func(req *http.Request, _ *mux.RouteMatch) bool { + tree.matcher = func(req *http.Request) bool { values, ok := req.URL.Query()[key] if !ok { return false } return slices.Contains(values, value) - }) + } return nil } -func queryRegexp(route *mux.Route, queries ...string) error { +func queryRegexp(tree *matchersTree, queries ...string) error { if len(queries) == 1 { - return query(route, queries...) + return query(tree, queries...) } key, value := queries[0], queries[1] @@ -212,7 +246,7 @@ func queryRegexp(route *mux.Route, queries ...string) error { return fmt.Errorf("compiling QueryRegexp matcher: %w", err) } - route.MatcherFunc(func(req *http.Request, _ *mux.RouteMatch) bool { + tree.matcher = func(req *http.Request) bool { values, ok := req.URL.Query()[key] if !ok { return false @@ -223,7 +257,7 @@ func queryRegexp(route *mux.Route, queries ...string) error { }) return idx >= 0 - }) + } return nil } diff --git a/pkg/muxer/http/matcher_test.go b/pkg/muxer/http/matcher_test.go index 2d31d8dc815eea60bc89977da1352c82452cc9bc..1b527a392058a2c5dad9ffb828ba0aaaf071d81e 100644 --- a/pkg/muxer/http/matcher_test.go +++ b/pkg/muxer/http/matcher_test.go @@ -3,11 +3,12 @@ package http import ( "net/http" "net/http/httptest" + "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/middlewares/requestdecorator" + "github.com/traefik/traefik/v3/pkg/middlewares/requestdecorator" ) func TestClientIPMatcher(t *testing.T) { @@ -121,16 +122,18 @@ func TestMethodMatcher(t *testing.T) { desc: "valid Method matcher", rule: "Method(`GET`)", expected: map[string]int{ - http.MethodGet: http.StatusOK, - http.MethodPost: http.StatusMethodNotAllowed, + http.MethodGet: http.StatusOK, + http.MethodPost: http.StatusNotFound, + strings.ToLower(http.MethodGet): http.StatusNotFound, }, }, { desc: "valid Method matcher (lower case)", rule: "Method(`get`)", expected: map[string]int{ - http.MethodGet: http.StatusOK, - http.MethodPost: http.StatusMethodNotAllowed, + http.MethodGet: http.StatusOK, + http.MethodPost: http.StatusNotFound, + strings.ToLower(http.MethodGet): http.StatusNotFound, }, }, } @@ -200,6 +203,7 @@ func TestHostMatcher(t *testing.T) { "https://example.com": http.StatusOK, "https://example.com:8080": http.StatusOK, "https://example.com/path": http.StatusOK, + "https://EXAMPLE.COM/path": http.StatusOK, "https://example.org": http.StatusNotFound, "https://example.org/path": http.StatusNotFound, }, @@ -665,6 +669,17 @@ func TestHeaderMatcher(t *testing.T) { {"X-Forwarded-Host": []string{"example.com"}}: http.StatusNotFound, }, }, + { + desc: "valid Header matcher (non-canonical form)", + rule: "Header(`x-forwarded-proto`, `https`)", + expected: map[*http.Header]int{ + {"X-Forwarded-Proto": []string{"https"}}: http.StatusOK, + {"x-forwarded-proto": []string{"https"}}: http.StatusNotFound, + {"X-Forwarded-Proto": []string{"http", "https"}}: http.StatusOK, + {"X-Forwarded-Proto": []string{"https", "http"}}: http.StatusOK, + {"X-Forwarded-Host": []string{"example.com"}}: http.StatusNotFound, + }, + }, } for _, test := range testCases { @@ -747,6 +762,18 @@ func TestHeaderRegexpMatcher(t *testing.T) { {"X-Forwarded-Host": []string{"example.com"}}: http.StatusNotFound, }, }, + { + desc: "valid HeaderRegexp matcher (non-canonical form)", + rule: "HeaderRegexp(`x-forwarded-proto`, `^https?$`)", + expected: map[*http.Header]int{ + {"X-Forwarded-Proto": []string{"http"}}: http.StatusOK, + {"x-forwarded-proto": []string{"http"}}: http.StatusNotFound, + {"X-Forwarded-Proto": []string{"https"}}: http.StatusOK, + {"X-Forwarded-Proto": []string{"HTTPS"}}: http.StatusNotFound, + {"X-Forwarded-Proto": []string{"ws", "https"}}: http.StatusOK, + {"X-Forwarded-Host": []string{"example.com"}}: http.StatusNotFound, + }, + }, { desc: "valid HeaderRegexp matcher with Traefik v2 syntax", rule: "HeaderRegexp(`X-Forwarded-Proto`, `http{secure:s?}`)", diff --git a/pkg/muxer/http/mux.go b/pkg/muxer/http/mux.go index 2379770445dd07d3fd934d0757c4a5f45dcdfd95..979634aa112476bcb2c253cf4b1a4d08cbb16f33 100644 --- a/pkg/muxer/http/mux.go +++ b/pkg/muxer/http/mux.go @@ -3,15 +3,16 @@ package http import ( "fmt" "net/http" + "sort" - "github.com/gorilla/mux" - "github.com/traefik/traefik/v2/pkg/rules" + "github.com/rs/zerolog/log" + "github.com/traefik/traefik/v3/pkg/rules" "github.com/vulcand/predicate" ) // Muxer handles routing with rules. type Muxer struct { - *mux.Router + routes routes parser predicate.Parser } @@ -24,18 +25,36 @@ func NewMuxer() (*Muxer, error) { parser, err := rules.NewParser(matchers) if err != nil { - return nil, err + return nil, fmt.Errorf("error while creating parser: %w", err) } return &Muxer{ - Router: mux.NewRouter().SkipClean(true), parser: parser, }, nil } +// ServeHTTP forwards the connection to the matching HTTP handler. +// Serves 404 if no handler is found. +func (m *Muxer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + for _, route := range m.routes { + if route.matchers.match(req) { + route.handler.ServeHTTP(rw, req) + return + } + } + + http.NotFoundHandler().ServeHTTP(rw, req) +} + +// GetRulePriority computes the priority for a given rule. +// The priority is calculated using the length of rule. +func GetRulePriority(rule string) int { + return len(rule) +} + // AddRoute add a new route to the router. -func (r *Muxer) AddRoute(rule string, priority int, handler http.Handler) error { - parse, err := r.parser.Parse(rule) +func (m *Muxer) AddRoute(rule string, priority int, handler http.Handler) error { + parse, err := m.parser.Parse(rule) if err != nil { return fmt.Errorf("error while parsing rule %s: %w", rule, err) } @@ -45,122 +64,138 @@ func (r *Muxer) AddRoute(rule string, priority int, handler http.Handler) error return fmt.Errorf("error while parsing rule %s", rule) } - if priority == 0 { - priority = len(rule) + var matchers matchersTree + err = matchers.addRule(buildTree()) + if err != nil { + return fmt.Errorf("error while adding rule %s: %w", rule, err) } - route := r.NewRoute().Handler(handler).Priority(priority) + m.routes = append(m.routes, &route{ + handler: handler, + matchers: matchers, + priority: priority, + }) - err = addRuleOnRoute(route, buildTree()) - if err != nil { - route.BuildOnly() - return err - } + sort.Sort(m.routes) return nil } -func addRuleOnRouter(router *mux.Router, rule *rules.Tree) error { - switch rule.Matcher { - case "and": - route := router.NewRoute() - err := addRuleOnRoute(route, rule.RuleLeft) - if err != nil { - return err - } - - return addRuleOnRoute(route, rule.RuleRight) - case "or": - err := addRuleOnRouter(router, rule.RuleLeft) - if err != nil { - return err - } +// ParseDomains extract domains from rule. +func ParseDomains(rule string) ([]string, error) { + var matchers []string + for matcher := range httpFuncs { + matchers = append(matchers, matcher) + } - return addRuleOnRouter(router, rule.RuleRight) - default: - err := rules.CheckRule(rule) - if err != nil { - return err - } + parser, err := rules.NewParser(matchers) + if err != nil { + return nil, fmt.Errorf("error while creating parser: %w", err) + } - if rule.Not { - return not(httpFuncs[rule.Matcher])(router.NewRoute(), rule.Value...) - } + parse, err := parser.Parse(rule) + if err != nil { + return nil, fmt.Errorf("error while parsing rule %s: %w", rule, err) + } - return httpFuncs[rule.Matcher](router.NewRoute(), rule.Value...) + buildTree, ok := parse.(rules.TreeBuilder) + if !ok { + return nil, fmt.Errorf("error while parsing rule %s", rule) } -} -func addRuleOnRoute(route *mux.Route, rule *rules.Tree) error { - switch rule.Matcher { - case "and": - err := addRuleOnRoute(route, rule.RuleLeft) - if err != nil { - return err - } + return buildTree().ParseMatchers([]string{"Host"}), nil +} - return addRuleOnRoute(route, rule.RuleRight) - case "or": - subRouter := route.Subrouter() +// routes implements sort.Interface. +type routes []*route - err := addRuleOnRouter(subRouter, rule.RuleLeft) - if err != nil { - return err - } +// Len implements sort.Interface. +func (r routes) Len() int { return len(r) } - return addRuleOnRouter(subRouter, rule.RuleRight) - default: - err := rules.CheckRule(rule) - if err != nil { - return err - } +// Swap implements sort.Interface. +func (r routes) Swap(i, j int) { r[i], r[j] = r[j], r[i] } - if rule.Not { - return not(httpFuncs[rule.Matcher])(route, rule.Value...) - } +// Less implements sort.Interface. +func (r routes) Less(i, j int) bool { return r[i].priority > r[j].priority } - return httpFuncs[rule.Matcher](route, rule.Value...) - } +// route holds the matchers to match HTTP route, +// and the handler that will serve the request. +type route struct { + // matchers tree structure reflecting the rule. + matchers matchersTree + // handler responsible for handling the route. + handler http.Handler + // priority is used to disambiguate between two (or more) rules that would all match for a given request. + // Computed from the matching rule length, if not user-set. + priority int } -func not(m func(*mux.Route, ...string) error) func(*mux.Route, ...string) error { - return func(r *mux.Route, v ...string) error { - router := mux.NewRouter() +// matchersTree represents the matchers tree structure. +type matchersTree struct { + // matcher is a matcher func used to match HTTP request properties. + // If matcher is not nil, it means that this matcherTree is a leaf of the tree. + // It is therefore mutually exclusive with left and right. + matcher func(*http.Request) bool + // operator to combine the evaluation of left and right leaves. + operator string + // Mutually exclusive with matcher. + left *matchersTree + right *matchersTree +} - err := m(router.NewRoute(), v...) - if err != nil { - return err - } +func (m *matchersTree) match(req *http.Request) bool { + if m == nil { + // This should never happen as it should have been detected during parsing. + log.Warn().Msg("Rule matcher is nil") + return false + } - r.MatcherFunc(func(req *http.Request, ma *mux.RouteMatch) bool { - return !router.Match(req, ma) - }) + if m.matcher != nil { + return m.matcher(req) + } - return nil + switch m.operator { + case "or": + return m.left.match(req) || m.right.match(req) + case "and": + return m.left.match(req) && m.right.match(req) + default: + // This should never happen as it should have been detected during parsing. + log.Warn().Str("operator", m.operator).Msg("Invalid rule operator") + return false } } -// ParseDomains extract domains from rule. -func ParseDomains(rule string) ([]string, error) { - var matchers []string - for matcher := range httpFuncs { - matchers = append(matchers, matcher) - } +func (m *matchersTree) addRule(rule *rules.Tree) error { + switch rule.Matcher { + case "and", "or": + m.operator = rule.Matcher + m.left = &matchersTree{} + err := m.left.addRule(rule.RuleLeft) + if err != nil { + return fmt.Errorf("error while adding rule %s: %w", rule.Matcher, err) + } - parser, err := rules.NewParser(matchers) - if err != nil { - return nil, err - } + m.right = &matchersTree{} + return m.right.addRule(rule.RuleRight) + default: + err := rules.CheckRule(rule) + if err != nil { + return fmt.Errorf("error while checking rule %s: %w", rule.Matcher, err) + } - parse, err := parser.Parse(rule) - if err != nil { - return nil, err - } + err = httpFuncs[rule.Matcher](m, rule.Value...) + if err != nil { + return fmt.Errorf("error while adding rule %s: %w", rule.Matcher, err) + } - buildTree, ok := parse.(rules.TreeBuilder) - if !ok { - return nil, fmt.Errorf("error while parsing rule %s", rule) + if rule.Not { + matcherFunc := m.matcher + m.matcher = func(req *http.Request) bool { + return !matcherFunc(req) + } + } } - return buildTree().ParseMatchers([]string{"Host"}), nil + return nil } diff --git a/pkg/muxer/http/mux_test.go b/pkg/muxer/http/mux_test.go index bdc98df373d50bfdf4ffc0d7f9a34471976e9312..a31a3788173acb71b23e2582de720517b68e4941 100644 --- a/pkg/muxer/http/mux_test.go +++ b/pkg/muxer/http/mux_test.go @@ -9,8 +9,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/middlewares/requestdecorator" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/middlewares/requestdecorator" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) func TestMuxer(t *testing.T) { @@ -36,6 +36,20 @@ func TestMuxer(t *testing.T) { rule: "Host(example.com)", expectedError: true, }, + { + desc: "Host IPv4", + rule: "Host(`127.0.0.1`)", + expected: map[string]int{ + "http://127.0.0.1/foo": http.StatusOK, + }, + }, + { + desc: "Host IPv6", + rule: "Host(`10::10`)", + expected: map[string]int{ + "http://10::10/foo": http.StatusOK, + }, + }, { desc: "Host and PathPrefix", rule: "Host(`localhost`) && PathPrefix(`/css`)", @@ -376,12 +390,14 @@ func Test_addRoutePriority(t *testing.T) { w.Header().Set("X-From", route.xFrom) }) + if route.priority == 0 { + route.priority = GetRulePriority(route.rule) + } + err := muxer.AddRoute(route.rule, route.priority, handler) require.NoError(t, err, route.rule) } - muxer.SortRoutes() - w := httptest.NewRecorder() req := testhelpers.MustNewRequest(http.MethodGet, test.path, http.NoBody) @@ -519,3 +535,26 @@ func TestEmptyHost(t *testing.T) { }) } } + +func TestGetRulePriority(t *testing.T) { + testCases := []struct { + desc string + rule string + expected int + }{ + { + desc: "simple rule", + rule: "Host(`example.org`)", + expected: 19, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + assert.Equal(t, test.expected, GetRulePriority(test.rule)) + }) + } +} diff --git a/pkg/muxer/tcp/matcher.go b/pkg/muxer/tcp/matcher.go index 40694c3eae05aa663b4bb4c11810027b01b9a17a..0ac0ed23a662af75446d13469122851c8088b68d 100644 --- a/pkg/muxer/tcp/matcher.go +++ b/pkg/muxer/tcp/matcher.go @@ -8,7 +8,7 @@ import ( "github.com/go-acme/lego/v4/challenge/tlsalpn01" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/ip" + "github.com/traefik/traefik/v3/pkg/ip" ) var tcpFuncs = map[string]func(*matchersTree, ...string) error{ @@ -67,7 +67,7 @@ func clientIP(tree *matchersTree, clientIP ...string) error { return nil } -var almostFQDN = regexp.MustCompile(`^[[:alnum:]\.-]+$`) +var hostOrIP = regexp.MustCompile(`^[[:alnum:]\.\-\:]+$`) // hostSNI checks if the SNI Host of the connection match the matcher host. func hostSNI(tree *matchersTree, hosts ...string) error { @@ -80,7 +80,7 @@ func hostSNI(tree *matchersTree, hosts ...string) error { return nil } - if !almostFQDN.MatchString(host) { + if !hostOrIP.MatchString(host) { return fmt.Errorf("invalid value for HostSNI matcher, %q is not a valid hostname", host) } diff --git a/pkg/muxer/tcp/matcher_test.go b/pkg/muxer/tcp/matcher_test.go index 06b45e1866bdee769763c076872baefc35631446..3ba833d494e4857143118199a73e95a92a27fa29 100644 --- a/pkg/muxer/tcp/matcher_test.go +++ b/pkg/muxer/tcp/matcher_test.go @@ -5,7 +5,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/tcp" ) func Test_HostSNICatchAll(t *testing.T) { diff --git a/pkg/muxer/tcp/mux.go b/pkg/muxer/tcp/mux.go index 3c5abffaf7a1a3233af5084c2ad60ab748ec6c53..f23ce629d6c3e37a48e64faf1594ddd581eae1a6 100644 --- a/pkg/muxer/tcp/mux.go +++ b/pkg/muxer/tcp/mux.go @@ -7,38 +7,12 @@ import ( "strings" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/rules" - "github.com/traefik/traefik/v2/pkg/tcp" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/rules" + "github.com/traefik/traefik/v3/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/types" "github.com/vulcand/predicate" ) -// ParseHostSNI extracts the HostSNIs declared in a rule. -// This is a first naive implementation used in TCP routing. -func ParseHostSNI(rule string) ([]string, error) { - var matchers []string - for matcher := range tcpFuncs { - matchers = append(matchers, matcher) - } - - parser, err := rules.NewParser(matchers) - if err != nil { - return nil, err - } - - parse, err := parser.Parse(rule) - if err != nil { - return nil, err - } - - buildTree, ok := parse.(rules.TreeBuilder) - if !ok { - return nil, fmt.Errorf("error while parsing rule %s", rule) - } - - return buildTree().ParseMatchers([]string{"HostSNI"}), nil -} - // ConnData contains TCP connection metadata. type ConnData struct { serverName string @@ -67,7 +41,7 @@ func NewConnData(serverName string, conn tcp.WriteCloser, alpnProtos []string) ( // Muxer defines a muxer that handles TCP routing with rules. type Muxer struct { - routes []*route + routes routes parser predicate.Parser } @@ -98,6 +72,38 @@ func (m Muxer) Match(meta ConnData) (tcp.Handler, bool) { return nil, false } +// GetRulePriority computes the priority for a given rule. +// The priority is calculated using the length of rule. +// There is a special case where the HostSNI(`*`) has a priority of -1. +func GetRulePriority(rule string) int { + catchAllParser, err := rules.NewParser([]string{"HostSNI"}) + if err != nil { + return len(rule) + } + + parse, err := catchAllParser.Parse(rule) + if err != nil { + return len(rule) + } + + buildTree, ok := parse.(rules.TreeBuilder) + if !ok { + return len(rule) + } + + ruleTree := buildTree() + + // Special case for when the catchAll fallback is present. + // When no user-defined priority is found, the lowest computable priority minus one is used, + // in order to make the fallback the last to be evaluated. + if ruleTree.RuleLeft == nil && ruleTree.RuleRight == nil && len(ruleTree.Value) == 1 && + ruleTree.Value[0] == "*" && strings.EqualFold(ruleTree.Matcher, "HostSNI") { + return -1 + } + + return len(rule) +} + // AddRoute adds a new route, associated to the given handler, at the given // priority, to the muxer. func (m *Muxer) AddRoute(rule string, priority int, handler tcp.Handler) error { @@ -114,9 +120,9 @@ func (m *Muxer) AddRoute(rule string, priority int, handler tcp.Handler) error { ruleTree := buildTree() var matchers matchersTree - err = addRule(&matchers, ruleTree) + err = matchers.addRule(ruleTree) if err != nil { - return err + return fmt.Errorf("error while adding rule %s: %w", rule, err) } var catchAll bool @@ -124,18 +130,6 @@ func (m *Muxer) AddRoute(rule string, priority int, handler tcp.Handler) error { catchAll = ruleTree.Value[0] == "*" && strings.EqualFold(ruleTree.Matcher, "HostSNI") } - // Special case for when the catchAll fallback is present. - // When no user-defined priority is found, the lowest computable priority minus one is used, - // in order to make the fallback the last to be evaluated. - if priority == 0 && catchAll { - priority = -1 - } - - // Default value, which means the user has not set it, so we'll compute it. - if priority == 0 { - priority = len(rule) - } - newRoute := &route{ handler: handler, matchers: matchers, @@ -144,48 +138,40 @@ func (m *Muxer) AddRoute(rule string, priority int, handler tcp.Handler) error { } m.routes = append(m.routes, newRoute) - sort.Sort(routes(m.routes)) + sort.Sort(m.routes) return nil } -func addRule(tree *matchersTree, rule *rules.Tree) error { - switch rule.Matcher { - case "and", "or": - tree.operator = rule.Matcher - tree.left = &matchersTree{} - err := addRule(tree.left, rule.RuleLeft) - if err != nil { - return err - } +// HasRoutes returns whether the muxer has routes. +func (m *Muxer) HasRoutes() bool { + return len(m.routes) > 0 +} - tree.right = &matchersTree{} - return addRule(tree.right, rule.RuleRight) - default: - err := rules.CheckRule(rule) - if err != nil { - return err - } +// ParseHostSNI extracts the HostSNIs declared in a rule. +// This is a first naive implementation used in TCP routing. +func ParseHostSNI(rule string) ([]string, error) { + var matchers []string + for matcher := range tcpFuncs { + matchers = append(matchers, matcher) + } - err = tcpFuncs[rule.Matcher](tree, rule.Value...) - if err != nil { - return err - } + parser, err := rules.NewParser(matchers) + if err != nil { + return nil, err + } - if rule.Not { - matcherFunc := tree.matcher - tree.matcher = func(meta ConnData) bool { - return !matcherFunc(meta) - } - } + parse, err := parser.Parse(rule) + if err != nil { + return nil, err } - return nil -} + buildTree, ok := parse.(rules.TreeBuilder) + if !ok { + return nil, fmt.Errorf("error while parsing rule %s", rule) + } -// HasRoutes returns whether the muxer has routes. -func (m *Muxer) HasRoutes() bool { - return len(m.routes) > 0 + return buildTree().ParseMatchers([]string{"HostSNI"}), nil } // routes implements sort.Interface. @@ -215,14 +201,12 @@ type route struct { priority int } -// matcher is a matcher func used to match connection properties. -type matcher func(meta ConnData) bool - // matchersTree represents the matchers tree structure. type matchersTree struct { + // matcher is a matcher func used to match connection properties. // If matcher is not nil, it means that this matcherTree is a leaf of the tree. // It is therefore mutually exclusive with left and right. - matcher matcher + matcher func(ConnData) bool // operator to combine the evaluation of left and right leaves. operator string // Mutually exclusive with matcher. @@ -252,3 +236,37 @@ func (m *matchersTree) match(meta ConnData) bool { return false } } + +func (m *matchersTree) addRule(rule *rules.Tree) error { + switch rule.Matcher { + case "and", "or": + m.operator = rule.Matcher + m.left = &matchersTree{} + err := m.left.addRule(rule.RuleLeft) + if err != nil { + return err + } + + m.right = &matchersTree{} + return m.right.addRule(rule.RuleRight) + default: + err := rules.CheckRule(rule) + if err != nil { + return err + } + + err = tcpFuncs[rule.Matcher](m, rule.Value...) + if err != nil { + return err + } + + if rule.Not { + matcherFunc := m.matcher + m.matcher = func(meta ConnData) bool { + return !matcherFunc(meta) + } + } + } + + return nil +} diff --git a/pkg/muxer/tcp/mux_test.go b/pkg/muxer/tcp/mux_test.go index 95e84a24587003df2eed5eb962bd66db026eec25..08258b99e193f05765d8f2b9d005eeb477ee9181 100644 --- a/pkg/muxer/tcp/mux_test.go +++ b/pkg/muxer/tcp/mux_test.go @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/tcp" ) func Test_addTCPRoute(t *testing.T) { @@ -250,6 +250,16 @@ func Test_addTCPRoute(t *testing.T) { serverName: "example.com", matchErr: true, }, + { + desc: "Matching IPv4", + rule: "HostSNI(`127.0.0.1`)", + serverName: "127.0.0.1", + }, + { + desc: "Matching IPv6", + rule: "HostSNI(`10::10`)", + serverName: "10::10", + }, } for _, test := range testCases { @@ -332,6 +342,16 @@ func TestParseHostSNI(t *testing.T) { expression: "hostsni(`example.com`)", domain: []string{"example.com"}, }, + { + desc: "HostSNI IPv4", + expression: "HostSNI(`127.0.0.1`)", + domain: []string{"127.0.0.1"}, + }, + { + desc: "HostSNI IPv6", + expression: "HostSNI(`10::10`)", + domain: []string{"10::10"}, + }, { desc: "No hostSNI rule", expression: "ClientIP(`10.1`)", @@ -444,6 +464,39 @@ func Test_Priority(t *testing.T) { } } +func TestGetRulePriority(t *testing.T) { + testCases := []struct { + desc string + rule string + expected int + }{ + { + desc: "simple rule", + rule: "HostSNI(`example.org`)", + expected: 22, + }, + { + desc: "HostSNI(`*`) rule", + rule: "HostSNI(`*`)", + expected: -1, + }, + { + desc: "strange HostSNI(`*`) rule", + rule: " HostSNI ( `*` ) ", + expected: -1, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + assert.Equal(t, test.expected, GetRulePriority(test.rule)) + }) + } +} + type fakeConn struct { call map[string]int remoteAddr net.Addr diff --git a/pkg/plugins/builder.go b/pkg/plugins/builder.go index aa3d4c9829ea8e7dd392150b88721fb40f22df22..c2012427bf3cdb4b6ce667a527184e4afd0347d8 100644 --- a/pkg/plugins/builder.go +++ b/pkg/plugins/builder.go @@ -8,7 +8,7 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/logs" "github.com/traefik/yaegi/interp" "github.com/traefik/yaegi/stdlib" ) diff --git a/pkg/plugins/client.go b/pkg/plugins/client.go index 9e7ba8538504dcc62daa64afa3c71510fae8f370..476d3f30203e7dca122c0f61b937e89ef516c7d6 100644 --- a/pkg/plugins/client.go +++ b/pkg/plugins/client.go @@ -18,7 +18,7 @@ import ( "github.com/hashicorp/go-retryablehttp" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/logs" "golang.org/x/mod/module" "golang.org/x/mod/zip" "gopkg.in/yaml.v3" diff --git a/pkg/plugins/providers.go b/pkg/plugins/providers.go index ea024c8364cda48f35c31e63bb6ced898f9b4306..5fdaf03accd6ee6eb1a9ec9132981e50d8c56557 100644 --- a/pkg/plugins/providers.go +++ b/pkg/plugins/providers.go @@ -10,10 +10,10 @@ import ( "github.com/mitchellh/mapstructure" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" "github.com/traefik/yaegi/interp" ) @@ -45,7 +45,7 @@ func (p _PP) Stop() error { func ppSymbols() map[string]map[string]reflect.Value { return map[string]map[string]reflect.Value{ - "github.com/traefik/traefik/v2/pkg/plugins/plugins": { + "github.com/traefik/traefik/v3/pkg/plugins/plugins": { "PP": reflect.ValueOf((*PP)(nil)), "_PP": reflect.ValueOf((*_PP)(nil)), }, @@ -115,7 +115,7 @@ import ( "context" ` + basePkg + ` "` + builder.Import + `" - "github.com/traefik/traefik/v2/pkg/plugins" + "github.com/traefik/traefik/v3/pkg/plugins" ) func NewWrapper(ctx context.Context, config *` + basePkg + `.Config, name string) (plugins.PP, error) { diff --git a/pkg/provider/acme/account.go b/pkg/provider/acme/account.go index 6bac6c186d4185979b66893967610daa5571bc22..c0a7458b3a12e36ceb68cd7bcf74fef3772dca5c 100644 --- a/pkg/provider/acme/account.go +++ b/pkg/provider/acme/account.go @@ -10,7 +10,7 @@ import ( "github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/registration" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/logs" ) // Account is used to store lets encrypt registration info. diff --git a/pkg/provider/acme/challenge_http.go b/pkg/provider/acme/challenge_http.go index 80d6a6c67c358686af525fd22fd00d9649de9202..1553565056fdbbed82db0ee4ec1ff19a7440c502 100644 --- a/pkg/provider/acme/challenge_http.go +++ b/pkg/provider/acme/challenge_http.go @@ -14,8 +14,8 @@ import ( "github.com/cenkalti/backoff/v4" "github.com/go-acme/lego/v4/challenge/http01" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/safe" ) // ChallengeHTTP HTTP challenge provider implements challenge.Provider. diff --git a/pkg/provider/acme/challenge_tls.go b/pkg/provider/acme/challenge_tls.go index a53f83f2b587180223261709279d7aaa122be930..b4ce624d5c8d7958a57bbbbdb329c49ac9ce9d41 100644 --- a/pkg/provider/acme/challenge_tls.go +++ b/pkg/provider/acme/challenge_tls.go @@ -7,11 +7,11 @@ import ( "github.com/go-acme/lego/v4/challenge/tlsalpn01" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/safe" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/safe" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" ) const providerNameALPN = "tlsalpn.acme" diff --git a/pkg/provider/acme/local_store.go b/pkg/provider/acme/local_store.go index 57a26207b3e43786f8ae1a589b0cdced7ec1ba2f..c7677e047b72a5a06ec8c0af43e3bae803fcce96 100644 --- a/pkg/provider/acme/local_store.go +++ b/pkg/provider/acme/local_store.go @@ -7,8 +7,8 @@ import ( "sync" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/safe" ) var _ Store = (*LocalStore)(nil) diff --git a/pkg/provider/acme/provider.go b/pkg/provider/acme/provider.go index e57c84d5bae13bfaedde9780c3ba528247f33134..c9c7a70e77187002df9a5aa874939c890bf50969 100644 --- a/pkg/provider/acme/provider.go +++ b/pkg/provider/acme/provider.go @@ -21,14 +21,14 @@ import ( "github.com/go-acme/lego/v4/registration" "github.com/rs/zerolog/log" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - httpmuxer "github.com/traefik/traefik/v2/pkg/muxer/http" - tcpmuxer "github.com/traefik/traefik/v2/pkg/muxer/tcp" - "github.com/traefik/traefik/v2/pkg/safe" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" - "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + httpmuxer "github.com/traefik/traefik/v3/pkg/muxer/http" + tcpmuxer "github.com/traefik/traefik/v3/pkg/muxer/tcp" + "github.com/traefik/traefik/v3/pkg/safe" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" + "github.com/traefik/traefik/v3/pkg/version" ) // ocspMustStaple enables OCSP stapling as from https://github.com/go-acme/lego/issues/270. diff --git a/pkg/provider/acme/provider_test.go b/pkg/provider/acme/provider_test.go index 3268b1c92317ecd59a54d397fa30a58d718a5762..d41f19c4523a286e9bc3cbe1b74c7a49cdee8792 100644 --- a/pkg/provider/acme/provider_test.go +++ b/pkg/provider/acme/provider_test.go @@ -8,8 +8,8 @@ import ( "github.com/go-acme/lego/v4/certcrypto" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/types" ) func TestGetUncheckedCertificates(t *testing.T) { diff --git a/pkg/provider/aggregator/aggregator.go b/pkg/provider/aggregator/aggregator.go index 8001711fca264578a4f46c4b6fb4487791595964..009aa9c938d4abce0cc763add0a949808f828403 100644 --- a/pkg/provider/aggregator/aggregator.go +++ b/pkg/provider/aggregator/aggregator.go @@ -5,13 +5,13 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/file" - "github.com/traefik/traefik/v2/pkg/provider/traefik" - "github.com/traefik/traefik/v2/pkg/redactor" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/file" + "github.com/traefik/traefik/v3/pkg/provider/traefik" + "github.com/traefik/traefik/v3/pkg/redactor" + "github.com/traefik/traefik/v3/pkg/safe" ) // throttled defines what kind of config refresh throttling the aggregator should @@ -80,10 +80,6 @@ func NewProviderAggregator(conf static.Providers) ProviderAggregator { p.quietAddProvider(conf.Docker) } - if conf.Marathon != nil { - p.quietAddProvider(conf.Marathon) - } - if conf.Rest != nil { p.quietAddProvider(conf.Rest) } @@ -100,10 +96,6 @@ func NewProviderAggregator(conf static.Providers) ProviderAggregator { p.quietAddProvider(conf.KubernetesGateway) } - if conf.Rancher != nil { - p.quietAddProvider(conf.Rancher) - } - if conf.Ecs != nil { p.quietAddProvider(conf.Ecs) } diff --git a/pkg/provider/aggregator/aggregator_test.go b/pkg/provider/aggregator/aggregator_test.go index 4bcf2bd7926e897178449c82e562dc699cdf461d..4683a2480038fc65bce211d9b6aa5b0c6391df3e 100644 --- a/pkg/provider/aggregator/aggregator_test.go +++ b/pkg/provider/aggregator/aggregator_test.go @@ -6,9 +6,9 @@ import ( "time" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" ) func TestProviderAggregator_Provide(t *testing.T) { diff --git a/pkg/provider/aggregator/ring_channel.go b/pkg/provider/aggregator/ring_channel.go index e69328da18dbac1b53c8864057383a1cf6580572..454a43a58b2f5d219255882989690dd9c58987a1 100644 --- a/pkg/provider/aggregator/ring_channel.go +++ b/pkg/provider/aggregator/ring_channel.go @@ -1,7 +1,7 @@ package aggregator import ( - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) // RingChannel implements a channel in a way that never blocks the writer. diff --git a/pkg/provider/configuration.go b/pkg/provider/configuration.go index c0119c885d8ae92b02f20b927e8abe618f4800ce..ebe57b92ecc77ffd3ac12e4c6052e33359c7f01b 100644 --- a/pkg/provider/configuration.go +++ b/pkg/provider/configuration.go @@ -11,8 +11,8 @@ import ( "github.com/Masterminds/sprig/v3" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" ) // Merge Merges multiple configurations. @@ -27,9 +27,10 @@ func Merge(ctx context.Context, configurations map[string]*dynamic.Configuration ServersTransports: make(map[string]*dynamic.ServersTransport), }, TCP: &dynamic.TCPConfiguration{ - Routers: make(map[string]*dynamic.TCPRouter), - Services: make(map[string]*dynamic.TCPService), - Middlewares: make(map[string]*dynamic.TCPMiddleware), + Routers: make(map[string]*dynamic.TCPRouter), + Services: make(map[string]*dynamic.TCPService), + Middlewares: make(map[string]*dynamic.TCPMiddleware), + ServersTransports: make(map[string]*dynamic.TCPServersTransport), }, UDP: &dynamic.UDPConfiguration{ Routers: make(map[string]*dynamic.UDPRouter), @@ -64,6 +65,9 @@ func Merge(ctx context.Context, configurations map[string]*dynamic.Configuration transportsToDelete := map[string]struct{}{} transports := map[string][]string{} + transportsTCPToDelete := map[string]struct{}{} + transportsTCP := map[string][]string{} + var sortedKeys []string for key := range configurations { sortedKeys = append(sortedKeys, key) @@ -107,6 +111,13 @@ func Merge(ctx context.Context, configurations map[string]*dynamic.Configuration } } + for transportName, transport := range conf.TCP.ServersTransports { + transportsTCP[transportName] = append(transportsTCP[transportName], root) + if !AddTransportTCP(configuration.TCP, transportName, transport) { + transportsTCPToDelete[transportName] = struct{}{} + } + } + for serviceName, service := range conf.UDP.Services { servicesUDP[serviceName] = append(servicesUDP[serviceName], root) if !AddServiceUDP(configuration.UDP, serviceName, service) { @@ -138,62 +149,78 @@ func Merge(ctx context.Context, configurations map[string]*dynamic.Configuration for serviceName := range servicesToDelete { logger.Error().Str(logs.ServiceName, serviceName). - Msgf("Service defined multiple times with different configurations in %v", services[serviceName]) + Interface("configuration", services[serviceName]). + Msg("Service defined multiple times with different configurations") delete(configuration.HTTP.Services, serviceName) } for routerName := range routersToDelete { logger.Error().Str(logs.RouterName, routerName). - Msgf("Router defined multiple times with different configurations in %v", routers[routerName]) + Interface("configuration", routers[routerName]). + Msg("Router defined multiple times with different configurations") delete(configuration.HTTP.Routers, routerName) } for transportName := range transportsToDelete { logger.Error().Str(logs.ServersTransportName, transportName). - Msgf("ServersTransport defined multiple times with different configurations in %v", transports[transportName]) + Interface("configuration", transports[transportName]). + Msg("ServersTransport defined multiple times with different configurations") delete(configuration.HTTP.ServersTransports, transportName) } for serviceName := range servicesTCPToDelete { logger.Error().Str(logs.ServiceName, serviceName). - Msgf("Service TCP defined multiple times with different configurations in %v", servicesTCP[serviceName]) + Interface("configuration", servicesTCP[serviceName]). + Msg("Service TCP defined multiple times with different configurations") delete(configuration.TCP.Services, serviceName) } for routerName := range routersTCPToDelete { logger.Error().Str(logs.RouterName, routerName). - Msgf("Router TCP defined multiple times with different configurations in %v", routersTCP[routerName]) + Interface("configuration", routersTCP[routerName]). + Msg("Router TCP defined multiple times with different configurations") delete(configuration.TCP.Routers, routerName) } + for transportName := range transportsTCPToDelete { + logger.Error().Str(logs.ServersTransportName, transportName). + Interface("configuration", transportsTCP[transportName]). + Msg("ServersTransport TCP defined multiple times with different configurations") + delete(configuration.TCP.ServersTransports, transportName) + } + for serviceName := range servicesUDPToDelete { logger.Error().Str(logs.ServiceName, serviceName). - Msgf("UDP service defined multiple times with different configurations in %v", servicesUDP[serviceName]) + Interface("configuration", servicesUDP[serviceName]). + Msg("UDP service defined multiple times with different configurations") delete(configuration.UDP.Services, serviceName) } for routerName := range routersUDPToDelete { logger.Error().Str(logs.RouterName, routerName). - Msgf("UDP router defined multiple times with different configurations in %v", routersUDP[routerName]) + Interface("configuration", routersUDP[routerName]). + Msg("UDP router defined multiple times with different configurations") delete(configuration.UDP.Routers, routerName) } for middlewareName := range middlewaresToDelete { logger.Error().Str(logs.MiddlewareName, middlewareName). - Msgf("Middleware defined multiple times with different configurations in %v", middlewares[middlewareName]) + Interface("configuration", middlewares[middlewareName]). + Msg("Middleware defined multiple times with different configurations") delete(configuration.HTTP.Middlewares, middlewareName) } for middlewareName := range middlewaresTCPToDelete { logger.Error().Str(logs.MiddlewareName, middlewareName). - Msgf("TCP Middleware defined multiple times with different configurations in %v", middlewaresTCP[middlewareName]) + Interface("configuration", middlewaresTCP[middlewareName]). + Msg("TCP Middleware defined multiple times with different configurations") delete(configuration.TCP.Middlewares, middlewareName) } return configuration } -// AddServiceTCP Adds a service to a configurations. +// AddServiceTCP adds a service to a configuration. func AddServiceTCP(configuration *dynamic.TCPConfiguration, serviceName string, service *dynamic.TCPService) bool { if _, ok := configuration.Services[serviceName]; !ok { configuration.Services[serviceName] = service @@ -218,7 +245,7 @@ func AddServiceTCP(configuration *dynamic.TCPConfiguration, serviceName string, return true } -// AddRouterTCP Adds a router to a configurations. +// AddRouterTCP adds a router to a configuration. func AddRouterTCP(configuration *dynamic.TCPConfiguration, routerName string, router *dynamic.TCPRouter) bool { if _, ok := configuration.Routers[routerName]; !ok { configuration.Routers[routerName] = router @@ -228,7 +255,7 @@ func AddRouterTCP(configuration *dynamic.TCPConfiguration, routerName string, ro return reflect.DeepEqual(configuration.Routers[routerName], router) } -// AddMiddlewareTCP Adds a middleware to a configurations. +// AddMiddlewareTCP adds a middleware to a configuration. func AddMiddlewareTCP(configuration *dynamic.TCPConfiguration, middlewareName string, middleware *dynamic.TCPMiddleware) bool { if _, ok := configuration.Middlewares[middlewareName]; !ok { configuration.Middlewares[middlewareName] = middleware @@ -238,6 +265,16 @@ func AddMiddlewareTCP(configuration *dynamic.TCPConfiguration, middlewareName st return reflect.DeepEqual(configuration.Middlewares[middlewareName], middleware) } +// AddTransportTCP adds a servers transport to a configuration. +func AddTransportTCP(configuration *dynamic.TCPConfiguration, transportName string, transport *dynamic.TCPServersTransport) bool { + if _, ok := configuration.ServersTransports[transportName]; !ok { + configuration.ServersTransports[transportName] = transport + return true + } + + return reflect.DeepEqual(configuration.ServersTransports[transportName], transport) +} + // AddServiceUDP adds a service to a configuration. func AddServiceUDP(configuration *dynamic.UDPConfiguration, serviceName string, service *dynamic.UDPService) bool { if _, ok := configuration.Services[serviceName]; !ok { @@ -273,7 +310,7 @@ func AddRouterUDP(configuration *dynamic.UDPConfiguration, routerName string, ro return reflect.DeepEqual(configuration.Routers[routerName], router) } -// AddService Adds a service to a configurations. +// AddService adds a service to a configuration. func AddService(configuration *dynamic.HTTPConfiguration, serviceName string, service *dynamic.Service) bool { if _, ok := configuration.Services[serviceName]; !ok { configuration.Services[serviceName] = service @@ -298,7 +335,7 @@ func AddService(configuration *dynamic.HTTPConfiguration, serviceName string, se return true } -// AddRouter Adds a router to a configurations. +// AddRouter adds a router to a configuration. func AddRouter(configuration *dynamic.HTTPConfiguration, routerName string, router *dynamic.Router) bool { if _, ok := configuration.Routers[routerName]; !ok { configuration.Routers[routerName] = router @@ -308,7 +345,7 @@ func AddRouter(configuration *dynamic.HTTPConfiguration, routerName string, rout return reflect.DeepEqual(configuration.Routers[routerName], router) } -// AddTransport Adds a transport to a configurations. +// AddTransport adds a servers transport to a configuration. func AddTransport(configuration *dynamic.HTTPConfiguration, transportName string, transport *dynamic.ServersTransport) bool { if _, ok := configuration.ServersTransports[transportName]; !ok { configuration.ServersTransports[transportName] = transport @@ -318,7 +355,7 @@ func AddTransport(configuration *dynamic.HTTPConfiguration, transportName string return reflect.DeepEqual(configuration.ServersTransports[transportName], transport) } -// AddMiddleware Adds a middleware to a configurations. +// AddMiddleware adds a middleware to a configuration. func AddMiddleware(configuration *dynamic.HTTPConfiguration, middlewareName string, middleware *dynamic.Middleware) bool { if _, ok := configuration.Middlewares[middlewareName]; !ok { configuration.Middlewares[middlewareName] = middleware diff --git a/pkg/provider/constraints/constraints_labels.go b/pkg/provider/constraints/constraints_labels.go index 6f194ba33072efc873251c4fe67f86e9bd391208..6d74bfbab2c1b7e78548650bdcb2916c0bbddda1 100644 --- a/pkg/provider/constraints/constraints_labels.go +++ b/pkg/provider/constraints/constraints_labels.go @@ -3,22 +3,16 @@ package constraints import ( "errors" "regexp" - "strings" "github.com/vulcand/predicate" ) -// MarathonConstraintPrefix is the prefix for each label's key created from a Marathon application constraint. -// It is used in order to create a specific and unique pattern for these labels. -const MarathonConstraintPrefix = "Traefik-Marathon-505F9E15-BDC7-45E7-828D-C06C7BAB8091" - type constraintLabelFunc func(map[string]string) bool // MatchLabels reports whether the expression matches with the given labels. // The expression must match any logical boolean combination of: // - `Label(labelName, labelValue)` -// - `LabelRegex(labelName, regexValue)` -// - `MarathonConstraint(field:operator:value)`. +// - `LabelRegex(labelName, regexValue)`. func MatchLabels(labels map[string]string, expr string) (bool, error) { if expr == "" { return true, nil @@ -31,9 +25,8 @@ func MatchLabels(labels map[string]string, expr string) (bool, error) { OR: orLabelFunc, }, Functions: map[string]interface{}{ - "Label": labelFn, - "LabelRegex": labelRegexFn, - "MarathonConstraint": marathonFn, + "Label": labelFn, + "LabelRegex": labelRegexFn, }, }) if err != nil { @@ -68,19 +61,6 @@ func labelRegexFn(name, expr string) constraintLabelFunc { } } -func marathonFn(value string) constraintLabelFunc { - return func(labels map[string]string) bool { - for k, v := range labels { - if strings.HasPrefix(k, MarathonConstraintPrefix) { - if v == value { - return true - } - } - } - return false - } -} - func andLabelFunc(a, b constraintLabelFunc) constraintLabelFunc { return func(labels map[string]string) bool { return a(labels) && b(labels) diff --git a/pkg/provider/constraints/constraints_labels_test.go b/pkg/provider/constraints/constraints_labels_test.go index 43fb9e0c6b8f7e6798c087683c96b1e1bd0662dd..8068735eb53990ee70fc6505c75b6a5d817ad48c 100644 --- a/pkg/provider/constraints/constraints_labels_test.go +++ b/pkg/provider/constraints/constraints_labels_test.go @@ -118,33 +118,6 @@ func TestMatchLabels(t *testing.T) { expr: ``, expected: true, }, - { - expr: `MarathonConstraint("bar")`, - labels: map[string]string{ - "hello": "world", - MarathonConstraintPrefix + "-1": "bar", - MarathonConstraintPrefix + "-2": "foo", - }, - expected: true, - }, - { - expr: `MarathonConstraint("bur")`, - labels: map[string]string{ - "hello": "world", - MarathonConstraintPrefix + "-1": "bar", - MarathonConstraintPrefix + "-2": "foo", - }, - expected: false, - }, - { - expr: `Label("hello", "world") && MarathonConstraint("bar")`, - labels: map[string]string{ - "hello": "world", - MarathonConstraintPrefix + "-1": "bar", - MarathonConstraintPrefix + "-2": "foo", - }, - expected: true, - }, { expr: `LabelRegex("hello", "w\\w+")`, labels: map[string]string{ diff --git a/pkg/provider/consulcatalog/config.go b/pkg/provider/consulcatalog/config.go index af8e7830c1ee87e40f58d8e328f4a2aadf7cee92..14c4fcc8707c89190b4850bd49a24cb0984a7c63 100644 --- a/pkg/provider/consulcatalog/config.go +++ b/pkg/provider/consulcatalog/config.go @@ -11,11 +11,11 @@ import ( "github.com/hashicorp/consul/api" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/label" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/constraints" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/label" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/constraints" ) func (p *Provider) buildConfiguration(ctx context.Context, items []itemData, certInfo *connectCert) *dynamic.Configuration { @@ -41,6 +41,17 @@ func (p *Provider) buildConfiguration(ctx context.Context, items []itemData, cer if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 { tcpOrUDP = true + if item.ExtraConf.ConsulCatalog.Connect { + if confFromLabel.TCP.ServersTransports == nil { + confFromLabel.TCP.ServersTransports = make(map[string]*dynamic.TCPServersTransport) + } + + serversTransportKey := itemServersTransportKey(item) + if confFromLabel.TCP.ServersTransports[serversTransportKey] == nil { + confFromLabel.TCP.ServersTransports[serversTransportKey] = certInfo.tcpServersTransport(item) + } + } + if err := p.buildTCPServiceConfiguration(item, confFromLabel.TCP); err != nil { logger.Error().Err(err).Send() continue @@ -131,13 +142,10 @@ func (p *Provider) keepContainer(ctx context.Context, item itemData) bool { func (p *Provider) buildTCPServiceConfiguration(item itemData, configuration *dynamic.TCPConfiguration) error { if len(configuration.Services) == 0 { - configuration.Services = make(map[string]*dynamic.TCPService) - - lb := &dynamic.TCPServersLoadBalancer{} - lb.SetDefaults() - - configuration.Services[getName(item)] = &dynamic.TCPService{ - LoadBalancer: lb, + configuration.Services = map[string]*dynamic.TCPService{ + getName(item): { + LoadBalancer: new(dynamic.TCPServersLoadBalancer), + }, } } @@ -215,6 +223,14 @@ func (p *Provider) addServerTCP(item itemData, loadBalancer *dynamic.TCPServersL return errors.New("port is missing") } + if item.Address == "" { + return errors.New("address is missing") + } + + if item.ExtraConf.ConsulCatalog.Connect { + loadBalancer.ServersTransport = itemServersTransportKey(item) + } + loadBalancer.Servers[0].Address = net.JoinHostPort(item.Address, port) return nil diff --git a/pkg/provider/consulcatalog/config_test.go b/pkg/provider/consulcatalog/config_test.go index 583ed27cc9a0e1dbf759cf754d95da24786ba9a2..d1a60655481abf65b678f15256bde88a9bbf2346 100644 --- a/pkg/provider/consulcatalog/config_test.go +++ b/pkg/provider/consulcatalog/config_test.go @@ -10,8 +10,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/tls" ) func Int(v int) *int { return &v } @@ -40,9 +40,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: "Host(`foo.bar`)", expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -93,9 +94,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: `Host("{{ .Name }}.{{ index .Labels "traefik.domain" }}")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -144,9 +146,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: `Host("{{ .Toto }}")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -190,9 +193,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: ``, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -236,9 +240,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: defaultTemplateRule, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -324,9 +329,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -380,9 +386,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Services: map[string]*dynamic.TCPService{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, + Routers: map[string]*dynamic.TCPRouter{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -466,9 +473,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Services: map[string]*dynamic.TCPService{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, + Routers: map[string]*dynamic.TCPRouter{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -544,9 +552,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -620,9 +629,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -682,9 +692,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -741,9 +752,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -795,9 +807,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -848,9 +861,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -899,9 +913,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -951,9 +966,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1004,9 +1020,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1072,9 +1089,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1129,9 +1147,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1176,9 +1195,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1230,9 +1250,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1296,9 +1317,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1365,9 +1387,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1441,9 +1464,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1509,9 +1533,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1580,9 +1605,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1644,9 +1670,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1698,9 +1725,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1750,9 +1778,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1802,9 +1831,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1859,9 +1889,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1890,9 +1921,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1921,9 +1953,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1952,9 +1985,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1985,9 +2019,10 @@ func Test_buildConfiguration(t *testing.T) { constraints: `Tag("traefik.tags=bar")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2018,9 +2053,10 @@ func Test_buildConfiguration(t *testing.T) { constraints: `Tag("traefik.tags=foo")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2070,9 +2106,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2155,10 +2192,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2173,14 +2210,19 @@ func Test_buildConfiguration(t *testing.T) { }, }, { - desc: "tcp with label", + desc: "tcp with label", + ConnectAware: true, items: []itemData{ { - ID: "Test", - Name: "Test", + ID: "Test", + Node: "Node1", + Datacenter: "dc1", + Name: "Test", + Namespace: "ns", Labels: map[string]string{ - "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.routers.foo.tls": "true", + "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", + "traefik.tcp.routers.foo.tls": "true", + "traefik.consulcatalog.connect": "true", }, Address: "127.0.0.1", Port: "80", @@ -2205,7 +2247,25 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), + ServersTransport: "tls-ns-dc1-Test", + }, + }, + }, + ServersTransports: map[string]*dynamic.TCPServersTransport{ + "tls-ns-dc1-Test": { + TLS: &dynamic.TLSClientConfig{ + ServerName: "ns-dc1-Test", + InsecureSkipVerify: true, + RootCAs: []tls.FileOrContent{ + "root", + }, + Certificates: []tls.Certificate{ + { + CertFile: "cert", + KeyFile: "key", + }, + }, + PeerCertURI: "spiffe:///ns/ns/dc/dc1/svc/Test", }, }, }, @@ -2257,9 +2317,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2295,10 +2356,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2348,10 +2409,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:8080", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2401,9 +2462,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2464,10 +2526,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.2:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2555,9 +2617,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2615,10 +2678,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2662,9 +2725,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2675,14 +2739,14 @@ func Test_buildConfiguration(t *testing.T) { }, }, { + // TODO: replace or delete? desc: "tcp with label for tcp service, with termination delay", items: []itemData{ { ID: "Test", Name: "Test", Labels: map[string]string{ - "traefik.tcp.services.foo.loadbalancer.server.port": "80", - "traefik.tcp.services.foo.loadbalancer.terminationdelay": "200", + "traefik.tcp.services.foo.loadbalancer.server.port": "80", }, Address: "127.0.0.1", Port: "80", @@ -2701,10 +2765,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(200), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2752,9 +2816,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2872,7 +2937,6 @@ func Test_buildConfiguration(t *testing.T) { Servers: []dynamic.TCPServer{ {Address: "127.0.0.1:80"}, }, - TerminationDelay: Int(100), }, }, "Test-17573747155436217342": { @@ -2880,10 +2944,10 @@ func Test_buildConfiguration(t *testing.T) { Servers: []dynamic.TCPServer{ {Address: "127.0.0.2:80"}, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2931,9 +2995,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{ @@ -2993,9 +3058,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{ diff --git a/pkg/provider/consulcatalog/connect_tls.go b/pkg/provider/consulcatalog/connect_tls.go index 5b7a927398b9d55049ce165d6f4ec9bef9c7ce60..904131283cf087afc1b805fa1918bbefaa898506 100644 --- a/pkg/provider/consulcatalog/connect_tls.go +++ b/pkg/provider/consulcatalog/connect_tls.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/hashicorp/consul/agent/connect" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" ) // connectCert holds our certificates as a client of the Consul Connect protocol. @@ -70,3 +70,25 @@ func (c *connectCert) serversTransport(item itemData) *dynamic.ServersTransport PeerCertURI: spiffeIDService.URI().String(), } } + +func (c *connectCert) tcpServersTransport(item itemData) *dynamic.TCPServersTransport { + spiffeIDService := connect.SpiffeIDService{ + Namespace: item.Namespace, + Datacenter: item.Datacenter, + Service: item.Name, + } + + return &dynamic.TCPServersTransport{ + TLS: &dynamic.TLSClientConfig{ + // This ensures that the config changes whenever the verifier function changes + ServerName: fmt.Sprintf("%s-%s-%s", item.Namespace, item.Datacenter, item.Name), + // InsecureSkipVerify is needed because Go wants to verify a hostname otherwise + InsecureSkipVerify: true, + RootCAs: c.getRoot(), + Certificates: traefiktls.Certificates{ + c.getLeaf(), + }, + PeerCertURI: spiffeIDService.URI().String(), + }, + } +} diff --git a/pkg/provider/consulcatalog/consul_catalog.go b/pkg/provider/consulcatalog/consul_catalog.go index af8c7e2f7737192587e422a48a587af8859d11b8..696214e0cdfa0e52ed5eacb84f32f34373a622fc 100644 --- a/pkg/provider/consulcatalog/consul_catalog.go +++ b/pkg/provider/consulcatalog/consul_catalog.go @@ -14,13 +14,13 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/constraints" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/job" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/constraints" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/types" ) // defaultTemplateRule is the default template for the default rule. diff --git a/pkg/provider/consulcatalog/label.go b/pkg/provider/consulcatalog/label.go index 65178750c07e340227fdb391907e24462cc94f5c..dd71e934797a5b6e9bc2b304e05daed653a94170 100644 --- a/pkg/provider/consulcatalog/label.go +++ b/pkg/provider/consulcatalog/label.go @@ -1,7 +1,7 @@ package consulcatalog import ( - "github.com/traefik/traefik/v2/pkg/config/label" + "github.com/traefik/traefik/v3/pkg/config/label" ) // configuration contains information from the labels that are globals (not related to the dynamic configuration) or specific to the provider. diff --git a/pkg/provider/docker/config.go b/pkg/provider/docker/config.go index e23575caf5cf9b63409db03ea463902c56101a90..53ff07fe162065b5d7f07ee42ae612daca432c73 100644 --- a/pkg/provider/docker/config.go +++ b/pkg/provider/docker/config.go @@ -10,11 +10,11 @@ import ( dockertypes "github.com/docker/docker/api/types" "github.com/docker/go-connections/nat" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/label" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/constraints" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/label" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/constraints" ) func (p *Provider) buildConfiguration(ctx context.Context, containersInspected []dockerData) *dynamic.Configuration { @@ -75,11 +75,13 @@ func (p *Provider) buildConfiguration(ctx context.Context, containersInspected [ serviceName := getServiceName(container) model := struct { - Name string - Labels map[string]string + Name string + ContainerName string + Labels map[string]string }{ - Name: serviceName, - Labels: container.Labels, + Name: serviceName, + ContainerName: strings.TrimPrefix(container.Name, "/"), + Labels: container.Labels, } provider.BuildRouterConfiguration(ctx, confFromLabel.HTTP, serviceName, p.defaultRuleTpl, model) @@ -94,11 +96,10 @@ func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, container d serviceName := getServiceName(container) if len(configuration.Services) == 0 { - configuration.Services = make(map[string]*dynamic.TCPService) - lb := &dynamic.TCPServersLoadBalancer{} - lb.SetDefaults() - configuration.Services[serviceName] = &dynamic.TCPService{ - LoadBalancer: lb, + configuration.Services = map[string]*dynamic.TCPService{ + serviceName: { + LoadBalancer: new(dynamic.TCPServersLoadBalancer), + }, } } diff --git a/pkg/provider/docker/config_test.go b/pkg/provider/docker/config_test.go index 6038cf4decd0befefe328ff43f189466898be796..5f0048b2ac3748a632add5a52c9d4f27c8e7e666 100644 --- a/pkg/provider/docker/config_test.go +++ b/pkg/provider/docker/config_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestDefaultRule(t *testing.T) { @@ -45,9 +45,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: "Host(`foo.bar`)", expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -103,9 +104,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: "Host(`{{ .Name }}.foo.bar`)", expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -163,9 +165,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: `Host("{{ .Name }}.{{ index .Labels "traefik.domain" }}")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -221,9 +224,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: `Host("{{ .Toto }}")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -274,9 +278,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: ``, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -327,9 +332,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: DefaultTemplateRule, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -423,9 +429,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -463,9 +470,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -503,9 +511,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -541,9 +550,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -614,9 +624,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -706,9 +717,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -768,9 +780,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -829,9 +842,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -888,9 +902,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -948,9 +963,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1009,9 +1025,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1077,9 +1094,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1156,9 +1174,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1240,9 +1259,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1305,9 +1325,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1367,9 +1388,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1452,9 +1474,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1540,9 +1563,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1641,9 +1665,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1726,9 +1751,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1822,9 +1848,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1902,9 +1929,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1982,9 +2010,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2049,9 +2078,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2109,9 +2139,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2169,9 +2200,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2232,9 +2264,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2270,9 +2303,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2310,9 +2344,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2337,9 +2372,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2365,9 +2401,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2409,9 +2446,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2449,11 +2487,10 @@ func Test_buildConfiguration(t *testing.T) { Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ "Test": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - TerminationDelay: Int(100), - }, + LoadBalancer: &dynamic.TCPServersLoadBalancer{}, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2481,9 +2518,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2512,9 +2550,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{ @@ -2561,9 +2600,10 @@ func Test_buildConfiguration(t *testing.T) { constraints: `Label("traefik.tags", "bar")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2602,9 +2642,10 @@ func Test_buildConfiguration(t *testing.T) { constraints: `Label("traefik.tags", "foo")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2662,9 +2703,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2755,10 +2797,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2813,10 +2855,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2873,9 +2915,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2919,10 +2962,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2980,10 +3023,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:8080", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -3041,9 +3084,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3122,9 +3166,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3194,9 +3239,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3207,14 +3253,14 @@ func Test_buildConfiguration(t *testing.T) { }, }, { + // TODO: replace or delete? desc: "tcp with label for tcp service, with termination delay", containers: []dockerData{ { ServiceName: "Test", Name: "Test", Labels: map[string]string{ - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - "traefik.tcp.services.foo.loadbalancer.terminationdelay": "200", + "traefik.tcp.services.foo.loadbalancer.server.port": "8080", }, NetworkSettings: networkSettings{ Ports: nat.PortMap{ @@ -3241,10 +3287,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:8080", }, }, - TerminationDelay: Int(200), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -3290,9 +3336,10 @@ func Test_buildConfiguration(t *testing.T) { useBindPortIP: true, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, diff --git a/pkg/provider/docker/docker.go b/pkg/provider/docker/docker.go index 2e902cf8aafe97a92493c196dc3c414a16d3edaa..ec48f714ce308bdeb9917619e63d41044fa050c3 100644 --- a/pkg/provider/docker/docker.go +++ b/pkg/provider/docker/docker.go @@ -25,13 +25,13 @@ import ( "github.com/docker/go-connections/sockets" "github.com/rs/zerolog/log" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" - "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/job" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/types" + "github.com/traefik/traefik/v3/pkg/version" ) const ( diff --git a/pkg/provider/docker/label.go b/pkg/provider/docker/label.go index f86de21667c54ce9c16514813582498da09cb276..b968eedf1af9fc6c8640dccbc9306b2fd2ff9dff 100644 --- a/pkg/provider/docker/label.go +++ b/pkg/provider/docker/label.go @@ -3,7 +3,7 @@ package docker import ( "fmt" - "github.com/traefik/traefik/v2/pkg/config/label" + "github.com/traefik/traefik/v3/pkg/config/label" ) const ( diff --git a/pkg/provider/ecs/config.go b/pkg/provider/ecs/config.go index 8dbdf15502862e236ce7858644ae14591768c88e..e53c7480eb415596a3b89b4f8cfcf4225b3785f3 100644 --- a/pkg/provider/ecs/config.go +++ b/pkg/provider/ecs/config.go @@ -11,10 +11,10 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" "github.com/docker/go-connections/nat" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/label" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/constraints" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/label" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/constraints" ) func (p *Provider) buildConfiguration(ctx context.Context, instances []ecsInstance) *dynamic.Configuration { @@ -93,11 +93,10 @@ func (p *Provider) buildTCPServiceConfiguration(instance ecsInstance, configurat serviceName := getServiceName(instance) if len(configuration.Services) == 0 { - configuration.Services = make(map[string]*dynamic.TCPService) - lb := &dynamic.TCPServersLoadBalancer{} - lb.SetDefaults() - configuration.Services[serviceName] = &dynamic.TCPService{ - LoadBalancer: lb, + configuration.Services = map[string]*dynamic.TCPService{ + serviceName: { + LoadBalancer: new(dynamic.TCPServersLoadBalancer), + }, } } diff --git a/pkg/provider/ecs/config_test.go b/pkg/provider/ecs/config_test.go index c0bd40a789646727afa94409c1e434cd73fc9363..aac4d9cfdee6ac904a885825c5a0578e9cb5d5ee 100644 --- a/pkg/provider/ecs/config_test.go +++ b/pkg/provider/ecs/config_test.go @@ -9,7 +9,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func Int(v int) *int { return &v } @@ -41,9 +41,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: "Host(`foo.bar`)", expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -94,9 +95,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: "Host(`{{ .Name }}.foo.bar`)", expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -149,9 +151,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: `Host("{{ .Name }}.{{ index .Labels "traefik.domain" }}")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -202,9 +205,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: `Host("{{ .Toto }}")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -250,9 +254,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: ``, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -298,9 +303,10 @@ func TestDefaultRule(t *testing.T) { defaultRule: DefaultTemplateRule, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -388,9 +394,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -423,9 +430,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -458,9 +466,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -491,9 +500,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -554,9 +564,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -636,9 +647,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -693,9 +705,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -749,9 +762,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -803,9 +817,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -858,9 +873,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -914,9 +930,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -977,9 +994,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1046,9 +1064,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1115,9 +1134,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1170,9 +1190,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1227,9 +1248,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1302,9 +1324,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1380,9 +1403,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1466,9 +1490,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1541,9 +1566,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1622,9 +1648,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1693,9 +1720,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1763,9 +1791,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1825,9 +1854,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1880,9 +1910,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1935,9 +1966,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1995,9 +2027,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2067,9 +2100,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2125,9 +2159,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2158,9 +2193,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2193,9 +2229,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2229,9 +2266,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2264,9 +2302,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2300,9 +2339,10 @@ func Test_buildConfiguration(t *testing.T) { constraints: `Label("traefik.tags", "bar")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2336,9 +2376,10 @@ func Test_buildConfiguration(t *testing.T) { constraints: `Label("traefik.tags", "foo")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2391,9 +2432,10 @@ func Test_buildConfiguration(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2479,10 +2521,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2532,10 +2574,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2587,9 +2629,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2628,10 +2671,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2684,10 +2727,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:8080", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2740,9 +2783,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2811,9 +2855,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2878,9 +2923,10 @@ func Test_buildConfiguration(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2891,13 +2937,13 @@ func Test_buildConfiguration(t *testing.T) { }, }, { + // TODO: replace or delete? desc: "tcp with label for tcp service, with termination delay", containers: []ecsInstance{ instance( name("Test"), labels(map[string]string{ - "traefik.tcp.services.foo.loadbalancer.server.port": "80", - "traefik.tcp.services.foo.loadbalancer.terminationdelay": "200", + "traefik.tcp.services.foo.loadbalancer.server.port": "80", }), iMachine( mState(ec2.InstanceStateNameRunning), @@ -2920,10 +2966,10 @@ func Test_buildConfiguration(t *testing.T) { Address: "127.0.0.1:8080", }, }, - TerminationDelay: Int(200), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, diff --git a/pkg/provider/ecs/ecs.go b/pkg/provider/ecs/ecs.go index 22e3e5695d2445a925e772a679564cae09691ac3..93337c766b2ad8870e0042aa798a153538fd6a19 100644 --- a/pkg/provider/ecs/ecs.go +++ b/pkg/provider/ecs/ecs.go @@ -19,11 +19,11 @@ import ( "github.com/patrickmn/go-cache" "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/job" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" ) // Provider holds configurations of the provider. @@ -320,6 +320,11 @@ func (p *Provider) listInstances(ctx context.Context, client *awsClient) ([]ecsI var mach *machine if len(task.Attachments) != 0 { + if len(container.NetworkInterfaces) == 0 { + logger.Error().Msgf("Skip container %s: no network interfaces", aws.StringValue(container.Name)) + continue + } + var ports []portMapping for _, mapping := range containerDefinition.PortMappings { if mapping != nil { diff --git a/pkg/provider/ecs/label.go b/pkg/provider/ecs/label.go index 0f3b2a8b3cf514bd4c8056312523d9fcff54f4e7..7a01a93fffbc16eefe08ab706b766984d8cd2e3a 100644 --- a/pkg/provider/ecs/label.go +++ b/pkg/provider/ecs/label.go @@ -1,7 +1,7 @@ package ecs import ( - "github.com/traefik/traefik/v2/pkg/config/label" + "github.com/traefik/traefik/v3/pkg/config/label" ) // configuration Contains information from the labels that are globals (not related to the dynamic configuration) or specific to the provider. diff --git a/pkg/provider/file/file.go b/pkg/provider/file/file.go index 839986cf8e4c65b8d89d2aeb74e81c65b38f17c5..938252664e608f9029f89580b2f828167c251bdc 100644 --- a/pkg/provider/file/file.go +++ b/pkg/provider/file/file.go @@ -13,11 +13,11 @@ import ( "github.com/Masterminds/sprig/v3" "github.com/rs/zerolog/log" "github.com/traefik/paerser/file" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/tls" "gopkg.in/fsnotify.v1" ) @@ -47,11 +47,6 @@ func (p *Provider) Init() error { // Provide allows the file provider to provide configurations to traefik // using the given configuration channel. func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error { - configuration, err := p.BuildConfiguration() - if err != nil { - return err - } - if p.Watch { var watchItem string @@ -69,6 +64,19 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe. } } + configuration, err := p.BuildConfiguration() + if err != nil { + if p.Watch { + log.Debug(). + Str(logs.ProviderName, providerName). + Err(err). + Msg("Error while building configuration (for the first time)") + + return nil + } + return err + } + sendConfigToChannel(configurationChan, configuration) return nil } @@ -215,7 +223,7 @@ func (p *Provider) loadFileConfig(ctx context.Context, filename string, parseTem } } - // ServersTransport + // HTTP ServersTransport if configuration.HTTP != nil && len(configuration.HTTP.ServersTransports) > 0 { for name, st := range configuration.HTTP.ServersTransports { var certificates []tls.Certificate @@ -254,6 +262,48 @@ func (p *Provider) loadFileConfig(ctx context.Context, filename string, parseTem } } + // TCP ServersTransport + if configuration.TCP != nil && len(configuration.TCP.ServersTransports) > 0 { + for name, st := range configuration.TCP.ServersTransports { + var certificates []tls.Certificate + if st.TLS == nil { + continue + } + for _, cert := range st.TLS.Certificates { + content, err := cert.CertFile.Read() + if err != nil { + log.Ctx(ctx).Error().Err(err).Send() + continue + } + cert.CertFile = tls.FileOrContent(content) + + content, err = cert.KeyFile.Read() + if err != nil { + log.Ctx(ctx).Error().Err(err).Send() + continue + } + cert.KeyFile = tls.FileOrContent(content) + + certificates = append(certificates, cert) + } + + configuration.TCP.ServersTransports[name].TLS.Certificates = certificates + + var rootCAs []tls.FileOrContent + for _, rootCA := range st.TLS.RootCAs { + content, err := rootCA.Read() + if err != nil { + log.Ctx(ctx).Error().Err(err).Send() + continue + } + + rootCAs = append(rootCAs, tls.FileOrContent(content)) + } + + st.TLS.RootCAs = rootCAs + } + } + return configuration, nil } @@ -295,9 +345,10 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st ServersTransports: make(map[string]*dynamic.ServersTransport), }, TCP: &dynamic.TCPConfiguration{ - Routers: make(map[string]*dynamic.TCPRouter), - Services: make(map[string]*dynamic.TCPService), - Middlewares: make(map[string]*dynamic.TCPMiddleware), + Routers: make(map[string]*dynamic.TCPRouter), + Services: make(map[string]*dynamic.TCPService), + Middlewares: make(map[string]*dynamic.TCPMiddleware), + ServersTransports: make(map[string]*dynamic.TCPServersTransport), }, TLS: &dynamic.TLSConfiguration{ Stores: make(map[string]tls.Store), @@ -392,6 +443,14 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st } } + for name, conf := range c.TCP.ServersTransports { + if _, exists := configuration.TCP.ServersTransports[name]; exists { + logger.Warn().Str(logs.ServersTransportName, name).Msg("TCP servers transport already configured, skipping") + } else { + configuration.TCP.ServersTransports[name] = conf + } + } + for name, conf := range c.UDP.Routers { if _, exists := configuration.UDP.Routers[name]; exists { logger.Warn().Str(logs.RouterName, name).Msg("UDP router already configured, skipping") @@ -506,9 +565,10 @@ func (p *Provider) decodeConfiguration(filePath, content string) (*dynamic.Confi ServersTransports: make(map[string]*dynamic.ServersTransport), }, TCP: &dynamic.TCPConfiguration{ - Routers: make(map[string]*dynamic.TCPRouter), - Services: make(map[string]*dynamic.TCPService), - Middlewares: make(map[string]*dynamic.TCPMiddleware), + Routers: make(map[string]*dynamic.TCPRouter), + Services: make(map[string]*dynamic.TCPService), + Middlewares: make(map[string]*dynamic.TCPMiddleware), + ServersTransports: make(map[string]*dynamic.TCPServersTransport), }, TLS: &dynamic.TLSConfiguration{ Stores: make(map[string]tls.Store), diff --git a/pkg/provider/file/file_test.go b/pkg/provider/file/file_test.go index 76fb4928297df008bb53de814299bd0e4ad8fcd1..57128030695598ecfbd058d0b951c8f5b2574d7a 100644 --- a/pkg/provider/file/file_test.go +++ b/pkg/provider/file/file_test.go @@ -11,8 +11,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/safe" ) type ProvideTestCase struct { @@ -54,6 +54,13 @@ func TestTLSCertificateContent(t *testing.T) { [[http.serversTransports.default.certificates]] certFile = "` + fileTLS.Name() + `" keyFile = "` + fileTLSKey.Name() + `" + +[tcp.serversTransports.default] + [tcp.serversTransports.default.tls] + rootCAs = ["` + fileTLS.Name() + `"] + [[tcp.serversTransports.default.tls.certificates]] + certFile = "` + fileTLS.Name() + `" + keyFile = "` + fileTLSKey.Name() + `" ` _, err = fileConfig.Write([]byte(content)) @@ -74,6 +81,10 @@ func TestTLSCertificateContent(t *testing.T) { require.Equal(t, "CONTENT", configuration.HTTP.ServersTransports["default"].Certificates[0].CertFile.String()) require.Equal(t, "CONTENTKEY", configuration.HTTP.ServersTransports["default"].Certificates[0].KeyFile.String()) require.Equal(t, "CONTENT", configuration.HTTP.ServersTransports["default"].RootCAs[0].String()) + + require.Equal(t, "CONTENT", configuration.TCP.ServersTransports["default"].TLS.Certificates[0].CertFile.String()) + require.Equal(t, "CONTENTKEY", configuration.TCP.ServersTransports["default"].TLS.Certificates[0].KeyFile.String()) + require.Equal(t, "CONTENT", configuration.TCP.ServersTransports["default"].TLS.RootCAs[0].String()) } func TestErrorWhenEmptyConfig(t *testing.T) { diff --git a/pkg/provider/http/http.go b/pkg/provider/http/http.go index e8ad5b8e7b4ea67fbdc63fb6d74bf0fb235c3f63..c354e5f8b29104bee2c96f8f1bbe344b53c18ac4 100644 --- a/pkg/provider/http/http.go +++ b/pkg/provider/http/http.go @@ -12,13 +12,13 @@ import ( "github.com/rs/zerolog/log" "github.com/traefik/paerser/file" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/job" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" ) var _ provider.Provider = (*Provider)(nil) @@ -175,8 +175,9 @@ func decodeConfiguration(data []byte) (*dynamic.Configuration, error) { ServersTransports: make(map[string]*dynamic.ServersTransport), }, TCP: &dynamic.TCPConfiguration{ - Routers: make(map[string]*dynamic.TCPRouter), - Services: make(map[string]*dynamic.TCPService), + Routers: make(map[string]*dynamic.TCPRouter), + Services: make(map[string]*dynamic.TCPService), + ServersTransports: make(map[string]*dynamic.TCPServersTransport), }, TLS: &dynamic.TLSConfiguration{ Stores: make(map[string]tls.Store), diff --git a/pkg/provider/http/http_test.go b/pkg/provider/http/http_test.go index 97f020c3bca098d2d4d3a793e50269ad9c820327..d805dd3c43b5635f9a1bb3235342ab2c5a224770 100644 --- a/pkg/provider/http/http_test.go +++ b/pkg/provider/http/http_test.go @@ -11,9 +11,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/tls" ) func TestProvider_Init(t *testing.T) { @@ -158,7 +158,8 @@ func TestProvider_decodeConfiguration(t *testing.T) { Routers: map[string]*dynamic.TCPRouter{ "foo": {}, }, - Services: make(map[string]*dynamic.TCPService), + Services: make(map[string]*dynamic.TCPService), + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{ Stores: make(map[string]tls.Store), @@ -214,8 +215,9 @@ func TestProvider_Provide(t *testing.T) { ServersTransports: make(map[string]*dynamic.ServersTransport), }, TCP: &dynamic.TCPConfiguration{ - Routers: make(map[string]*dynamic.TCPRouter), - Services: make(map[string]*dynamic.TCPService), + Routers: make(map[string]*dynamic.TCPRouter), + Services: make(map[string]*dynamic.TCPService), + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{ Stores: make(map[string]tls.Store), diff --git a/pkg/provider/hub/handler.go b/pkg/provider/hub/handler.go index 23cc47b1e0ff262075cd9475c930c5c8ca55964e..86014cb7c2b15af0e678f876737e67890946efaf 100644 --- a/pkg/provider/hub/handler.go +++ b/pkg/provider/hub/handler.go @@ -10,7 +10,7 @@ import ( "sync/atomic" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) type handler struct { diff --git a/pkg/provider/hub/handler_test.go b/pkg/provider/hub/handler_test.go index b69fc8b6d56a43195484f14dee99a0a68d98b044..bc13f90c0f20c9b377c29dbe48cf94e7e89a504e 100644 --- a/pkg/provider/hub/handler_test.go +++ b/pkg/provider/hub/handler_test.go @@ -15,8 +15,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/tls/generate" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/tls/generate" ) func TestHandleConfig(t *testing.T) { diff --git a/pkg/provider/hub/hub.go b/pkg/provider/hub/hub.go index c44cb7e9723076a9e51d0ae18aff5f489f4dbded..f1120cc80b00e8394667e78ffb4d23c0cd090ee0 100644 --- a/pkg/provider/hub/hub.go +++ b/pkg/provider/hub/hub.go @@ -9,11 +9,11 @@ import ( "net/http" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" - ttls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" + ttls "github.com/traefik/traefik/v3/pkg/tls" ) var _ provider.Provider = (*Provider)(nil) @@ -152,8 +152,9 @@ func emptyDynamicConfiguration() *dynamic.Configuration { ServersTransports: make(map[string]*dynamic.ServersTransport), }, TCP: &dynamic.TCPConfiguration{ - Routers: make(map[string]*dynamic.TCPRouter), - Services: make(map[string]*dynamic.TCPService), + Routers: make(map[string]*dynamic.TCPRouter), + Services: make(map[string]*dynamic.TCPService), + ServersTransports: make(map[string]*dynamic.TCPServersTransport), }, TLS: &dynamic.TLSConfiguration{ Stores: make(map[string]ttls.Store), diff --git a/pkg/provider/kubernetes/crd/client.go b/pkg/provider/kubernetes/crd/client.go index 0b40a91aad496de4bd966416a1de31df3492ae54..44e0cb29c854855ed26fea73caf9dbe708bacab1 100644 --- a/pkg/provider/kubernetes/crd/client.go +++ b/pkg/provider/kubernetes/crd/client.go @@ -9,11 +9,11 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" - "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s" + "github.com/traefik/traefik/v3/pkg/version" corev1 "k8s.io/api/core/v1" kubeerror "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -40,6 +40,7 @@ type Client interface { GetTraefikServices() []*v1alpha1.TraefikService GetTLSOptions() []*v1alpha1.TLSOption GetServersTransports() []*v1alpha1.ServersTransport + GetServersTransportTCPs() []*v1alpha1.ServersTransportTCP GetTLSStores() []*v1alpha1.TLSStore GetService(namespace, name string) (*corev1.Service, bool, error) GetSecret(namespace, name string) (*corev1.Secret, bool, error) @@ -170,6 +171,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< factoryCrd.Traefik().V1alpha1().IngressRouteUDPs().Informer().AddEventHandler(eventHandler) factoryCrd.Traefik().V1alpha1().TLSOptions().Informer().AddEventHandler(eventHandler) factoryCrd.Traefik().V1alpha1().ServersTransports().Informer().AddEventHandler(eventHandler) + factoryCrd.Traefik().V1alpha1().ServersTransportTCPs().Informer().AddEventHandler(eventHandler) factoryCrd.Traefik().V1alpha1().TLSStores().Informer().AddEventHandler(eventHandler) factoryCrd.Traefik().V1alpha1().TraefikServices().Informer().AddEventHandler(eventHandler) @@ -300,11 +302,11 @@ func (c *clientWrapper) GetTraefikServices() []*v1alpha1.TraefikService { var result []*v1alpha1.TraefikService for ns, factory := range c.factoriesCrd { - ings, err := factory.Traefik().V1alpha1().TraefikServices().Lister().List(labels.Everything()) + traefikServices, err := factory.Traefik().V1alpha1().TraefikServices().Lister().List(labels.Everything()) if err != nil { log.Error().Err(err).Msgf("Failed to list Traefik services in namespace %s", ns) } - result = append(result, ings...) + result = append(result, traefikServices...) } return result @@ -317,7 +319,22 @@ func (c *clientWrapper) GetServersTransports() []*v1alpha1.ServersTransport { for ns, factory := range c.factoriesCrd { serversTransports, err := factory.Traefik().V1alpha1().ServersTransports().Lister().List(labels.Everything()) if err != nil { - log.Error().Err(err).Msgf("Failed to list servers transport in namespace %s", ns) + log.Error().Err(err).Str("namespace", ns).Msg("Failed to list servers transport in namespace") + } + result = append(result, serversTransports...) + } + + return result +} + +// GetServersTransportTCPs returns all ServersTransportTCP. +func (c *clientWrapper) GetServersTransportTCPs() []*v1alpha1.ServersTransportTCP { + var result []*v1alpha1.ServersTransportTCP + + for ns, factory := range c.factoriesCrd { + serversTransports, err := factory.Traefik().V1alpha1().ServersTransportTCPs().Lister().List(labels.Everything()) + if err != nil { + log.Error().Err(err).Str("namespace", ns).Msg("Failed to list servers transport TCP in namespace") } result = append(result, serversTransports...) } @@ -401,15 +418,6 @@ func (c *clientWrapper) lookupNamespace(ns string) string { return ns } -// translateNotFoundError will translate a "not found" error to a boolean return -// value which indicates if the resource exists and a nil error. -func translateNotFoundError(err error) (bool, error) { - if kubeerror.IsNotFound(err) { - return false, nil - } - return err == nil, err -} - // isWatchedNamespace checks to ensure that the namespace is being watched before we request // it to ensure we don't panic by requesting an out-of-watch object. func (c *clientWrapper) isWatchedNamespace(ns string) bool { @@ -423,3 +431,12 @@ func (c *clientWrapper) isWatchedNamespace(ns string) bool { } return false } + +// translateNotFoundError will translate a "not found" error to a boolean return +// value which indicates if the resource exists and a nil error. +func translateNotFoundError(err error) (bool, error) { + if kubeerror.IsNotFound(err) { + return false, nil + } + return err == nil, err +} diff --git a/pkg/provider/kubernetes/crd/client_mock_test.go b/pkg/provider/kubernetes/crd/client_mock_test.go index 5e018ca6dfca3797ee93ea1447fafe15f2c577dc..7509fc2eff044c0e5ab7ca3700c228a304c6e33c 100644 --- a/pkg/provider/kubernetes/crd/client_mock_test.go +++ b/pkg/provider/kubernetes/crd/client_mock_test.go @@ -5,8 +5,8 @@ import ( "os" "path/filepath" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s" corev1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes/scheme" ) @@ -30,15 +30,16 @@ type clientMock struct { apiSecretError error apiEndpointsError error - ingressRoutes []*v1alpha1.IngressRoute - ingressRouteTCPs []*v1alpha1.IngressRouteTCP - ingressRouteUDPs []*v1alpha1.IngressRouteUDP - middlewares []*v1alpha1.Middleware - middlewareTCPs []*v1alpha1.MiddlewareTCP - tlsOptions []*v1alpha1.TLSOption - tlsStores []*v1alpha1.TLSStore - traefikServices []*v1alpha1.TraefikService - serversTransport []*v1alpha1.ServersTransport + ingressRoutes []*v1alpha1.IngressRoute + ingressRouteTCPs []*v1alpha1.IngressRouteTCP + ingressRouteUDPs []*v1alpha1.IngressRouteUDP + middlewares []*v1alpha1.Middleware + middlewareTCPs []*v1alpha1.MiddlewareTCP + tlsOptions []*v1alpha1.TLSOption + tlsStores []*v1alpha1.TLSStore + traefikServices []*v1alpha1.TraefikService + serversTransports []*v1alpha1.ServersTransport + serversTransportTCPs []*v1alpha1.ServersTransportTCP watchChan chan interface{} } @@ -74,7 +75,9 @@ func newClientMock(paths ...string) clientMock { case *v1alpha1.TLSOption: c.tlsOptions = append(c.tlsOptions, o) case *v1alpha1.ServersTransport: - c.serversTransport = append(c.serversTransport, o) + c.serversTransports = append(c.serversTransports, o) + case *v1alpha1.ServersTransportTCP: + c.serversTransportTCPs = append(c.serversTransportTCPs, o) case *v1alpha1.TLSStore: c.tlsStores = append(c.tlsStores, o) case *corev1.Secret: @@ -131,7 +134,11 @@ func (c clientMock) GetTLSStores() []*v1alpha1.TLSStore { } func (c clientMock) GetServersTransports() []*v1alpha1.ServersTransport { - return c.serversTransport + return c.serversTransports +} + +func (c clientMock) GetServersTransportTCPs() []*v1alpha1.ServersTransportTCP { + return c.serversTransportTCPs } func (c clientMock) GetTLSOption(namespace, name string) (*v1alpha1.TLSOption, bool, error) { diff --git a/pkg/provider/kubernetes/crd/client_test.go b/pkg/provider/kubernetes/crd/client_test.go index 42aa574ee29438b802c52a6fe13478d6a9c50f13..5d64d08f7063bd4126f46a11c8761464b27ca133 100644 --- a/pkg/provider/kubernetes/crd/client_test.go +++ b/pkg/provider/kubernetes/crd/client_test.go @@ -6,7 +6,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - crdfake "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake" + crdfake "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" kubefake "k8s.io/client-go/kubernetes/fake" diff --git a/pkg/provider/kubernetes/crd/fixtures/services.yml b/pkg/provider/kubernetes/crd/fixtures/services.yml index 8de8ff369dc7f913f1b2323896307fd670910ea0..818a5bd3d3adacff34729bf79a0723126c1266e4 100644 --- a/pkg/provider/kubernetes/crd/fixtures/services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/services.yml @@ -252,3 +252,17 @@ apiVersion: v1 metadata: name: whoami-without-endpoints-subsets namespace: default + +--- +apiVersion: v1 +kind: Service +metadata: + name: native-svc + namespace: default + +spec: + ports: + - name: web + port: 80 + type: ClusterIP + clusterIP: 10.10.0.1 diff --git a/pkg/provider/kubernetes/crd/fixtures/simple.yml b/pkg/provider/kubernetes/crd/fixtures/simple.yml index 15e20535c5a95c2f5e7d59d16adb21a925eb6b1a..36d4313382a362495301f614565c09419c4b9dc1 100644 --- a/pkg/provider/kubernetes/crd/fixtures/simple.yml +++ b/pkg/provider/kubernetes/crd/fixtures/simple.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml index 9b5cfd973e2782636773df18d10a0b8265d79fcd..8c18ffdc8f2937e0e489bf8acd43fd224a2a515b 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/services.yml @@ -261,3 +261,17 @@ apiVersion: v1 metadata: name: whoamitcp-without-endpoints-subsets namespace: default + +--- +apiVersion: v1 +kind: Service +metadata: + name: native-svc + namespace: default + +spec: + ports: + - name: myapp + port: 8000 + type: ClusterIP + clusterIP: 10.10.0.1 diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/simple.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/simple.yml index 141cf6cb41409f26e9e736161d94067314b22657..170b05a09ba9f203a7f8ef512a4a9564d5474ee8 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/simple.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/simple.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_bad_tls_options.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_bad_tls_options.yml index 5bb19f25994bd0cc3d8eeeaada7040cddd6b3acb..8b44aecb3debf29ce93c1583a27a572012a590df 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_bad_tls_options.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_bad_tls_options.yml @@ -18,7 +18,7 @@ data: tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: foo @@ -49,7 +49,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_cross_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_cross_namespace.yml index c7ba22f1972edb4aaf9ae36abfd66dd19247a012..da7dcb4f40fe09cda49689911e501e21d113cd63 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_cross_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_cross_namespace.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_different_services_ns.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_different_services_ns.yml index 02af98254b7842d12d273f5def56d9d96ed771d4..9d129badbb70c4626debc90daad0e0906e27d4cd 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_different_services_ns.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_different_services_ns.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_empty_services.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_empty_services.yml index cf5853736f962bf5ce2b707231e9256ae936e301..55202d867fc3ded90a7c0c9c26119b21276c28e3 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_empty_services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_empty_services.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname.yml index 43226be283958c25a874745889a792358bf69cda..34a105c348204bfe2e4bd73298a65821b4aabcd2 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname_with_port.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname_with_port.yml index 3645601c5358baef79e933c665c5a2d484579b80..f31764a3e8ed5261501202b4b56f5a830cacb206 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname_with_port.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname_with_port.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname_without_ports.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname_without_ports.yml index 376d82469c00a46af55c1def6c386ece00145e84..1065d1380a8e2d6fe348c2e7da5b16931b107ac4 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname_without_ports.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_externalname_without_ports.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_ipv6.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_ipv6.yml index 777915c1871f514b46ed6295842d464e0c4c9798..dd6f23bea189dc2e32ece9a9f78a43506c9b6456 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_ipv6.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_ipv6.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware.yml index 19f83bd760286c127cb918972ec6b8b762320012..8c54dc2eff89b7fd07f266b2bf79698cedfbebf5 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: ipallowlist @@ -9,7 +9,7 @@ spec: - 127.0.0.1/32 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: ipallowlist @@ -19,7 +19,7 @@ spec: sourceRange: - 127.0.0.1/32 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_crossprovider.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_crossprovider.yml index 731d8aabaab8b1aa727e0c01e1e371414be42913..375cf7c40759d795a2ab49dbd7977cb7aa800c0b 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_crossprovider.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_crossprovider.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: ipallowlist @@ -9,7 +9,7 @@ spec: - 127.0.0.1/32 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: ipallowlist @@ -19,7 +19,7 @@ spec: sourceRange: - 127.0.0.1/32 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_multiple_hyphens.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_multiple_hyphens.yml index ba7aed1c0181f27a5939fbf057ea28195c85f34e..3523c780b3c70ce8b380ec5edee2fbee19aa6ead 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_multiple_hyphens.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_multiple_hyphens.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: multiple---hyphens @@ -9,7 +9,7 @@ spec: - 127.0.0.1/32 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_with_cross_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_with_cross_namespace.yml index 8b631fc981bda016a516435855395d79d192c59a..c504d8f2427961a3e6d34b4ba39ffbe7a63e59a0 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_with_cross_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_middleware_with_cross_namespace.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: ipallowlist @@ -9,7 +9,7 @@ spec: - 127.0.0.1/32 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: MiddlewareTCP metadata: name: ipallowlist @@ -19,7 +19,7 @@ spec: sourceRange: - 127.0.0.1/32 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_native_service_lb.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_native_service_lb.yml new file mode 100644 index 0000000000000000000000000000000000000000..f95202ec0153e49ccc96fd692f096f989f4db3fa --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_native_service_lb.yml @@ -0,0 +1,16 @@ +apiVersion: traefik.io/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`foo.com`) + services: + - name: native-svc + port: 8000 + nativeLB: true diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_no_rule_value.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_no_rule_value.yml index e78a0bfec11b3d8a7770577bb8e13d58c2cea2e0..2c3d578034812822237f838330dc717a90e5041a 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_no_rule_value.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_no_rule_value.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_proxyprotocol.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_proxyprotocol.yml index 843f13a716fbeb8b781152e17e8c42606da80ea8..af9c53b9f6d14c6298a8c842ebb2edb6387eb130 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_proxyprotocol.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_proxyprotocol.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_servers_transport.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_servers_transport.yml new file mode 100644 index 0000000000000000000000000000000000000000..f0fb21f5d3e65337c7185adc8cfb2e523c6adab1 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_servers_transport.yml @@ -0,0 +1,147 @@ +apiVersion: v1 +kind: Secret +metadata: + name: root-ca0 + namespace: foo + +data: + foobar: VEVTVFJPT1RDQVMw + +--- +apiVersion: v1 +kind: Secret +metadata: + name: root-ca1 + namespace: foo + +data: + tls.ca: VEVTVFJPT1RDQVMx + +--- +apiVersion: v1 +kind: Secret +metadata: + name: root-ca2 + namespace: foo + +data: + tls.ca: VEVTVFJPT1RDQVMy + +--- +apiVersion: v1 +kind: Secret +metadata: + name: root-ca3 + namespace: foo + +data: + ca.crt: VEVTVFJPT1RDQVMz + +--- +apiVersion: v1 +kind: Secret +metadata: + name: root-ca4 + namespace: foo + +data: + ca.crt: VEVTVFJPT1RDQVM0 + tls.ca: VEVTVFJPT1RDQVM1 # <-- This should be the preferred one. + +--- +apiVersion: v1 +kind: Secret +metadata: + name: mtls1 + namespace: foo + +data: + tls.crt: VEVTVENFUlQx + tls.key: VEVTVEtFWTE= + +--- +apiVersion: v1 +kind: Secret +metadata: + name: mtls2 + namespace: foo + +data: + tls.crt: VEVTVENFUlQy + tls.key: VEVTVEtFWTI= + +--- +apiVersion: v1 +kind: Secret +metadata: + name: allcerts + namespace: foo + +data: + ca.crt: VEVTVEFMTENFUlRT + tls.crt: VEVTVENFUlQz + tls.key: VEVTVEtFWTM= + +--- +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: test + namespace: foo + +spec: + tls: + serverName: "test" + insecureSkipVerify: true + peerCertURI: foo://bar + rootCAsSecrets: + - root-ca0 + - root-ca1 + - root-ca2 + - root-ca3 + - root-ca4 + - allcerts + certificatesSecrets: + - mtls1 + - mtls2 + - allcerts + spiffe: + ids: + - spiffe://foo/buz + - spiffe://bar/biz + trustDomain: spiffe://lol + dialTimeout: 42 + dialKeepAlive: 42 + terminationDelay: 42 + +--- +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: test + namespace: default + +spec: + tls: + serverName: "test" + +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`foo.com`) + services: + - name: whoamitcp + port: 8000 + serversTransport: test + - name: whoamitcp2 + port: 8080 + serversTransport: default-test diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_servers_transport_cross_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_servers_transport_cross_namespace.yml new file mode 100644 index 0000000000000000000000000000000000000000..2f64f0e2b88d3e2e637e67e2fbd4bfadaee1bfa3 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_servers_transport_cross_namespace.yml @@ -0,0 +1,27 @@ +apiVersion: traefik.io/v1alpha1 +kind: IngressRouteTCP +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: HostSNI(`foo.com`) + priority: 12 + services: + - name: whoamitcp + port: 8000 + serversTransport: cross-ns-st-cross-ns@kubernetescrd + +--- +apiVersion: traefik.io/v1alpha1 +kind: ServersTransportTCP +metadata: + name: st-cross-ns + namespace: cross-ns + +spec: + dialKeepAlive: 0 diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_termination_delay.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_termination_delay.yml index 1d942ab6a10066a0bc4247d60d36e50aa1154800..7b0076dfe81b83ae7acd813291d5b8859105c35f 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_termination_delay.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_termination_delay.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls.yml index 17548e2b33ce72f343e8e206052f0ca545440ded..4bb90073aacc5f47ce5c277b63690a7bc68695c2 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls.yml @@ -9,7 +9,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_acme.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_acme.yml index f7e33451339319f2c14801cb7ddb94965c41a136..8d22a46e4276596106541cb6b2e770ebc26c69c4 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_acme.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_acme.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options.yml index 1b45d99534965831b83d248cc4b86e4772865c3b..123abc113cbb6725a4424b67cfad35968f71d27b 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options.yml @@ -18,7 +18,7 @@ data: tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: foo @@ -47,7 +47,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options_and_specific_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options_and_specific_namespace.yml index 27e34fcaf2496878ec02000d967182c68a2e0edd..0861644d07df70fc29f6029073708d8c58f482aa 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options_and_specific_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options_and_specific_namespace.yml @@ -18,7 +18,7 @@ data: tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: foo @@ -48,7 +48,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options_cross_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options_cross_namespace.yml index 13958f95d9e22f504c28b76143ee2122304ad5b8..2d6687e5c7ddcdfcc367e630f256a7975534d9bd 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options_cross_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_options_cross_namespace.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route @@ -20,7 +20,7 @@ spec: namespace: cross-ns --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: tls-options-cn diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_passthrough.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_passthrough.yml index 5cfac32f53c4d153b64f9f44f912840426689ab7..4f84b028098e871c4219e9fdff3f291b2befb71c 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_passthrough.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_passthrough.yml @@ -9,7 +9,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_store.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_store.yml index 24894e300d2502268e587700b9ceaa2e0b4d829a..16918e314aee30e3af06bfa09b90443c53767289 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_store.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_tls_store.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSStore metadata: name: default @@ -20,7 +20,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_identical_rules.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_identical_rules.yml index b6e6108cd92f8faee3f8e1811c259dd8d7ce8e13..99aabf28b724c39de7ab399488db61d786013055 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_identical_rules.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_identical_rules.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_rules.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_rules.yml index dd068d0c3f764c1a646d3816ce5ca6331f7ba6ae..3b148ec312dd34006612cdccb9dac1a5172656f0 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_rules.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_rules.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_services.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_services.yml index 73f60f0372ce7ca6c1e1fa1ff7067c86504b3f5e..d45527039be56f2026f80703c0fb878b5b314488 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_two_services.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_unknown_tls_options.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_unknown_tls_options.yml index 5798a07195f53e53d8b2e50015801f79562c881d..3df4fdae32ef7e8ace3107f5395a978959c899d3 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_unknown_tls_options.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_unknown_tls_options.yml @@ -1,5 +1,5 @@ --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: foo @@ -9,7 +9,7 @@ spec: minVersion: VersionTLS12 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/tcp/with_unknown_tls_options_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/tcp/with_unknown_tls_options_namespace.yml index ed34abdf6b03546f8188aecd6450a622956664d0..6a9eb2ecd07978647c1bce7c41e6901d41f92c18 100644 --- a/pkg/provider/kubernetes/crd/fixtures/tcp/with_unknown_tls_options_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/tcp/with_unknown_tls_options_namespace.yml @@ -1,5 +1,5 @@ --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: foo @@ -9,7 +9,7 @@ spec: minVersion: VersionTLS12 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteTCP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/services.yml b/pkg/provider/kubernetes/crd/fixtures/udp/services.yml index d58973c823ae0247b6551db91247f30ac7e4168d..adaa7272e3e6258472b49a7d353a0b0a694e525a 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/services.yml @@ -220,3 +220,17 @@ apiVersion: v1 metadata: name: whoamiudp-without-endpoints-subsets namespace: default + +--- +apiVersion: v1 +kind: Service +metadata: + name: native-svc + namespace: default + +spec: + ports: + - name: myapp + port: 8000 + type: ClusterIP + clusterIP: 10.10.0.1 diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/simple.yml b/pkg/provider/kubernetes/crd/fixtures/udp/simple.yml index f514d78a5972bc0c9f1e35b2d92e6e06dc0b8a4e..60da5fa888f98cee9413f5cb2b36e281e41cef57 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/simple.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/simple.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_cross_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_cross_namespace.yml index 8df091d70013a2ece9a6dc1ca287c41c10e96f6a..5b54397d7f24728909e383a26784df3ff1de18df 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_cross_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_cross_namespace.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_different_services_ns.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_different_services_ns.yml index d5c6cc728858342f9453ed72c761e44ad7549c4e..c6518c62c33bfaea100ae9b50574af79742e2105 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_different_services_ns.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_different_services_ns.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_empty_services.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_empty_services.yml index 98aeb2bd6971a87c4e75a74fed52c061dde75e04..dc588d5e93f424027fa059c940366d62659b8fb2 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_empty_services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_empty_services.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname.yml index 14c3ab658fe5b0e27906c1ef33e615cabc2bdda3..dbd919422ea5fa384517e90a51db5088682efa7c 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_service.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_service.yml index 962178ed5c80cddd120edf05e9c821337ff16c77..302332c0c0f0b86bd74dea6ca657536a4a2107ba 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_service.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_service.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_with_port.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_with_port.yml index 962178ed5c80cddd120edf05e9c821337ff16c77..302332c0c0f0b86bd74dea6ca657536a4a2107ba 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_with_port.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_with_port.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_without_ports.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_without_ports.yml index 6478e6aa41e5b2daf45f7940fa67f8f456b24e2e..2a30279bb2c035b69cc43d2f8a11401a1c0d5bb5 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_without_ports.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_externalname_without_ports.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_ipv6.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_ipv6.yml index 2acc8bdc7ef718f96136db641fae9abca99268c5..dfdbe512f2e92e2f8cae2ecf0ac357d5fc61d4ca 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_ipv6.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_ipv6.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_native_service_lb.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_native_service_lb.yml new file mode 100644 index 0000000000000000000000000000000000000000..6942f106b4fe64eaf994af10314f8797cfe358a2 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_native_service_lb.yml @@ -0,0 +1,15 @@ +apiVersion: traefik.io/v1alpha1 +kind: IngressRouteUDP +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - foo + + routes: + - services: + - name: native-svc + port: 8000 + nativeLB: true diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_two_routes.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_two_routes.yml index 9abffc0d898ab2f712bd7aa9314fcb94c7931489..762a17178061a18aa8367ce5d124cdec084a58f1 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_two_routes.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_two_routes.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/udp/with_two_services.yml b/pkg/provider/kubernetes/crd/fixtures/udp/with_two_services.yml index 46bae5d8c885955514e758714d8ba5c10f77bb3e..0cee38f9e2a16c8b47efd6b3291ff9ba85213cb2 100644 --- a/pkg/provider/kubernetes/crd/fixtures/udp/with_two_services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/udp/with_two_services.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRouteUDP metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_auth.yml b/pkg/provider/kubernetes/crd/fixtures/with_auth.yml index b03b82b643cb09e8a923f5a1f538af67440b1523..6da695b12db2ec7e510b2c5a3c29fce25110e6fb 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_auth.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_auth.yml @@ -30,7 +30,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: basicauth @@ -41,7 +41,7 @@ spec: secret: authsecret --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: digestauth @@ -51,7 +51,7 @@ spec: digestAuth: secret: authsecret --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: forwardauth diff --git a/pkg/provider/kubernetes/crd/fixtures/with_bad_tls_options.yml b/pkg/provider/kubernetes/crd/fixtures/with_bad_tls_options.yml index 2df4c3a677f341d7416b2bd6f1fb8810ae423f18..2dd766bfeca15d354f66eb26a8c15139fff10bbc 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_bad_tls_options.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_bad_tls_options.yml @@ -18,7 +18,7 @@ data: tls.ca: --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: foo @@ -38,7 +38,7 @@ spec: clientAuthType: VerifyClientCertIfGiven --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_cross_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/with_cross_namespace.yml index 543c5696c2f28d80187d4797d443bfe495b48203..e66307a71db1c15d6d9a382408eec013cec08d5f 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_cross_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_cross_namespace.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: cross-ns-route @@ -36,7 +36,7 @@ spec: serversTransport: foo-test@kubernetescrd --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: tr-svc-wrr1 @@ -51,7 +51,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: tr-svc-wrr2 @@ -65,7 +65,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: tr-svc-mirror1 @@ -82,7 +82,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: tr-svc-mirror2 @@ -99,7 +99,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: test diff --git a/pkg/provider/kubernetes/crd/fixtures/with_default_tls_options.yml b/pkg/provider/kubernetes/crd/fixtures/with_default_tls_options.yml index 3646d952245f23a3d13dc036f5d9ae191622a46a..494fb236933ebdf5ed67161320085bc7f7306155 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_default_tls_options.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_default_tls_options.yml @@ -18,7 +18,7 @@ data: tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: default @@ -37,7 +37,7 @@ spec: clientAuthType: VerifyClientCertIfGiven --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_default_tls_options_default_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/with_default_tls_options_default_namespace.yml index 49e1289830b701923add191a9da4a66b0167aab1..ec84b589d6fe4dc2a6016a389ea2799e97abd590 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_default_tls_options_default_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_default_tls_options_default_namespace.yml @@ -18,7 +18,7 @@ data: tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: default @@ -37,7 +37,7 @@ spec: clientAuthType: VerifyClientCertIfGiven --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_default_tls_store.yml b/pkg/provider/kubernetes/crd/fixtures/with_default_tls_store.yml index 07f1f982cb8ce4df167f8e2d5a7578725ccae7da..36de8bd5082c387c6c1fc524c43ee822bdddcd9c 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_default_tls_store.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_default_tls_store.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSStore metadata: name: default @@ -20,7 +20,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_empty_services.yml b/pkg/provider/kubernetes/crd/fixtures/with_empty_services.yml index f6ebb84c065e0f0e7efa40605d8c6df2375331b1..b3ff215d16f0d64cfed8ace6a03417e9ac15f159 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_empty_services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_empty_services.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml b/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml index 92500f3fd074c753d722ecbe5d1182ef8e9ea866..bc4f9626c2647118d03b94f319caa40532ebb28d 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_empty_services_ts.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route @@ -21,7 +21,7 @@ spec: - name: test-errorpage --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: test-weighted @@ -35,7 +35,7 @@ spec: port: 80 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: test-mirror @@ -52,7 +52,7 @@ spec: kind: TraefikService --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-errorpage diff --git a/pkg/provider/kubernetes/crd/fixtures/with_error_page.yml b/pkg/provider/kubernetes/crd/fixtures/with_error_page.yml index 3eea37acdbff0b45395ac8968bad01cd0b2bf5f9..e352d596b41ca698e9591ec54976ea60dfb40e16 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_error_page.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_error_page.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: errorpage diff --git a/pkg/provider/kubernetes/crd/fixtures/with_externalname.yml b/pkg/provider/kubernetes/crd/fixtures/with_externalname.yml index b70ec012e8daffc57ffa1c203067ffa3b903126e..8a14262116434508ba208779353dd61d90b55f53 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_externalname.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_externalname.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_externalname_with_http.yml b/pkg/provider/kubernetes/crd/fixtures/with_externalname_with_http.yml index 1f3e3a3f722694c834c672bdf1d8e98356851943..af1c37d386b0f4e7ec5df076b65f96ce883dd0e8 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_externalname_with_http.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_externalname_with_http.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_externalname_with_https.yml b/pkg/provider/kubernetes/crd/fixtures/with_externalname_with_https.yml index 21c39a1c338b0cdac31afd748e783cf020eeac57..51a7bb3e2e6518852cfa8a2461e82daef43fa947 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_externalname_with_https.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_externalname_with_https.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_externalname_without_ports.yml b/pkg/provider/kubernetes/crd/fixtures/with_externalname_without_ports.yml index 25f230574237ce8256f6f515121cbf841f0a7255..15b45c3df3f3b6573065890b88ee070865c24f68 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_externalname_without_ports.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_externalname_without_ports.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_https_default.yml b/pkg/provider/kubernetes/crd/fixtures/with_https_default.yml index c022a6cded67ad919bc337ef3c7ef1f3302d5b35..2df7e0079af6f9e2f61a1ec61c00cbd837f44a4d 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_https_default.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_https_default.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_https_scheme.yml b/pkg/provider/kubernetes/crd/fixtures/with_https_scheme.yml index 4a9bb8b4671e00a03b06480a18212aa9fb690568..1a0ff7d77099482e80f34f6dcaf96525df9fe6b2 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_https_scheme.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_https_scheme.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_ipv6.yml b/pkg/provider/kubernetes/crd/fixtures/with_ipv6.yml index 23af879ac52c276b3b3b12fa8a445b0a842f2f64..27a67bc4af931353ab328c67ab451b44f1d67003 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_ipv6.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_ipv6.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_middleware.yml b/pkg/provider/kubernetes/crd/fixtures/with_middleware.yml index 45b2dcd4936f5d94d00bf536b761757f7ac5b0e8..3837a507b34d40b816615cab55e3cf177be3b1a6 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_middleware.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_middleware.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: stripprefix @@ -10,7 +10,7 @@ spec: - /tobestripped --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: ratelimit @@ -28,7 +28,7 @@ spec: - 192.168.1.7 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: addprefix @@ -39,7 +39,7 @@ spec: prefix: /tobeadded --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test2.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_middleware_cross_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/with_middleware_cross_namespace.yml index 25a2ac4488f0b4123347f646bd5f7de8686f1d91..3c1e899562b9a0d8d2b98155d6257c8bf1ac7c8c 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_middleware_cross_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_middleware_cross_namespace.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test-crossnamespace.route @@ -39,7 +39,7 @@ spec: - name: cross-ns-stripprefix@kubernetescrd --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: stripprefix @@ -51,7 +51,7 @@ spec: - /stripit --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-errorpage diff --git a/pkg/provider/kubernetes/crd/fixtures/with_middleware_crossprovider.yml b/pkg/provider/kubernetes/crd/fixtures/with_middleware_crossprovider.yml index 9150003295170fd7fe572bbc5c3346aa60123e45..0607ea066341f81c7272273cea57705fb75c4f52 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_middleware_crossprovider.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_middleware_crossprovider.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: stripprefix @@ -10,7 +10,7 @@ spec: - /tobestripped --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: addprefix @@ -21,7 +21,7 @@ spec: prefix: /tobeadded --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test2.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_middleware_multiple_hyphens.yml b/pkg/provider/kubernetes/crd/fixtures/with_middleware_multiple_hyphens.yml index cee835136309e5475b0f7689ce7503be910c6a9b..648137c6ee1aee7c55f1043e9e74ce26ba4f8fd7 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_middleware_multiple_hyphens.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_middleware_multiple_hyphens.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: multiple---hyphens @@ -10,7 +10,7 @@ spec: - /tobestripped --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test2.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_mirroring.yml b/pkg/provider/kubernetes/crd/fixtures/with_mirroring.yml index 7a9fb49c95e4e0f599349d03c8823bb8755cae0f..a1ead36d8e0a4a202fe0548166037c2aca992958 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_mirroring.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_mirroring.yml @@ -59,7 +59,7 @@ spec: task: whoami5 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror1 @@ -77,7 +77,7 @@ spec: port: 8080 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_mirroring2.yml b/pkg/provider/kubernetes/crd/fixtures/with_mirroring2.yml index b43b33c1c2a75223636cb86693d5f1172b865404..5f498a29603acf0daec1c9357e9c66aaac1db1ce 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_mirroring2.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_mirroring2.yml @@ -59,7 +59,7 @@ spec: task: whoami5 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr2 @@ -73,7 +73,7 @@ spec: port: 8080 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 @@ -87,7 +87,7 @@ spec: port: 8080 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror1 @@ -103,7 +103,7 @@ spec: percent: 30 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_namespaces.yml b/pkg/provider/kubernetes/crd/fixtures/with_namespaces.yml index 9bdf1a0045d60ca39cee11369d7d9317c9468f77..d8d4867e99bcadf8217c4f8016435bb34a778a70 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_namespaces.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_namespaces.yml @@ -89,7 +89,7 @@ spec: task: whoami4 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror1 @@ -111,7 +111,7 @@ spec: namespace: bar --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr2 @@ -126,7 +126,7 @@ spec: port: 8080 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror2 @@ -150,7 +150,7 @@ spec: namespace: foo --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror3 @@ -176,7 +176,7 @@ spec: --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror4 @@ -200,7 +200,7 @@ spec: namespace: foo --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirrored @@ -218,7 +218,7 @@ spec: namespace: foo --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 @@ -239,7 +239,7 @@ spec: namespace: bar --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_native_service_lb.yml b/pkg/provider/kubernetes/crd/fixtures/with_native_service_lb.yml new file mode 100644 index 0000000000000000000000000000000000000000..259ea216cfabf70b1ed548971b2fe07c9aab2546 --- /dev/null +++ b/pkg/provider/kubernetes/crd/fixtures/with_native_service_lb.yml @@ -0,0 +1,17 @@ +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: test.route + namespace: default + +spec: + entryPoints: + - foo + + routes: + - match: Host(`foo.com`) + kind: Rule + services: + - name: native-svc + port: 80 + nativeLB: true diff --git a/pkg/provider/kubernetes/crd/fixtures/with_no_rule_value.yml b/pkg/provider/kubernetes/crd/fixtures/with_no_rule_value.yml index 35a2df6d37c32e545d8bce86bd5e410dd7f2b2ef..a1f3ed335527339d0f6838e3c16af59bd5c418a8 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_no_rule_value.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_no_rule_value.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_options.yml b/pkg/provider/kubernetes/crd/fixtures/with_options.yml index 1c945829d2fded88ec13297ccea63fe085b6b169..281975a71052833a2507749a6caee7c4240d9711 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_options.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_options.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_plugin_deep_read_secret.yml b/pkg/provider/kubernetes/crd/fixtures/with_plugin_deep_read_secret.yml index f99bde07c5c79540a9e2ed4c514ce50b3515bf3b..fcd10d6bd288be809520bd0499f70caad28c73c2 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_plugin_deep_read_secret.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_plugin_deep_read_secret.yml @@ -8,7 +8,7 @@ data: key: dGhpc19pc190aGVfdmVyeV9kZWVwX3NlY3JldA== --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-secret diff --git a/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_array_of_map_contain_secret.yml b/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_array_of_map_contain_secret.yml index 36042fe57577b291d9c798d3e8c77e27f3e15296..c45873cbfce9a649499b48932f7f772a170924e4 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_array_of_map_contain_secret.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_array_of_map_contain_secret.yml @@ -9,7 +9,7 @@ data: key2: dXNlcl9wYXNzd29yZA== --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-secret diff --git a/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_array_of_secret.yml b/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_array_of_secret.yml index 7b88c1c42d1d1a2dfb0c6b45fb331b20dbb0ac80..7544b2e6db141e1ebb96fb5f38e25bbe09b39d2c 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_array_of_secret.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_array_of_secret.yml @@ -9,7 +9,7 @@ data: key2: c2VjcmV0X2RhdGEy --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-secret diff --git a/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_not_exist_secret.yml b/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_not_exist_secret.yml index c9923d1d83fd4ee86d8fe484f077fb8f55cc2d3e..8430ca60036e1aa5574fcb84e75ce8ce74fdffe7 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_not_exist_secret.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_not_exist_secret.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-secret diff --git a/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_secret.yml b/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_secret.yml index bcd368619afea7c6e7c0201549ffc2d67ed1192d..e7f9a70dd4db1b50451fbc99adb848a77661d482 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_secret.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_plugin_read_secret.yml @@ -8,7 +8,7 @@ data: key: dGhpc19pc190aGVfc2VjcmV0 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: Middleware metadata: name: test-secret diff --git a/pkg/provider/kubernetes/crd/fixtures/with_servers_transport.yml b/pkg/provider/kubernetes/crd/fixtures/with_servers_transport.yml index fdbf7b930fedd45a1baef7341d5081e2e696edb3..8515039f4ff208b4b38bb8001a8cbbbf1e4c71b9 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_servers_transport.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_servers_transport.yml @@ -83,7 +83,7 @@ data: tls.key: VEVTVEtFWTM= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: test @@ -119,7 +119,7 @@ spec: trustDomain: spiffe://lol --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: test @@ -129,7 +129,7 @@ spec: serverName: "test" --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_servers_transport_cross_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/with_servers_transport_cross_namespace.yml index 7b9ab8891a6c8fef317146133a7169d3ddd06124..7aa2e6fb34907948ed6a230155ccafecd1f6e472 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_servers_transport_cross_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_servers_transport_cross_namespace.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route @@ -18,7 +18,7 @@ spec: serversTransport: cross-ns-st-cross-ns@kubernetescrd --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: ServersTransport metadata: name: st-cross-ns diff --git a/pkg/provider/kubernetes/crd/fixtures/with_services_lb0.yml b/pkg/provider/kubernetes/crd/fixtures/with_services_lb0.yml index 7a1456498c1adf782d5cb8ca3f7929c684a6318b..d4f7b7d94581436be45e632ac9527c9b7fe4764a 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_services_lb0.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_services_lb0.yml @@ -29,7 +29,7 @@ spec: task: whoami5 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 @@ -44,7 +44,7 @@ spec: port: 8080 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_services_lb1.yml b/pkg/provider/kubernetes/crd/fixtures/with_services_lb1.yml index 078b261dc0c9d7edae4139ecd3ed9c778bbb8092..d863c3f1f38350c135d1f19090060571994e57fc 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_services_lb1.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_services_lb1.yml @@ -119,7 +119,7 @@ spec: task: whoami7 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 @@ -136,7 +136,7 @@ spec: weight: 1 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr2 @@ -153,7 +153,7 @@ spec: weight: 1 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_services_lb2.yml b/pkg/provider/kubernetes/crd/fixtures/with_services_lb2.yml index 4d99705e91d2f58bfcb5b6f074081cd5a5a95cf2..c1732c18b9ebb468b7fd709fbab9170642862032 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_services_lb2.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_services_lb2.yml @@ -14,7 +14,7 @@ subsets: port: 8080 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr2 @@ -43,7 +43,7 @@ spec: task: whoami5 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 @@ -60,7 +60,7 @@ spec: port: 8080 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_services_lb3.yml b/pkg/provider/kubernetes/crd/fixtures/with_services_lb3.yml index 939cf7c7b30b79d25a1a78de626d0fe2cc511c38..8b15d9fd99975f523e2642d25ef9eb3b39e4f3ce 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_services_lb3.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_services_lb3.yml @@ -59,7 +59,7 @@ spec: task: whoami4 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr2 @@ -73,7 +73,7 @@ spec: port: 8080 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: mirror1 @@ -89,7 +89,7 @@ spec: port: 8080 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 @@ -109,7 +109,7 @@ spec: weight: 1 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_services_only.yml b/pkg/provider/kubernetes/crd/fixtures/with_services_only.yml index 9dabe61471b49c1ad8cc747d9ea789e7f3c14516..c98462ee9443438cdb985590994ee80ef1eeb61b 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_services_only.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_services_only.yml @@ -29,7 +29,7 @@ spec: task: whoami5 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TraefikService metadata: name: wrr1 diff --git a/pkg/provider/kubernetes/crd/fixtures/with_tls.yml b/pkg/provider/kubernetes/crd/fixtures/with_tls.yml index 8f78a318d3d008b14e6fc123839d599af225e1dd..224164d366adb1d2e30933e0e0b2c39d762fa763 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_tls.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_tls.yml @@ -9,7 +9,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_tls_acme.yml b/pkg/provider/kubernetes/crd/fixtures/with_tls_acme.yml index 170c7a94d68f2c402ab0dbe3b59578afb9a5224c..22ef09000d8db8a6a4deef7d68655d7734cdeec8 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_tls_acme.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_tls_acme.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_tls_options.yml b/pkg/provider/kubernetes/crd/fixtures/with_tls_options.yml index f49aab66e5d3275aabc4dad8aa30473d658eda57..f4bb0850a4652af018e86f7323fe359eee28e87e 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_tls_options.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_tls_options.yml @@ -18,7 +18,7 @@ data: ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: foo @@ -37,7 +37,7 @@ spec: clientAuthType: VerifyClientCertIfGiven --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_tls_options_and_specific_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/with_tls_options_and_specific_namespace.yml index eec9d6fd10e1c0e2803e1206575a0209a094a960..976cd8821ba6b742a3c293d5c879e5929fd4d4b1 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_tls_options_and_specific_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_tls_options_and_specific_namespace.yml @@ -18,7 +18,7 @@ data: tls.ca: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: foo @@ -37,7 +37,7 @@ spec: clientAuthType: VerifyClientCertIfGiven --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_tls_options_cross_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/with_tls_options_cross_namespace.yml index 57228278b3f8eaf83d454b4ecf5ef675e7bacabe..ac8a902976fc7546dd7404dac97f3a8b569ee697 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_tls_options_cross_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_tls_options_cross_namespace.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route @@ -21,7 +21,7 @@ spec: namespace: cross-ns --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: tls-options-cn diff --git a/pkg/provider/kubernetes/crd/fixtures/with_tls_store.yml b/pkg/provider/kubernetes/crd/fixtures/with_tls_store.yml index ba1acc4cda290f1225bf3d6f2a852d819c4ef617..84a892fee7805dfb6a8dcad471ba5eac487591e9 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_tls_store.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_tls_store.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSStore metadata: name: default @@ -20,7 +20,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_tls_store_certificates.yml b/pkg/provider/kubernetes/crd/fixtures/with_tls_store_certificates.yml index 2691ac79b5836e9fc24a0056142dc442a691d774..01127dcd1917c0ab7ff3a2db81fbaff7dc80813e 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_tls_store_certificates.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_tls_store_certificates.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSStore metadata: name: default @@ -20,7 +20,7 @@ data: tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0= --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_two_rules.yml b/pkg/provider/kubernetes/crd/fixtures/with_two_rules.yml index f307b797dd4a7adfc26c87e7c35954e5726657d1..a3ea7a5d17607dc251e12fe40ca700b98487830b 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_two_rules.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_two_rules.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_two_services.yml b/pkg/provider/kubernetes/crd/fixtures/with_two_services.yml index 8a6a17e24e58d71f5c2f1e70a9bea71be807f06d..4a971280a61f348b755d183468640de2aa22e81a 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_two_services.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_two_services.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_two_services_weight.yml b/pkg/provider/kubernetes/crd/fixtures/with_two_services_weight.yml index 76a5c7c3ef8240650025d06410a3ce51b19d3cbf..e9bb74c210874541f470e49ccd830639b6945661 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_two_services_weight.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_two_services_weight.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_unknown_tls_options.yml b/pkg/provider/kubernetes/crd/fixtures/with_unknown_tls_options.yml index 543851e37f4b854f141ce240f255c36241c3928c..8f4a0d0c8fb740fdc3796c980489a5b25e1edff5 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_unknown_tls_options.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_unknown_tls_options.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: foo @@ -8,7 +8,7 @@ spec: minVersion: VersionTLS12 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_unknown_tls_options_namespace.yml b/pkg/provider/kubernetes/crd/fixtures/with_unknown_tls_options_namespace.yml index 13356148255491337be639df8a0eab2589520b50..2ebfc2e6245e415b2d73ed074c5dc97908ed01dc 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_unknown_tls_options_namespace.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_unknown_tls_options_namespace.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: TLSOption metadata: name: foo @@ -8,7 +8,7 @@ spec: minVersion: VersionTLS12 --- -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/fixtures/with_wrong_rule_kind.yml b/pkg/provider/kubernetes/crd/fixtures/with_wrong_rule_kind.yml index 6c649295a6f37c8ff5e08b03fb4f55f07f25dace..1cb62e1a97ff11dd0004a640630005446149afdc 100644 --- a/pkg/provider/kubernetes/crd/fixtures/with_wrong_rule_kind.yml +++ b/pkg/provider/kubernetes/crd/fixtures/with_wrong_rule_kind.yml @@ -1,4 +1,4 @@ -apiVersion: traefik.containo.us/v1alpha1 +apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: test.route diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/clientset.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/clientset.go index 334f5de4cb73612b882651ed4d020b4a9fb32cc3..ec71200a70ee250b0875fc10e09e5dfe0289e5ca 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/clientset.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/clientset.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package versioned import ( "fmt" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1" + traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" flowcontrol "k8s.io/client-go/util/flowcontrol" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/doc.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/doc.go index c5b70f22f9b9e411e6ef114d81f43bf03e0d9c65..b6f98d4756a3b71963f2d699b4c6c24fbc0c8a5d 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/doc.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/doc.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/clientset_generated.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/clientset_generated.go index 3b0aad3ce47ed3b63c5fddbe6b5764dc9ec8fca8..55b5edcb25b171b826e1153b698133305b4e0479 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/clientset_generated.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/clientset_generated.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,9 +27,9 @@ THE SOFTWARE. package fake import ( - clientset "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1" - faketraefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake" + clientset "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1" + faketraefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/watch" "k8s.io/client-go/discovery" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/doc.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/doc.go index f0c4f5bd0a47b62d99d3192c573353322f95f4d9..081d07edbc79775f8fe5fd97baae8218231c7a45 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/doc.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/doc.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/register.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/register.go index 3ab7c4b7308246afb11a4d58c4e993256c70cb7f..c25b16318c3bd3412a90ac92e4e2079e3757cb41 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/register.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake/register.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package fake import ( - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme/doc.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme/doc.go index faef00f1af309ec6bc11cd9990e2ef6a756e2ab0..87af682734dd347b94a0854f690c6bc9ef848b9c 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme/doc.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme/doc.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme/register.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme/register.go index 55a7726a9d9945c079dafd87cb35fdc9e9affd7f..cb048b1546106d41414f5820c5d1668a40fb6f2f 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme/register.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme/register.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package scheme import ( - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/doc.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/doc.go similarity index 94% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/doc.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/doc.go index 0a563190793e463aa75e18963f9432c9f5b41cbe..e39212eab4294a757c8aab615994d8107db4c2af 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/doc.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/doc.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/doc.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/doc.go similarity index 94% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/doc.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/doc.go index 076d4e4ce072450ea1cf89f2ed4c2dc2872411ae..24ecc2be057d09e405a830dee12068d652d17b4a 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/doc.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/doc.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressroute.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_ingressroute.go similarity index 95% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressroute.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_ingressroute.go index 76aa065c4732b099b3c7e93b34e49da778b12d67..b01905713e1a8534cfebbd090e7eb0b7b83cf2be 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressroute.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_ingressroute.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package fake import ( "context" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -44,9 +44,9 @@ type FakeIngressRoutes struct { ns string } -var ingressroutesResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "ingressroutes"} +var ingressroutesResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "ingressroutes"} -var ingressroutesKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "IngressRoute"} +var ingressroutesKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "IngressRoute"} // Get takes name of the ingressRoute, and returns the corresponding ingressRoute object, and an error if there is any. func (c *FakeIngressRoutes) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IngressRoute, err error) { diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressroutetcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_ingressroutetcp.go similarity index 95% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressroutetcp.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_ingressroutetcp.go index c98c593a6c047949e82d185057b3c9d54ad2bae9..394b1ff554a16180f95bcca95dbdcd410928472f 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressroutetcp.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_ingressroutetcp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package fake import ( "context" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -44,9 +44,9 @@ type FakeIngressRouteTCPs struct { ns string } -var ingressroutetcpsResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "ingressroutetcps"} +var ingressroutetcpsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "ingressroutetcps"} -var ingressroutetcpsKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "IngressRouteTCP"} +var ingressroutetcpsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "IngressRouteTCP"} // Get takes name of the ingressRouteTCP, and returns the corresponding ingressRouteTCP object, and an error if there is any. func (c *FakeIngressRouteTCPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IngressRouteTCP, err error) { diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressrouteudp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_ingressrouteudp.go similarity index 95% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressrouteudp.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_ingressrouteudp.go index e81872b0d7f2f2c5c42eb3da79c90683f1e9dd45..f67d889decd701befe4b6b3bb63e0dcff5bc513e 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_ingressrouteudp.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_ingressrouteudp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package fake import ( "context" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -44,9 +44,9 @@ type FakeIngressRouteUDPs struct { ns string } -var ingressrouteudpsResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "ingressrouteudps"} +var ingressrouteudpsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "ingressrouteudps"} -var ingressrouteudpsKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "IngressRouteUDP"} +var ingressrouteudpsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "IngressRouteUDP"} // Get takes name of the ingressRouteUDP, and returns the corresponding ingressRouteUDP object, and an error if there is any. func (c *FakeIngressRouteUDPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.IngressRouteUDP, err error) { diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_middleware.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_middleware.go similarity index 93% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_middleware.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_middleware.go index e1bcc76031e8b66872bc0ac0559da241c9ff2475..efef604fda4d23188bda360100db25106e1b3ad0 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_middleware.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_middleware.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package fake import ( "context" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -44,9 +44,9 @@ type FakeMiddlewares struct { ns string } -var middlewaresResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "middlewares"} +var middlewaresResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "middlewares"} -var middlewaresKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "Middleware"} +var middlewaresKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "Middleware"} // Get takes name of the middleware, and returns the corresponding middleware object, and an error if there is any. func (c *FakeMiddlewares) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.Middleware, err error) { diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_middlewaretcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_middlewaretcp.go similarity index 95% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_middlewaretcp.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_middlewaretcp.go index cb9adaae8cc95c2b4d3e934bffab3c96870bb7c5..767405b0e84400a62c31e1b0113c6a92a59617aa 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_middlewaretcp.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_middlewaretcp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package fake import ( "context" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -44,9 +44,9 @@ type FakeMiddlewareTCPs struct { ns string } -var middlewaretcpsResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "middlewaretcps"} +var middlewaretcpsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "middlewaretcps"} -var middlewaretcpsKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "MiddlewareTCP"} +var middlewaretcpsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "MiddlewareTCP"} // Get takes name of the middlewareTCP, and returns the corresponding middlewareTCP object, and an error if there is any. func (c *FakeMiddlewareTCPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.MiddlewareTCP, err error) { diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_serverstransport.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_serverstransport.go similarity index 95% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_serverstransport.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_serverstransport.go index b144f0c652bbcf4230690b6fdda365356ad781da..3666bb4a5171dfe5e5bdfe2659ac2a2a21cfbe05 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_serverstransport.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_serverstransport.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package fake import ( "context" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -44,9 +44,9 @@ type FakeServersTransports struct { ns string } -var serverstransportsResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "serverstransports"} +var serverstransportsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "serverstransports"} -var serverstransportsKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "ServersTransport"} +var serverstransportsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "ServersTransport"} // Get takes name of the serversTransport, and returns the corresponding serversTransport object, and an error if there is any. func (c *FakeServersTransports) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ServersTransport, err error) { diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_serverstransporttcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_serverstransporttcp.go new file mode 100644 index 0000000000000000000000000000000000000000..e18ae4db1a636b84f55d409c9da7ad4136a579e9 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_serverstransporttcp.go @@ -0,0 +1,138 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + schema "k8s.io/apimachinery/pkg/runtime/schema" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeServersTransportTCPs implements ServersTransportTCPInterface +type FakeServersTransportTCPs struct { + Fake *FakeTraefikV1alpha1 + ns string +} + +var serverstransporttcpsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "serverstransporttcps"} + +var serverstransporttcpsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "ServersTransportTCP"} + +// Get takes name of the serversTransportTCP, and returns the corresponding serversTransportTCP object, and an error if there is any. +func (c *FakeServersTransportTCPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ServersTransportTCP, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(serverstransporttcpsResource, c.ns, name), &v1alpha1.ServersTransportTCP{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ServersTransportTCP), err +} + +// List takes label and field selectors, and returns the list of ServersTransportTCPs that match those selectors. +func (c *FakeServersTransportTCPs) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ServersTransportTCPList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(serverstransporttcpsResource, serverstransporttcpsKind, c.ns, opts), &v1alpha1.ServersTransportTCPList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1alpha1.ServersTransportTCPList{ListMeta: obj.(*v1alpha1.ServersTransportTCPList).ListMeta} + for _, item := range obj.(*v1alpha1.ServersTransportTCPList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested serversTransportTCPs. +func (c *FakeServersTransportTCPs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(serverstransporttcpsResource, c.ns, opts)) + +} + +// Create takes the representation of a serversTransportTCP and creates it. Returns the server's representation of the serversTransportTCP, and an error, if there is any. +func (c *FakeServersTransportTCPs) Create(ctx context.Context, serversTransportTCP *v1alpha1.ServersTransportTCP, opts v1.CreateOptions) (result *v1alpha1.ServersTransportTCP, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(serverstransporttcpsResource, c.ns, serversTransportTCP), &v1alpha1.ServersTransportTCP{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ServersTransportTCP), err +} + +// Update takes the representation of a serversTransportTCP and updates it. Returns the server's representation of the serversTransportTCP, and an error, if there is any. +func (c *FakeServersTransportTCPs) Update(ctx context.Context, serversTransportTCP *v1alpha1.ServersTransportTCP, opts v1.UpdateOptions) (result *v1alpha1.ServersTransportTCP, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(serverstransporttcpsResource, c.ns, serversTransportTCP), &v1alpha1.ServersTransportTCP{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ServersTransportTCP), err +} + +// Delete takes name of the serversTransportTCP and deletes it. Returns an error if one occurs. +func (c *FakeServersTransportTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteAction(serverstransporttcpsResource, c.ns, name), &v1alpha1.ServersTransportTCP{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeServersTransportTCPs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(serverstransporttcpsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1alpha1.ServersTransportTCPList{}) + return err +} + +// Patch applies the patch and returns the patched serversTransportTCP. +func (c *FakeServersTransportTCPs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ServersTransportTCP, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(serverstransporttcpsResource, c.ns, name, pt, data, subresources...), &v1alpha1.ServersTransportTCP{}) + + if obj == nil { + return nil, err + } + return obj.(*v1alpha1.ServersTransportTCP), err +} diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_tlsoption.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_tlsoption.go similarity index 93% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_tlsoption.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_tlsoption.go index bfcab1e9e344a28da602b8b0eba77d7462eb6ea2..182812ff9c101e5040cfaea8a0749f916d20f958 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_tlsoption.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_tlsoption.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package fake import ( "context" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -44,9 +44,9 @@ type FakeTLSOptions struct { ns string } -var tlsoptionsResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "tlsoptions"} +var tlsoptionsResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "tlsoptions"} -var tlsoptionsKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "TLSOption"} +var tlsoptionsKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "TLSOption"} // Get takes name of the tLSOption, and returns the corresponding tLSOption object, and an error if there is any. func (c *FakeTLSOptions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TLSOption, err error) { diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_tlsstore.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_tlsstore.go similarity index 93% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_tlsstore.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_tlsstore.go index 8fe3e1fb02db74d28efe38a5bdd9e7b5df548b8a..09bd1f8279a370c313d7621cfcd553053c38c01f 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_tlsstore.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_tlsstore.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package fake import ( "context" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -44,9 +44,9 @@ type FakeTLSStores struct { ns string } -var tlsstoresResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "tlsstores"} +var tlsstoresResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "tlsstores"} -var tlsstoresKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "TLSStore"} +var tlsstoresKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "TLSStore"} // Get takes name of the tLSStore, and returns the corresponding tLSStore object, and an error if there is any. func (c *FakeTLSStores) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TLSStore, err error) { diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_traefik_client.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_traefikio_client.go similarity index 88% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_traefik_client.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_traefikio_client.go index c593b1ccd975e20096f7b79c57ad1ecc13e6e4bd..6e6ca7d86b1cb02a85637b31cb60addf23c6b376 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_traefik_client.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_traefikio_client.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package fake import ( - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1" rest "k8s.io/client-go/rest" testing "k8s.io/client-go/testing" ) @@ -60,6 +60,10 @@ func (c *FakeTraefikV1alpha1) ServersTransports(namespace string) v1alpha1.Serve return &FakeServersTransports{c, namespace} } +func (c *FakeTraefikV1alpha1) ServersTransportTCPs(namespace string) v1alpha1.ServersTransportTCPInterface { + return &FakeServersTransportTCPs{c, namespace} +} + func (c *FakeTraefikV1alpha1) TLSOptions(namespace string) v1alpha1.TLSOptionInterface { return &FakeTLSOptions{c, namespace} } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_traefikservice.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_traefikservice.go similarity index 95% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_traefikservice.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_traefikservice.go index d3033538650c2bdac56582832ca8417fc5812c8f..ef3cf30f3ed6eb2a1646873c7662d3618d2cf13d 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/fake/fake_traefikservice.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/fake/fake_traefikservice.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package fake import ( "context" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" labels "k8s.io/apimachinery/pkg/labels" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -44,9 +44,9 @@ type FakeTraefikServices struct { ns string } -var traefikservicesResource = schema.GroupVersionResource{Group: "traefik.containo.us", Version: "v1alpha1", Resource: "traefikservices"} +var traefikservicesResource = schema.GroupVersionResource{Group: "traefik.io", Version: "v1alpha1", Resource: "traefikservices"} -var traefikservicesKind = schema.GroupVersionKind{Group: "traefik.containo.us", Version: "v1alpha1", Kind: "TraefikService"} +var traefikservicesKind = schema.GroupVersionKind{Group: "traefik.io", Version: "v1alpha1", Kind: "TraefikService"} // Get takes name of the traefikService, and returns the corresponding traefikService object, and an error if there is any. func (c *FakeTraefikServices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.TraefikService, err error) { diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/generated_expansion.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/generated_expansion.go similarity index 93% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/generated_expansion.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/generated_expansion.go index a252692a73b424b01dce08269d6f43c34c2f9894..0fbf0a82f0eaaf7e9f37884e00847e8acde89146 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/generated_expansion.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/generated_expansion.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -38,6 +38,8 @@ type MiddlewareTCPExpansion interface{} type ServersTransportExpansion interface{} +type ServersTransportTCPExpansion interface{} + type TLSOptionExpansion interface{} type TLSStoreExpansion interface{} diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroute.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressroute.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroute.go index 32021452ead65c448b9e8414e2f3339a7458a95d..6ec9217603f5d3b233fd5b9603ad068ac27e22ee 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressroute.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroute.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,8 @@ import ( "context" "time" - scheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + scheme "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroutetcp.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressroutetcp.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroutetcp.go index e32f1622ade766bf74cdbfc1b369d33301a9bcd2..93caa16aa3a2646c827962d4280b95f857355cba 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressroutetcp.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressroutetcp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,8 @@ import ( "context" "time" - scheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + scheme "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressrouteudp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressrouteudp.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressrouteudp.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressrouteudp.go index 9c2db2a100982b87bf4c6ba74597b9ff4e9bbd6c..74dab24ac7f8283e215152d16f1f98d74e6c99e1 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/ingressrouteudp.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/ingressrouteudp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,8 @@ import ( "context" "time" - scheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + scheme "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/middleware.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middleware.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/middleware.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middleware.go index b6b895ed16f8061efd952f9c55c1df866670c7d8..615f8d20012f3b53ced4df0dc46b573597bf73d6 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/middleware.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middleware.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,8 @@ import ( "context" "time" - scheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + scheme "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/middlewaretcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middlewaretcp.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/middlewaretcp.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middlewaretcp.go index 563b2c6da4a1ab517bee73cec982d7966fc78822..ca4c596f90220ccd2a0a45af4b31a9364054a993 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/middlewaretcp.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/middlewaretcp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,8 @@ import ( "context" "time" - scheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + scheme "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/serverstransport.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransport.go similarity index 97% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/serverstransport.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransport.go index 89f015e9a203c3f17315f7a7bd065dc4153be5b1..cc1b467faf07c8d6f4c6094b7df3b76e141f923a 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/serverstransport.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransport.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,8 @@ import ( "context" "time" - scheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + scheme "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransporttcp.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransporttcp.go new file mode 100644 index 0000000000000000000000000000000000000000..ba1c1bd07e333e569fc4eca3067421abe40bec90 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/serverstransporttcp.go @@ -0,0 +1,186 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + "time" + + scheme "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ServersTransportTCPsGetter has a method to return a ServersTransportTCPInterface. +// A group's client should implement this interface. +type ServersTransportTCPsGetter interface { + ServersTransportTCPs(namespace string) ServersTransportTCPInterface +} + +// ServersTransportTCPInterface has methods to work with ServersTransportTCP resources. +type ServersTransportTCPInterface interface { + Create(ctx context.Context, serversTransportTCP *v1alpha1.ServersTransportTCP, opts v1.CreateOptions) (*v1alpha1.ServersTransportTCP, error) + Update(ctx context.Context, serversTransportTCP *v1alpha1.ServersTransportTCP, opts v1.UpdateOptions) (*v1alpha1.ServersTransportTCP, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ServersTransportTCP, error) + List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ServersTransportTCPList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ServersTransportTCP, err error) + ServersTransportTCPExpansion +} + +// serversTransportTCPs implements ServersTransportTCPInterface +type serversTransportTCPs struct { + client rest.Interface + ns string +} + +// newServersTransportTCPs returns a ServersTransportTCPs +func newServersTransportTCPs(c *TraefikV1alpha1Client, namespace string) *serversTransportTCPs { + return &serversTransportTCPs{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the serversTransportTCP, and returns the corresponding serversTransportTCP object, and an error if there is any. +func (c *serversTransportTCPs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ServersTransportTCP, err error) { + result = &v1alpha1.ServersTransportTCP{} + err = c.client.Get(). + Namespace(c.ns). + Resource("serverstransporttcps"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ServersTransportTCPs that match those selectors. +func (c *serversTransportTCPs) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ServersTransportTCPList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1alpha1.ServersTransportTCPList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("serverstransporttcps"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested serversTransportTCPs. +func (c *serversTransportTCPs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("serverstransporttcps"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a serversTransportTCP and creates it. Returns the server's representation of the serversTransportTCP, and an error, if there is any. +func (c *serversTransportTCPs) Create(ctx context.Context, serversTransportTCP *v1alpha1.ServersTransportTCP, opts v1.CreateOptions) (result *v1alpha1.ServersTransportTCP, err error) { + result = &v1alpha1.ServersTransportTCP{} + err = c.client.Post(). + Namespace(c.ns). + Resource("serverstransporttcps"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(serversTransportTCP). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a serversTransportTCP and updates it. Returns the server's representation of the serversTransportTCP, and an error, if there is any. +func (c *serversTransportTCPs) Update(ctx context.Context, serversTransportTCP *v1alpha1.ServersTransportTCP, opts v1.UpdateOptions) (result *v1alpha1.ServersTransportTCP, err error) { + result = &v1alpha1.ServersTransportTCP{} + err = c.client.Put(). + Namespace(c.ns). + Resource("serverstransporttcps"). + Name(serversTransportTCP.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(serversTransportTCP). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the serversTransportTCP and deletes it. Returns an error if one occurs. +func (c *serversTransportTCPs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("serverstransporttcps"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *serversTransportTCPs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("serverstransporttcps"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched serversTransportTCP. +func (c *serversTransportTCPs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ServersTransportTCP, err error) { + result = &v1alpha1.ServersTransportTCP{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("serverstransporttcps"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsoption.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/tlsoption.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsoption.go index bc9556934233545d2959753457dd34eb5d22660f..24ba147f17db78ccab53769047ccdc086dfc1d9b 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsoption.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,8 @@ import ( "context" "time" - scheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + scheme "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/tlsstore.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsstore.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/tlsstore.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsstore.go index e90d79e459ad29f1825a3707ba74d713f4055ea2..1f66fb4822dd2efdfca7c16b4ca558810abef4df 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/tlsstore.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/tlsstore.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,8 @@ import ( "context" "time" - scheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + scheme "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/traefik_client.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/traefikio_client.go similarity index 90% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/traefik_client.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/traefikio_client.go index 2682dbad5066aa028c10a5b2cfd566b3c4c2993a..6de07c33c3dd0dbb2349a8162c51e19b6fedb316 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/traefik_client.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/traefikio_client.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,8 +27,8 @@ THE SOFTWARE. package v1alpha1 import ( - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" rest "k8s.io/client-go/rest" ) @@ -40,12 +40,13 @@ type TraefikV1alpha1Interface interface { MiddlewaresGetter MiddlewareTCPsGetter ServersTransportsGetter + ServersTransportTCPsGetter TLSOptionsGetter TLSStoresGetter TraefikServicesGetter } -// TraefikV1alpha1Client is used to interact with features provided by the traefik.containo.us group. +// TraefikV1alpha1Client is used to interact with features provided by the traefik.io group. type TraefikV1alpha1Client struct { restClient rest.Interface } @@ -74,6 +75,10 @@ func (c *TraefikV1alpha1Client) ServersTransports(namespace string) ServersTrans return newServersTransports(c, namespace) } +func (c *TraefikV1alpha1Client) ServersTransportTCPs(namespace string) ServersTransportTCPInterface { + return newServersTransportTCPs(c, namespace) +} + func (c *TraefikV1alpha1Client) TLSOptions(namespace string) TLSOptionInterface { return newTLSOptions(c, namespace) } diff --git a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/traefikservice.go b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/traefikservice.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/traefikservice.go rename to pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/traefikservice.go index ad5f093f47e7089d4ec8c1f6ac3670e4bed29822..e838894729d4994fcda0591a461bad10aebdee67 100644 --- a/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefik/v1alpha1/traefikservice.go +++ b/pkg/provider/kubernetes/crd/generated/clientset/versioned/typed/traefikio/v1alpha1/traefikservice.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,8 +30,8 @@ import ( "context" "time" - scheme "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + scheme "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" types "k8s.io/apimachinery/pkg/types" watch "k8s.io/apimachinery/pkg/watch" diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/factory.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/factory.go index d198621df3eabc07deb8c85b9be92b601f288de2..75b79d658a0a0d6cabc4c402c96644ab7239bd6c 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/factory.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/factory.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -31,9 +31,9 @@ import ( sync "sync" time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - traefik "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + traefikio "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" schema "k8s.io/apimachinery/pkg/runtime/schema" @@ -180,9 +180,9 @@ type SharedInformerFactory interface { ForResource(resource schema.GroupVersionResource) (GenericInformer, error) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool - Traefik() traefik.Interface + Traefik() traefikio.Interface } -func (f *sharedInformerFactory) Traefik() traefik.Interface { - return traefik.New(f, f.namespace, f.tweakListOptions) +func (f *sharedInformerFactory) Traefik() traefikio.Interface { + return traefikio.New(f, f.namespace, f.tweakListOptions) } diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/generic.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/generic.go index a062e290df797319ea02540a5b264a573eafae57..93ba25251959ef86ea6a5d330647e8cfdbb733d1 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/generic.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/generic.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package externalversions import ( "fmt" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" ) @@ -60,7 +60,7 @@ func (f *genericInformer) Lister() cache.GenericLister { // TODO extend this to unknown resources with a client pool func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { switch resource { - // Group=traefik.containo.us, Version=v1alpha1 + // Group=traefik.io, Version=v1alpha1 case v1alpha1.SchemeGroupVersion.WithResource("ingressroutes"): return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().IngressRoutes().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("ingressroutetcps"): @@ -73,6 +73,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().MiddlewareTCPs().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("serverstransports"): return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().ServersTransports().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("serverstransporttcps"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().ServersTransportTCPs().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("tlsoptions"): return &genericInformer{resource: resource.GroupResource(), informer: f.Traefik().V1alpha1().TLSOptions().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("tlsstores"): diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces/factory_interfaces.go index 0809220e6bc2a81639a735710e2af9c6043d68e3..6af7a12d8bef5df78748d6b1a66a4f79874249a5 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -29,7 +29,7 @@ package internalinterfaces import ( time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" cache "k8s.io/client-go/tools/cache" diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/interface.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/interface.go similarity index 87% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/interface.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/interface.go index 8bc5dfcd23fb2587a78bf3ffec2100b38bb5e3e0..22009c56e703f7321c2a948157bcc14d37cf8366 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/interface.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/interface.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -24,11 +24,11 @@ THE SOFTWARE. // Code generated by informer-gen. DO NOT EDIT. -package traefik +package traefikio import ( - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1" ) // Interface provides access to each of this group's versions. diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/ingressroute.go similarity index 88% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressroute.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/ingressroute.go index 49c8df23821989160cb1d1065324f86c08431001..c2293518fc5c30743816d48562138b1bfb4ddaa3 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressroute.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/ingressroute.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,10 +30,10 @@ import ( "context" time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1" + traefikiov1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -79,7 +79,7 @@ func NewFilteredIngressRouteInformer(client versioned.Interface, namespace strin return client.TraefikV1alpha1().IngressRoutes(namespace).Watch(context.TODO(), options) }, }, - &traefikv1alpha1.IngressRoute{}, + &traefikiov1alpha1.IngressRoute{}, resyncPeriod, indexers, ) @@ -90,7 +90,7 @@ func (f *ingressRouteInformer) defaultInformer(client versioned.Interface, resyn } func (f *ingressRouteInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&traefikv1alpha1.IngressRoute{}, f.defaultInformer) + return f.factory.InformerFor(&traefikiov1alpha1.IngressRoute{}, f.defaultInformer) } func (f *ingressRouteInformer) Lister() v1alpha1.IngressRouteLister { diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/ingressroutetcp.go similarity index 88% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressroutetcp.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/ingressroutetcp.go index 4fecc2bddb10b800bc733b951415bfd367487887..0ed00501a89b4aa3222616b9bd20df3d5cbc4af9 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressroutetcp.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/ingressroutetcp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,10 +30,10 @@ import ( "context" time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1" + traefikiov1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -79,7 +79,7 @@ func NewFilteredIngressRouteTCPInformer(client versioned.Interface, namespace st return client.TraefikV1alpha1().IngressRouteTCPs(namespace).Watch(context.TODO(), options) }, }, - &traefikv1alpha1.IngressRouteTCP{}, + &traefikiov1alpha1.IngressRouteTCP{}, resyncPeriod, indexers, ) @@ -90,7 +90,7 @@ func (f *ingressRouteTCPInformer) defaultInformer(client versioned.Interface, re } func (f *ingressRouteTCPInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&traefikv1alpha1.IngressRouteTCP{}, f.defaultInformer) + return f.factory.InformerFor(&traefikiov1alpha1.IngressRouteTCP{}, f.defaultInformer) } func (f *ingressRouteTCPInformer) Lister() v1alpha1.IngressRouteTCPLister { diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressrouteudp.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/ingressrouteudp.go similarity index 88% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressrouteudp.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/ingressrouteudp.go index 4b4b007438c76b3a0879a146a3f4af6bd2c5e38a..68787c969da20fd717d3755358e3355208411693 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/ingressrouteudp.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/ingressrouteudp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,10 +30,10 @@ import ( "context" time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1" + traefikiov1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -79,7 +79,7 @@ func NewFilteredIngressRouteUDPInformer(client versioned.Interface, namespace st return client.TraefikV1alpha1().IngressRouteUDPs(namespace).Watch(context.TODO(), options) }, }, - &traefikv1alpha1.IngressRouteUDP{}, + &traefikiov1alpha1.IngressRouteUDP{}, resyncPeriod, indexers, ) @@ -90,7 +90,7 @@ func (f *ingressRouteUDPInformer) defaultInformer(client versioned.Interface, re } func (f *ingressRouteUDPInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&traefikv1alpha1.IngressRouteUDP{}, f.defaultInformer) + return f.factory.InformerFor(&traefikiov1alpha1.IngressRouteUDP{}, f.defaultInformer) } func (f *ingressRouteUDPInformer) Lister() v1alpha1.IngressRouteUDPLister { diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/interface.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/interface.go similarity index 90% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/interface.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/interface.go index 563e81956e8c84bf023537871a33e37c91829ed8..a611e3c78e05147bb23ee8b4ce6f958cec0e0df3 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/interface.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/interface.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package v1alpha1 import ( - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" ) // Interface provides access to all the informers in this group version. @@ -44,6 +44,8 @@ type Interface interface { MiddlewareTCPs() MiddlewareTCPInformer // ServersTransports returns a ServersTransportInformer. ServersTransports() ServersTransportInformer + // ServersTransportTCPs returns a ServersTransportTCPInformer. + ServersTransportTCPs() ServersTransportTCPInformer // TLSOptions returns a TLSOptionInformer. TLSOptions() TLSOptionInformer // TLSStores returns a TLSStoreInformer. @@ -93,6 +95,11 @@ func (v *version) ServersTransports() ServersTransportInformer { return &serversTransportInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } +// ServersTransportTCPs returns a ServersTransportTCPInformer. +func (v *version) ServersTransportTCPs() ServersTransportTCPInformer { + return &serversTransportTCPInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // TLSOptions returns a TLSOptionInformer. func (v *version) TLSOptions() TLSOptionInformer { return &tLSOptionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/middleware.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/middleware.go similarity index 88% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/middleware.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/middleware.go index 80e2679ba8b7203ca2bda51d69e932f7c459bce7..9a00c146bf8b2563b550403e165c908260fa23a3 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/middleware.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/middleware.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,10 +30,10 @@ import ( "context" time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1" + traefikiov1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -79,7 +79,7 @@ func NewFilteredMiddlewareInformer(client versioned.Interface, namespace string, return client.TraefikV1alpha1().Middlewares(namespace).Watch(context.TODO(), options) }, }, - &traefikv1alpha1.Middleware{}, + &traefikiov1alpha1.Middleware{}, resyncPeriod, indexers, ) @@ -90,7 +90,7 @@ func (f *middlewareInformer) defaultInformer(client versioned.Interface, resyncP } func (f *middlewareInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&traefikv1alpha1.Middleware{}, f.defaultInformer) + return f.factory.InformerFor(&traefikiov1alpha1.Middleware{}, f.defaultInformer) } func (f *middlewareInformer) Lister() v1alpha1.MiddlewareLister { diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/middlewaretcp.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/middlewaretcp.go similarity index 88% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/middlewaretcp.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/middlewaretcp.go index 2285d4a4b660bdbdb11b21adf825221b4029961b..8b547fc45d0b68a604e7807440e91a4874d9a90e 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/middlewaretcp.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/middlewaretcp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,10 +30,10 @@ import ( "context" time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1" + traefikiov1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -79,7 +79,7 @@ func NewFilteredMiddlewareTCPInformer(client versioned.Interface, namespace stri return client.TraefikV1alpha1().MiddlewareTCPs(namespace).Watch(context.TODO(), options) }, }, - &traefikv1alpha1.MiddlewareTCP{}, + &traefikiov1alpha1.MiddlewareTCP{}, resyncPeriod, indexers, ) @@ -90,7 +90,7 @@ func (f *middlewareTCPInformer) defaultInformer(client versioned.Interface, resy } func (f *middlewareTCPInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&traefikv1alpha1.MiddlewareTCP{}, f.defaultInformer) + return f.factory.InformerFor(&traefikiov1alpha1.MiddlewareTCP{}, f.defaultInformer) } func (f *middlewareTCPInformer) Lister() v1alpha1.MiddlewareTCPLister { diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/serverstransport.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/serverstransport.go similarity index 88% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/serverstransport.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/serverstransport.go index dfd10f4850c1fb8fa4991e78ff6580bffad10e8d..cd76b44579fa8240b00d2741864f393c28f1ad47 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/serverstransport.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/serverstransport.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,10 +30,10 @@ import ( "context" time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1" + traefikiov1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -79,7 +79,7 @@ func NewFilteredServersTransportInformer(client versioned.Interface, namespace s return client.TraefikV1alpha1().ServersTransports(namespace).Watch(context.TODO(), options) }, }, - &traefikv1alpha1.ServersTransport{}, + &traefikiov1alpha1.ServersTransport{}, resyncPeriod, indexers, ) @@ -90,7 +90,7 @@ func (f *serversTransportInformer) defaultInformer(client versioned.Interface, r } func (f *serversTransportInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&traefikv1alpha1.ServersTransport{}, f.defaultInformer) + return f.factory.InformerFor(&traefikiov1alpha1.ServersTransport{}, f.defaultInformer) } func (f *serversTransportInformer) Lister() v1alpha1.ServersTransportLister { diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/serverstransporttcp.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/serverstransporttcp.go new file mode 100644 index 0000000000000000000000000000000000000000..467e2fad1beff620ad297c85a88aa4df1e4d8723 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/serverstransporttcp.go @@ -0,0 +1,98 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + time "time" + + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1" + traefikiov1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ServersTransportTCPInformer provides access to a shared informer and lister for +// ServersTransportTCPs. +type ServersTransportTCPInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1alpha1.ServersTransportTCPLister +} + +type serversTransportTCPInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewServersTransportTCPInformer constructs a new informer for ServersTransportTCP type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewServersTransportTCPInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredServersTransportTCPInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredServersTransportTCPInformer constructs a new informer for ServersTransportTCP type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredServersTransportTCPInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.TraefikV1alpha1().ServersTransportTCPs(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.TraefikV1alpha1().ServersTransportTCPs(namespace).Watch(context.TODO(), options) + }, + }, + &traefikiov1alpha1.ServersTransportTCP{}, + resyncPeriod, + indexers, + ) +} + +func (f *serversTransportTCPInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredServersTransportTCPInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *serversTransportTCPInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&traefikiov1alpha1.ServersTransportTCP{}, f.defaultInformer) +} + +func (f *serversTransportTCPInformer) Lister() v1alpha1.ServersTransportTCPLister { + return v1alpha1.NewServersTransportTCPLister(f.Informer().GetIndexer()) +} diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/tlsoption.go similarity index 88% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/tlsoption.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/tlsoption.go index 7e1f3ad68507537e6a4b2bf27b23359992f819ec..34336133b59809ddafa85abe53888ac840218004 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/tlsoption.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,10 +30,10 @@ import ( "context" time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1" + traefikiov1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -79,7 +79,7 @@ func NewFilteredTLSOptionInformer(client versioned.Interface, namespace string, return client.TraefikV1alpha1().TLSOptions(namespace).Watch(context.TODO(), options) }, }, - &traefikv1alpha1.TLSOption{}, + &traefikiov1alpha1.TLSOption{}, resyncPeriod, indexers, ) @@ -90,7 +90,7 @@ func (f *tLSOptionInformer) defaultInformer(client versioned.Interface, resyncPe } func (f *tLSOptionInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&traefikv1alpha1.TLSOption{}, f.defaultInformer) + return f.factory.InformerFor(&traefikiov1alpha1.TLSOption{}, f.defaultInformer) } func (f *tLSOptionInformer) Lister() v1alpha1.TLSOptionLister { diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/tlsstore.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/tlsstore.go similarity index 88% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/tlsstore.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/tlsstore.go index c017915f3a3bba4f63e81ffe15ff68010bac47e6..56314fa203cb394c438142db36230cfeda12b9ac 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/tlsstore.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/tlsstore.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,10 +30,10 @@ import ( "context" time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1" + traefikiov1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -79,7 +79,7 @@ func NewFilteredTLSStoreInformer(client versioned.Interface, namespace string, r return client.TraefikV1alpha1().TLSStores(namespace).Watch(context.TODO(), options) }, }, - &traefikv1alpha1.TLSStore{}, + &traefikiov1alpha1.TLSStore{}, resyncPeriod, indexers, ) @@ -90,7 +90,7 @@ func (f *tLSStoreInformer) defaultInformer(client versioned.Interface, resyncPer } func (f *tLSStoreInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&traefikv1alpha1.TLSStore{}, f.defaultInformer) + return f.factory.InformerFor(&traefikiov1alpha1.TLSStore{}, f.defaultInformer) } func (f *tLSStoreInformer) Lister() v1alpha1.TLSStoreLister { diff --git a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/traefikservice.go b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/traefikservice.go similarity index 88% rename from pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/traefikservice.go rename to pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/traefikservice.go index 8a3dce49cf6c998b1d625d9af14695a3b5f28af2..59dd21c71cf1ca1f0e447cda9127773975759cd8 100644 --- a/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefik/v1alpha1/traefikservice.go +++ b/pkg/provider/kubernetes/crd/generated/informers/externalversions/traefikio/v1alpha1/traefikservice.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,10 +30,10 @@ import ( "context" time "time" - versioned "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned" - internalinterfaces "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + versioned "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned" + internalinterfaces "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/informers/externalversions/internalinterfaces" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1" + traefikiov1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" watch "k8s.io/apimachinery/pkg/watch" @@ -79,7 +79,7 @@ func NewFilteredTraefikServiceInformer(client versioned.Interface, namespace str return client.TraefikV1alpha1().TraefikServices(namespace).Watch(context.TODO(), options) }, }, - &traefikv1alpha1.TraefikService{}, + &traefikiov1alpha1.TraefikService{}, resyncPeriod, indexers, ) @@ -90,7 +90,7 @@ func (f *traefikServiceInformer) defaultInformer(client versioned.Interface, res } func (f *traefikServiceInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&traefikv1alpha1.TraefikService{}, f.defaultInformer) + return f.factory.InformerFor(&traefikiov1alpha1.TraefikService{}, f.defaultInformer) } func (f *traefikServiceInformer) Lister() v1alpha1.TraefikServiceLister { diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/expansion_generated.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/expansion_generated.go similarity index 90% rename from pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/expansion_generated.go rename to pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/expansion_generated.go index c338fb9765dfbd85f284d0abc3276729f20de1b0..a8df13373bb093b8716be3d77d86f523c5c55f0d 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/expansion_generated.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/expansion_generated.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -74,6 +74,14 @@ type ServersTransportListerExpansion interface{} // ServersTransportNamespaceLister. type ServersTransportNamespaceListerExpansion interface{} +// ServersTransportTCPListerExpansion allows custom methods to be added to +// ServersTransportTCPLister. +type ServersTransportTCPListerExpansion interface{} + +// ServersTransportTCPNamespaceListerExpansion allows custom methods to be added to +// ServersTransportTCPNamespaceLister. +type ServersTransportTCPNamespaceListerExpansion interface{} + // TLSOptionListerExpansion allows custom methods to be added to // TLSOptionLister. type TLSOptionListerExpansion interface{} diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/ingressroute.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressroute.go rename to pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/ingressroute.go index 532620c79eb60df2cde995d746ef7caa5f58b0c9..dbbcd28fe5d1449dd4aad0787682e32fd6f50199 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressroute.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/ingressroute.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package v1alpha1 import ( - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/ingressroutetcp.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressroutetcp.go rename to pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/ingressroutetcp.go index 8bdd6c94c1f13463323e37920773d0fae722e654..63ffc06b1b534ee463f28c52411488a01062cf9c 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressroutetcp.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/ingressroutetcp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package v1alpha1 import ( - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressrouteudp.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/ingressrouteudp.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressrouteudp.go rename to pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/ingressrouteudp.go index 4c8166d94b4f55957a1f61a1aa941171faad6f10..7156f8bf98feb2ac4cfef33d85f3aac3a3e478d1 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/ingressrouteudp.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/ingressrouteudp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package v1alpha1 import ( - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/middleware.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/middleware.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/middleware.go rename to pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/middleware.go index 89ec6190f4504f980741ee023685b7efd5aab991..c69ef6beae300c2bde92881e83df9df678ee0a89 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/middleware.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/middleware.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package v1alpha1 import ( - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/middlewaretcp.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/middlewaretcp.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/middlewaretcp.go rename to pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/middlewaretcp.go index 597cbcd9744e12fd0fbf2fcb698ed88f92bd4c7e..388537233dd639ddcbcb94cf4d92d1fd9f3b6712 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/middlewaretcp.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/middlewaretcp.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package v1alpha1 import ( - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/serverstransport.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/serverstransport.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/serverstransport.go rename to pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/serverstransport.go index 1d18bf9fc94edcbe6bb1eb88ad0991bdc7a4351e..2532091faefa9a57d49f5b5faec15e7515b14ed0 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/serverstransport.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/serverstransport.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package v1alpha1 import ( - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/serverstransporttcp.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/serverstransporttcp.go new file mode 100644 index 0000000000000000000000000000000000000000..2b2354e1a4edded6dbed047b6371b24cc8633e64 --- /dev/null +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/serverstransporttcp.go @@ -0,0 +1,107 @@ +/* +The MIT License (MIT) + +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ServersTransportTCPLister helps list ServersTransportTCPs. +// All objects returned here must be treated as read-only. +type ServersTransportTCPLister interface { + // List lists all ServersTransportTCPs in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ServersTransportTCP, err error) + // ServersTransportTCPs returns an object that can list and get ServersTransportTCPs. + ServersTransportTCPs(namespace string) ServersTransportTCPNamespaceLister + ServersTransportTCPListerExpansion +} + +// serversTransportTCPLister implements the ServersTransportTCPLister interface. +type serversTransportTCPLister struct { + indexer cache.Indexer +} + +// NewServersTransportTCPLister returns a new ServersTransportTCPLister. +func NewServersTransportTCPLister(indexer cache.Indexer) ServersTransportTCPLister { + return &serversTransportTCPLister{indexer: indexer} +} + +// List lists all ServersTransportTCPs in the indexer. +func (s *serversTransportTCPLister) List(selector labels.Selector) (ret []*v1alpha1.ServersTransportTCP, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ServersTransportTCP)) + }) + return ret, err +} + +// ServersTransportTCPs returns an object that can list and get ServersTransportTCPs. +func (s *serversTransportTCPLister) ServersTransportTCPs(namespace string) ServersTransportTCPNamespaceLister { + return serversTransportTCPNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ServersTransportTCPNamespaceLister helps list and get ServersTransportTCPs. +// All objects returned here must be treated as read-only. +type ServersTransportTCPNamespaceLister interface { + // List lists all ServersTransportTCPs in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1alpha1.ServersTransportTCP, err error) + // Get retrieves the ServersTransportTCP from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1alpha1.ServersTransportTCP, error) + ServersTransportTCPNamespaceListerExpansion +} + +// serversTransportTCPNamespaceLister implements the ServersTransportTCPNamespaceLister +// interface. +type serversTransportTCPNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ServersTransportTCPs in the indexer for a given namespace. +func (s serversTransportTCPNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ServersTransportTCP, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1alpha1.ServersTransportTCP)) + }) + return ret, err +} + +// Get retrieves the ServersTransportTCP from the indexer for a given namespace and name. +func (s serversTransportTCPNamespaceLister) Get(name string) (*v1alpha1.ServersTransportTCP, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1alpha1.Resource("serverstransporttcp"), name) + } + return obj.(*v1alpha1.ServersTransportTCP), nil +} diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/tlsoption.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/tlsoption.go rename to pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/tlsoption.go index 1d6fc90496d9bb19c102173c675b84081b972a79..520c95da141fd90c8afb6205bba0c2a9ff6c65fe 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/tlsoption.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/tlsoption.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package v1alpha1 import ( - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/tlsstore.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/tlsstore.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/tlsstore.go rename to pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/tlsstore.go index 8c79402c1c309ff20b213bc03e5a0e38fc878efc..9687ba4920428b81b127bfb007fa7dd2fc418fc0 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/tlsstore.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/tlsstore.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package v1alpha1 import ( - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" diff --git a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/traefikservice.go b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/traefikservice.go similarity index 96% rename from pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/traefikservice.go rename to pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/traefikservice.go index 89e8f4d8587564eee9e583b6388dc90bde088c02..cb4331c100fbbbcda26db8b8aaac945435496516 100644 --- a/pkg/provider/kubernetes/crd/generated/listers/traefik/v1alpha1/traefikservice.go +++ b/pkg/provider/kubernetes/crd/generated/listers/traefikio/v1alpha1/traefikservice.go @@ -1,7 +1,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -27,7 +27,7 @@ THE SOFTWARE. package v1alpha1 import ( - v1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + v1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/tools/cache" diff --git a/pkg/provider/kubernetes/crd/kubernetes.go b/pkg/provider/kubernetes/crd/kubernetes.go index f2054d09eda09f4f2fa12f7d31687a52b75f76da..c0180b639b1e848f6fcf80c56eb039bb1867274d 100644 --- a/pkg/provider/kubernetes/crd/kubernetes.go +++ b/pkg/provider/kubernetes/crd/kubernetes.go @@ -10,8 +10,10 @@ import ( "encoding/json" "errors" "fmt" + "net" "os" "sort" + "strconv" "strings" "time" @@ -19,14 +21,14 @@ import ( "github.com/mitchellh/hashstructure" "github.com/rs/zerolog/log" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/job" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" corev1 "k8s.io/api/core/v1" apiextensionv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/labels" @@ -102,6 +104,8 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe. logger := log.With().Str(logs.ProviderName, providerName).Logger() ctxLog := logger.WithContext(context.Background()) + logger.Warn().Msg("CRDs API Version \"traefik.io/v1alpha1\" will not be supported in Traefik v3 itself. However, an automatic migration path to the next version will be available.") + k8sClient, err := p.newK8sClient(ctxLog) if err != nil { return err @@ -393,9 +397,84 @@ func (p *Provider) loadConfigurationFromCRD(ctx context.Context, client Client) } } + for _, serversTransportTCP := range client.GetServersTransportTCPs() { + logger := log.Ctx(ctx).With().Str(logs.ServersTransportName, serversTransportTCP.Name).Logger() + + var tcpServerTransport dynamic.TCPServersTransport + tcpServerTransport.SetDefaults() + + if serversTransportTCP.Spec.DialTimeout != nil { + err := tcpServerTransport.DialTimeout.Set(serversTransportTCP.Spec.DialTimeout.String()) + if err != nil { + logger.Error().Err(err).Msg("Error while reading DialTimeout") + } + } + + if serversTransportTCP.Spec.DialKeepAlive != nil { + err := tcpServerTransport.DialKeepAlive.Set(serversTransportTCP.Spec.DialKeepAlive.String()) + if err != nil { + logger.Error().Err(err).Msg("Error while reading DialKeepAlive") + } + } + + if serversTransportTCP.Spec.TerminationDelay != nil { + err := tcpServerTransport.TerminationDelay.Set(serversTransportTCP.Spec.TerminationDelay.String()) + if err != nil { + logger.Error().Err(err).Msg("Error while reading TerminationDelay") + } + } + + if serversTransportTCP.Spec.TLS != nil { + var rootCAs []tls.FileOrContent + for _, secret := range serversTransportTCP.Spec.TLS.RootCAsSecrets { + caSecret, err := loadCASecret(serversTransportTCP.Namespace, secret, client) + if err != nil { + logger.Error(). + Err(err). + Str("rootCAs", secret). + Msg("Error while loading rootCAs") + continue + } + + rootCAs = append(rootCAs, tls.FileOrContent(caSecret)) + } + + var certs tls.Certificates + for _, secret := range serversTransportTCP.Spec.TLS.CertificatesSecrets { + tlsCert, tlsKey, err := loadAuthTLSSecret(serversTransportTCP.Namespace, secret, client) + if err != nil { + logger.Error(). + Err(err). + Str("certificates", secret). + Msg("Error while loading certificates") + continue + } + + certs = append(certs, tls.Certificate{ + CertFile: tls.FileOrContent(tlsCert), + KeyFile: tls.FileOrContent(tlsKey), + }) + } + + tcpServerTransport.TLS = &dynamic.TLSClientConfig{ + ServerName: serversTransportTCP.Spec.TLS.ServerName, + InsecureSkipVerify: serversTransportTCP.Spec.TLS.InsecureSkipVerify, + RootCAs: rootCAs, + Certificates: certs, + PeerCertURI: serversTransportTCP.Spec.TLS.PeerCertURI, + } + + tcpServerTransport.TLS.Spiffe = serversTransportTCP.Spec.TLS.Spiffe + } + + id := provider.Normalize(makeID(serversTransportTCP.Namespace, serversTransportTCP.Name)) + conf.TCP.ServersTransports[id] = &tcpServerTransport + } + return conf } +// getServicePort always returns a valid port, an error otherwise. func getServicePort(svc *corev1.Service, port intstr.IntOrString) (*corev1.ServicePort, error) { if svc == nil { return nil, errors.New("service is not defined") @@ -428,6 +507,18 @@ func getServicePort(svc *corev1.Service, port intstr.IntOrString) (*corev1.Servi return &corev1.ServicePort{Port: port.IntVal}, nil } +func getNativeServiceAddress(service corev1.Service, svcPort corev1.ServicePort) (string, error) { + if service.Spec.ClusterIP == "None" { + return "", fmt.Errorf("no clusterIP on headless service: %s/%s", service.Namespace, service.Name) + } + + if service.Spec.ClusterIP == "" { + return "", fmt.Errorf("no clusterIP found for service: %s/%s", service.Namespace, service.Name) + } + + return net.JoinHostPort(service.Spec.ClusterIP, strconv.Itoa(int(svcPort.Port))), nil +} + func createPluginMiddleware(k8sClient Client, ns string, plugins map[string]apiextensionv1.JSON) (map[string]dynamic.PluginConf, error) { if plugins == nil { return nil, nil diff --git a/pkg/provider/kubernetes/crd/kubernetes_http.go b/pkg/provider/kubernetes/crd/kubernetes_http.go index fa8bed11d7e4914de0b4caf6f2a2511dcd86f675..66eb87dcd3a582e435f783df63df44fbb26d4a90 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_http.go +++ b/pkg/provider/kubernetes/crd/kubernetes_http.go @@ -9,11 +9,11 @@ import ( "strings" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + "github.com/traefik/traefik/v3/pkg/tls" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -374,6 +374,20 @@ func (c configBuilder) loadServers(parentNamespace string, svc v1alpha1.LoadBala return nil, err } + if svc.NativeLB { + address, err := getNativeServiceAddress(*service, *svcPort) + if err != nil { + return nil, fmt.Errorf("getting native Kubernetes Service address: %w", err) + } + + protocol, err := parseServiceProtocol(svc.Scheme, svcPort.Name, svcPort.Port) + if err != nil { + return nil, err + } + + return []dynamic.Server{{URL: fmt.Sprintf("%s://%s", protocol, address)}}, nil + } + var servers []dynamic.Server if service.Spec.Type == corev1.ServiceTypeExternalName { if !c.allowExternalNameServices { diff --git a/pkg/provider/kubernetes/crd/kubernetes_tcp.go b/pkg/provider/kubernetes/crd/kubernetes_tcp.go index bdb11ee338171872fc7ff0c490d1a0feab36f74e..374a2a7ab20a577446b3de30def2d0a818ecc5dc 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_tcp.go +++ b/pkg/provider/kubernetes/crd/kubernetes_tcp.go @@ -9,19 +9,20 @@ import ( "strings" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + "github.com/traefik/traefik/v3/pkg/tls" corev1 "k8s.io/api/core/v1" ) func (p *Provider) loadIngressRouteTCPConfiguration(ctx context.Context, client Client, tlsConfigs map[string]*tls.CertAndStores) *dynamic.TCPConfiguration { conf := &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, } for _, ingressRouteTCP := range client.GetIngressRouteTCPs() { @@ -202,8 +203,11 @@ func (p *Provider) createLoadBalancerServerTCP(client Client, parentNamespace st } } - if service.TerminationDelay != nil { - tcpService.LoadBalancer.TerminationDelay = service.TerminationDelay + if service.ServersTransport != "" { + tcpService.LoadBalancer.ServersTransport, err = p.makeTCPServersTransportKey(parentNamespace, service.ServersTransport) + if err != nil { + return nil, err + } } return tcpService, nil @@ -228,6 +232,15 @@ func (p *Provider) loadTCPServers(client Client, namespace string, svc v1alpha1. return nil, err } + if svc.NativeLB { + address, err := getNativeServiceAddress(*service, *svcPort) + if err != nil { + return nil, fmt.Errorf("getting native Kubernetes Service address: %w", err) + } + + return []dynamic.TCPServer{{Address: address}}, nil + } + var servers []dynamic.TCPServer if service.Spec.Type == corev1.ServiceTypeExternalName { servers = append(servers, dynamic.TCPServer{ @@ -271,6 +284,25 @@ func (p *Provider) loadTCPServers(client Client, namespace string, svc v1alpha1. return servers, nil } +func (p *Provider) makeTCPServersTransportKey(parentNamespace string, serversTransportName string) (string, error) { + if serversTransportName == "" { + return "", nil + } + + if !p.AllowCrossNamespace && strings.HasSuffix(serversTransportName, providerNamespaceSeparator+providerName) { + // Since we are not able to know if another namespace is in the name (namespace-name@kubernetescrd), + // if the provider namespace kubernetescrd is used, + // we don't allow this format to avoid cross namespace references. + return "", fmt.Errorf("invalid reference to serversTransport %s: namespace-name@kubernetescrd format is not allowed when crossnamespace is disallowed", serversTransportName) + } + + if strings.Contains(serversTransportName, providerNamespaceSeparator) { + return serversTransportName, nil + } + + return provider.Normalize(makeID(parentNamespace, serversTransportName)), nil +} + // getTLSTCP mutates tlsConfigs. func getTLSTCP(ctx context.Context, ingressRoute *v1alpha1.IngressRouteTCP, k8sClient Client, tlsConfigs map[string]*tls.CertAndStores) error { if ingressRoute.Spec.TLS == nil { diff --git a/pkg/provider/kubernetes/crd/kubernetes_test.go b/pkg/provider/kubernetes/crd/kubernetes_test.go index 48e5844dbcb33d2962b53e62c0a4238c27162480..d09989ed74da9d195e8808b5b516b4f189ff9163 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_test.go +++ b/pkg/provider/kubernetes/crd/kubernetes_test.go @@ -12,13 +12,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/provider" - crdfake "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" - "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/provider" + crdfake "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s" + "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/intstr" @@ -46,9 +46,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -96,6 +97,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{}, }, @@ -149,6 +151,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{}, }, @@ -197,6 +200,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{}, }, @@ -250,6 +254,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{}, }, @@ -302,6 +307,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -343,6 +349,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -410,6 +417,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -493,6 +501,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -513,9 +522,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -535,9 +545,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -590,6 +601,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -633,6 +645,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -701,6 +714,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -768,6 +782,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -834,6 +849,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -889,6 +905,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -944,6 +961,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -985,6 +1003,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1024,10 +1043,10 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Address: "10.10.0.2:8000", }, }, - TerminationDelay: Int(500), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1075,6 +1094,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1116,6 +1136,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1154,6 +1175,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1173,6 +1195,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ + // The router that references the invalid service will be discarded. Routers: map[string]*dynamic.TCPRouter{ "default-test.route-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, @@ -1180,8 +1203,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Rule: "HostSNI(`foo.com`)", }, }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1265,6 +1289,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1355,6 +1380,109 @@ func TestLoadIngressRouteTCPs(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{}, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{}, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + }, + }, + { + desc: "TCP with ServersTransport", + paths: []string{"tcp/services.yml", "tcp/with_servers_transport.yml"}, + expected: &dynamic.Configuration{ + TLS: &dynamic.TLSConfiguration{}, + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + ServersTransports: map[string]*dynamic.TCPServersTransport{ + "foo-test": { + TLS: &dynamic.TLSClientConfig{ + ServerName: "test", + InsecureSkipVerify: true, + RootCAs: []tls.FileOrContent{"TESTROOTCAS0", "TESTROOTCAS1", "TESTROOTCAS2", "TESTROOTCAS3", "TESTROOTCAS5", "TESTALLCERTS"}, + Certificates: tls.Certificates{ + {CertFile: "TESTCERT1", KeyFile: "TESTKEY1"}, + {CertFile: "TESTCERT2", KeyFile: "TESTKEY2"}, + {CertFile: "TESTCERT3", KeyFile: "TESTKEY3"}, + }, + PeerCertURI: "foo://bar", + Spiffe: &dynamic.Spiffe{ + IDs: []string{ + "spiffe://foo/buz", + "spiffe://bar/biz", + }, + TrustDomain: "spiffe://lol", + }, + }, + DialTimeout: ptypes.Duration(42 * time.Second), + DialKeepAlive: ptypes.Duration(42 * time.Second), + TerminationDelay: ptypes.Duration(42 * time.Second), + }, + "default-test": { + TLS: &dynamic.TLSClientConfig{ + ServerName: "test", + }, + DialTimeout: ptypes.Duration(30 * time.Second), + DialKeepAlive: ptypes.Duration(15 * time.Second), + TerminationDelay: ptypes.Duration(100 * time.Millisecond), + }, + }, + Routers: map[string]*dynamic.TCPRouter{ + "default-test.route-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default-test.route-fdd3e9338e47a45efefc", + Rule: "HostSNI(`foo.com`)", + }, + }, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{ + "default-test.route-fdd3e9338e47a45efefc-whoamitcp-8000": { + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{ + { + Address: "10.10.0.1:8000", + }, + { + Address: "10.10.0.2:8000", + }, + }, + ServersTransport: "default-test", + }, + }, + "default-test.route-fdd3e9338e47a45efefc-whoamitcp2-8080": { + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{ + { + Address: "10.10.0.3:8080", + }, + { + Address: "10.10.0.4:8080", + }, + }, + ServersTransport: "default-default-test", + }, + }, + "default-test.route-fdd3e9338e47a45efefc": { + Weighted: &dynamic.TCPWeightedRoundRobin{ + Services: []dynamic.TCPWRRService{ + { + Name: "default-test.route-fdd3e9338e47a45efefc-whoamitcp-8000", + Weight: Int(1), + }, + { + Name: "default-test.route-fdd3e9338e47a45efefc-whoamitcp2-8080", + Weight: Int(1), + }, + }, + }, + }, + }, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1373,6 +1501,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ + // The router that references the invalid service will be discarded. Routers: map[string]*dynamic.TCPRouter{ "default-test.route-fdd3e9338e47a45efefc": { EntryPoints: []string{"foo"}, @@ -1380,8 +1509,9 @@ func TestLoadIngressRouteTCPs(t *testing.T) { Rule: "HostSNI(`foo.com`)", }, }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1415,6 +1545,7 @@ func TestLoadIngressRouteTCPs(t *testing.T) { LoadBalancer: &dynamic.TCPServersLoadBalancer{}, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1468,9 +1599,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1490,9 +1622,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1537,9 +1670,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1608,9 +1742,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1663,9 +1798,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1720,9 +1856,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1789,9 +1926,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1865,9 +2003,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1921,9 +2060,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1970,9 +2110,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2106,9 +2247,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2176,9 +2318,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2275,9 +2418,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2462,9 +2606,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2532,9 +2677,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2622,9 +2768,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2699,9 +2846,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2721,9 +2869,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2743,9 +2892,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2774,9 +2924,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2844,9 +2995,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2895,9 +3047,10 @@ func TestLoadIngressRoutes(t *testing.T) { Options: map[string]tls.Options{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2967,9 +3120,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3040,9 +3194,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3111,9 +3266,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3171,9 +3327,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3232,9 +3389,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3281,9 +3439,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3328,9 +3487,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3374,9 +3534,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3420,9 +3581,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3463,9 +3625,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3494,9 +3657,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3531,9 +3695,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3561,9 +3726,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3601,9 +3767,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3623,9 +3790,10 @@ func TestLoadIngressRoutes(t *testing.T) { }, TLS: &dynamic.TLSConfiguration{}, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3669,9 +3837,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3723,9 +3892,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3783,9 +3953,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3832,9 +4003,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3881,9 +4053,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3923,9 +4096,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3965,9 +4139,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -4007,9 +4182,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4029,9 +4205,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ ServersTransports: map[string]*dynamic.ServersTransport{ @@ -4139,9 +4316,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4162,9 +4340,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -4201,9 +4380,10 @@ func TestLoadIngressRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -4323,9 +4503,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4369,9 +4550,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { ServersTransports: map[string]*dynamic.ServersTransport{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{}, }, @@ -4419,9 +4601,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4485,9 +4668,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4567,9 +4751,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4604,9 +4789,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4641,9 +4827,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4659,6 +4846,7 @@ func TestLoadIngressRouteUDPs(t *testing.T) { paths: []string{"udp/services.yml", "udp/with_externalname_without_ports.yml"}, expected: &dynamic.Configuration{ UDP: &dynamic.UDPConfiguration{ + // The router that references the invalid service will be discarded. Routers: map[string]*dynamic.UDPRouter{ "default-test.route-0": { EntryPoints: []string{"foo"}, @@ -4668,9 +4856,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4691,9 +4880,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4709,6 +4899,7 @@ func TestLoadIngressRouteUDPs(t *testing.T) { paths: []string{"udp/services.yml", "udp/with_empty_services.yml"}, expected: &dynamic.Configuration{ UDP: &dynamic.UDPConfiguration{ + // The router that references the invalid service will be discarded. Routers: map[string]*dynamic.UDPRouter{ "default-test.route-0": { EntryPoints: []string{"foo"}, @@ -4718,9 +4909,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -4750,9 +4942,10 @@ func TestLoadIngressRouteUDPs(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -5105,9 +5298,10 @@ func TestCrossNamespace(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ ServersTransports: map[string]*dynamic.ServersTransport{}, @@ -5127,9 +5321,10 @@ func TestCrossNamespace(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -5181,9 +5376,10 @@ func TestCrossNamespace(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -5306,9 +5502,10 @@ func TestCrossNamespace(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -5458,9 +5655,10 @@ func TestCrossNamespace(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -5535,9 +5733,10 @@ func TestCrossNamespace(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -5593,9 +5792,10 @@ func TestCrossNamespace(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -5627,9 +5827,10 @@ func TestCrossNamespace(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -5684,9 +5885,10 @@ func TestCrossNamespace(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -5764,6 +5966,7 @@ func TestCrossNamespace(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -5836,6 +6039,7 @@ func TestCrossNamespace(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -5884,6 +6088,7 @@ func TestCrossNamespace(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{}, }, @@ -5905,8 +6110,97 @@ func TestCrossNamespace(t *testing.T) { Rule: "HostSNI(`foo.com`)", }, }, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{}, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{}, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "TCP ServersTransport cross namespace allowed", + paths: []string{"tcp/services.yml", "tcp/with_servers_transport_cross_namespace.yml"}, + allowCrossNamespace: true, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{ + "default-test.route-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default-test.route-fdd3e9338e47a45efefc", + Rule: "HostSNI(`foo.com`)", + Priority: 12, + }, + }, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{ + "default-test.route-fdd3e9338e47a45efefc": { + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{ + { + Address: "10.10.0.1:8000", + }, + { + Address: "10.10.0.2:8000", + }, + }, + ServersTransport: "cross-ns-st-cross-ns@kubernetescrd", + }, + }, + }, + ServersTransports: map[string]*dynamic.TCPServersTransport{ + "cross-ns-st-cross-ns": { + DialTimeout: ptypes.Duration(30 * time.Second), + DialKeepAlive: 0, + TerminationDelay: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{}, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{}, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "TCP ServersTransport cross namespace disallowed", + paths: []string{"tcp/services.yml", "tcp/with_servers_transport_cross_namespace.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + // The router that references the invalid service will be discarded. + Routers: map[string]*dynamic.TCPRouter{ + "default-test.route-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default-test.route-fdd3e9338e47a45efefc", + Rule: "HostSNI(`foo.com`)", + Priority: 12, + }, + }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{ + "cross-ns-st-cross-ns": { + DialTimeout: 30000000000, + DialKeepAlive: 0, + TerminationDelay: ptypes.Duration(100 * time.Millisecond), + }, + }, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -5958,6 +6252,7 @@ func TestCrossNamespace(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{ Options: map[string]tls.Options{ @@ -6001,6 +6296,7 @@ func TestCrossNamespace(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{ Options: map[string]tls.Options{ @@ -6046,9 +6342,10 @@ func TestCrossNamespace(t *testing.T) { ServersTransports: map[string]*dynamic.ServersTransport{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{}, }, @@ -6057,8 +6354,8 @@ func TestCrossNamespace(t *testing.T) { desc: "UDP cross namespace disallowed", paths: []string{"udp/services.yml", "udp/with_cross_namespace.yml"}, expected: &dynamic.Configuration{ - // The router that references the invalid service will be discarded. UDP: &dynamic.UDPConfiguration{ + // The router that references the invalid service will be discarded. Routers: map[string]*dynamic.UDPRouter{ "default-test.route-0": { EntryPoints: []string{"foo"}, @@ -6068,9 +6365,10 @@ func TestCrossNamespace(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -6120,6 +6418,8 @@ func TestCrossNamespace(t *testing.T) { crdObjects = append(crdObjects, o) case *v1alpha1.ServersTransport: crdObjects = append(crdObjects, o) + case *v1alpha1.ServersTransportTCP: + crdObjects = append(crdObjects, o) default: } } @@ -6164,9 +6464,10 @@ func TestExternalNameService(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ ServersTransports: map[string]*dynamic.ServersTransport{}, @@ -6187,9 +6488,10 @@ func TestExternalNameService(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ ServersTransports: map[string]*dynamic.ServersTransport{}, @@ -6230,9 +6532,10 @@ func TestExternalNameService(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ ServersTransports: map[string]*dynamic.ServersTransport{}, @@ -6279,6 +6582,7 @@ func TestExternalNameService(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{}, }, @@ -6300,8 +6604,9 @@ func TestExternalNameService(t *testing.T) { Rule: "HostSNI(`foo.com`)", }, }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ ServersTransports: map[string]*dynamic.ServersTransport{}, @@ -6344,9 +6649,10 @@ func TestExternalNameService(t *testing.T) { Services: map[string]*dynamic.Service{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{}, }, @@ -6355,8 +6661,8 @@ func TestExternalNameService(t *testing.T) { desc: "UDP ExternalName service disallowed", paths: []string{"udp/services.yml", "udp/with_externalname_service.yml"}, expected: &dynamic.Configuration{ - // The router that references the invalid service will be discarded. UDP: &dynamic.UDPConfiguration{ + // The router that references the invalid service will be discarded. Routers: map[string]*dynamic.UDPRouter{ "default-test.route-0": { EntryPoints: []string{"foo"}, @@ -6366,9 +6672,10 @@ func TestExternalNameService(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ ServersTransports: map[string]*dynamic.ServersTransport{}, @@ -6442,6 +6749,219 @@ func TestExternalNameService(t *testing.T) { } } +func TestNativeLB(t *testing.T) { + testCases := []struct { + desc string + ingressClass string + paths []string + expected *dynamic.Configuration + }{ + { + desc: "Empty", + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + ServersTransports: map[string]*dynamic.ServersTransport{}, + Routers: map[string]*dynamic.Router{}, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "HTTP with native Service LB", + paths: []string{"services.yml", "with_native_service_lb.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + ServersTransports: map[string]*dynamic.ServersTransport{}, + Routers: map[string]*dynamic.Router{ + "default-test-route-6f97418635c7e18853da": { + EntryPoints: []string{"foo"}, + Service: "default-test-route-6f97418635c7e18853da", + Rule: "Host(`foo.com`)", + Priority: 0, + }, + }, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{ + "default-test-route-6f97418635c7e18853da": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval}, + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:80", + }, + }, + PassHostHeader: Bool(true), + }, + }, + }, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "TCP with native Service LB", + paths: []string{"tcp/services.yml", "tcp/with_native_service_lb.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + ServersTransports: map[string]*dynamic.ServersTransport{}, + Routers: map[string]*dynamic.Router{}, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{}, + }, + TCP: &dynamic.TCPConfiguration{ + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + Routers: map[string]*dynamic.TCPRouter{ + "default-test.route-fdd3e9338e47a45efefc": { + EntryPoints: []string{"foo"}, + Service: "default-test.route-fdd3e9338e47a45efefc", + Rule: "HostSNI(`foo.com`)", + }, + }, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{ + "default-test.route-fdd3e9338e47a45efefc": { + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{ + { + Address: "10.10.0.1:8000", + Port: "", + }, + }, + }, + }, + }, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "UDP with native Service LB", + paths: []string{"udp/services.yml", "udp/with_native_service_lb.yml"}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{ + "default-test.route-0": { + EntryPoints: []string{"foo"}, + Service: "default-test.route-0", + }, + }, + Services: map[string]*dynamic.UDPService{ + "default-test.route-0": { + LoadBalancer: &dynamic.UDPServersLoadBalancer{ + Servers: []dynamic.UDPServer{ + { + Address: "10.10.0.1:8000", + Port: "", + }, + }, + }, + }, + }, + }, + HTTP: &dynamic.HTTPConfiguration{ + ServersTransports: map[string]*dynamic.ServersTransport{}, + Routers: map[string]*dynamic.Router{}, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{}, + }, + TCP: &dynamic.TCPConfiguration{ + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + } + + for _, test := range testCases { + test := test + + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + var k8sObjects []runtime.Object + var crdObjects []runtime.Object + for _, path := range test.paths { + yamlContent, err := os.ReadFile(filepath.FromSlash("./fixtures/" + path)) + if err != nil { + panic(err) + } + + objects := k8s.MustParseYaml(yamlContent) + for _, obj := range objects { + switch o := obj.(type) { + case *corev1.Service, *corev1.Endpoints, *corev1.Secret: + k8sObjects = append(k8sObjects, o) + case *v1alpha1.IngressRoute: + crdObjects = append(crdObjects, o) + case *v1alpha1.IngressRouteTCP: + crdObjects = append(crdObjects, o) + case *v1alpha1.IngressRouteUDP: + crdObjects = append(crdObjects, o) + case *v1alpha1.Middleware: + crdObjects = append(crdObjects, o) + case *v1alpha1.TraefikService: + crdObjects = append(crdObjects, o) + case *v1alpha1.TLSOption: + crdObjects = append(crdObjects, o) + case *v1alpha1.TLSStore: + crdObjects = append(crdObjects, o) + default: + } + } + } + + kubeClient := kubefake.NewSimpleClientset(k8sObjects...) + crdClient := crdfake.NewSimpleClientset(crdObjects...) + + client := newClientImpl(kubeClient, crdClient) + + stopCh := make(chan struct{}) + + eventCh, err := client.WatchAll([]string{"default", "cross-ns"}, stopCh) + require.NoError(t, err) + + if k8sObjects != nil || crdObjects != nil { + // just wait for the first event + <-eventCh + } + + p := Provider{} + + conf := p.loadConfigurationFromCRD(context.Background(), client) + assert.Equal(t, test.expected, conf) + }) + } +} + func TestCreateBasicAuthCredentials(t *testing.T) { var k8sObjects []runtime.Object var crdObjects []runtime.Object diff --git a/pkg/provider/kubernetes/crd/kubernetes_udp.go b/pkg/provider/kubernetes/crd/kubernetes_udp.go index 2589ebb0f02951d5507362e1c79d8f99c34ce11f..5d0d02bb9608ecad3bf81da676cf90755ef4d589 100644 --- a/pkg/provider/kubernetes/crd/kubernetes_udp.go +++ b/pkg/provider/kubernetes/crd/kubernetes_udp.go @@ -8,8 +8,8 @@ import ( "strconv" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" corev1 "k8s.io/api/core/v1" ) @@ -121,6 +121,15 @@ func (p *Provider) loadUDPServers(client Client, namespace string, svc v1alpha1. return nil, err } + if svc.NativeLB { + address, err := getNativeServiceAddress(*service, *svcPort) + if err != nil { + return nil, fmt.Errorf("getting native Kubernetes Service address: %w", err) + } + + return []dynamic.UDPServer{{Address: address}}, nil + } + var servers []dynamic.UDPServer if service.Spec.Type == corev1.ServiceTypeExternalName { servers = append(servers, dynamic.UDPServer{ diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/doc.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/doc.go similarity index 67% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/doc.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/doc.go index 71b5219b4821a913f8a8a8fe8f2fdf28d043fb4e..7004a17129bf15d7885796c5d3d357fe42374aa1 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/doc.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/doc.go @@ -1,5 +1,6 @@ // +k8s:deepcopy-gen=package // Package v1alpha1 is the v1alpha1 version of the API. -// +groupName=traefik.containo.us +// +groupName=traefik.io +// +groupGoName=Traefik package v1alpha1 diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go similarity index 95% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go index 93f57998c5826671c18516723d41f7842545e89c..6471381ae739ea728992f84bab405533b7e5d264 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroute.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroute.go @@ -1,8 +1,8 @@ package v1alpha1 import ( - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/types" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -115,10 +115,14 @@ type LoadBalancerSpec struct { // It allows to configure the transport between Traefik and your servers. // Can only be used on a Kubernetes Service. ServersTransport string `json:"serversTransport,omitempty"` - // Weight defines the weight and should only be specified when Name references a TraefikService object // (and to be precise, one that embeds a Weighted Round Robin). Weight *int `json:"weight,omitempty"` + // NativeLB controls, when creating the load-balancer, + // whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + // The Kubernetes Service itself does load-balance to the pods. + // By default, NativeLB is false. + NativeLB bool `json:"nativeLB,omitempty"` } type ResponseForwarding struct { diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroutetcp.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroutetcp.go similarity index 85% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroutetcp.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroutetcp.go index 4d89c7fdb131b5c26653423167653b7b6347c97b..5669e8f4f66e394512449d92660103529484248c 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressroutetcp.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressroutetcp.go @@ -1,8 +1,8 @@ package v1alpha1 import ( - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/types" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -69,15 +69,20 @@ type ServiceTCP struct { Port intstr.IntOrString `json:"port"` // Weight defines the weight used when balancing requests between multiple Kubernetes Service. Weight *int `json:"weight,omitempty"` - // TerminationDelay defines the deadline that the proxy sets, after one of its connected peers indicates - // it has closed the writing capability of its connection, to close the reading capability as well, - // hence fully terminating the connection. - // It is a duration in milliseconds, defaulting to 100. - // A negative value means an infinite deadline (i.e. the reading capability is never closed). - TerminationDelay *int `json:"terminationDelay,omitempty"` // ProxyProtocol defines the PROXY protocol configuration. // More info: https://doc.traefik.io/traefik/v3.0/routing/services/#proxy-protocol ProxyProtocol *dynamic.ProxyProtocol `json:"proxyProtocol,omitempty"` + // ServersTransport defines the name of ServersTransportTCP resource to use. + // It allows to configure the transport between Traefik and your servers. + // Can only be used on a Kubernetes Service. + ServersTransport string `json:"serversTransport,omitempty"` + // TLS determines whether to use TLS when dialing with the backend. + TLS bool `json:"tls,omitempty"` + // NativeLB controls, when creating the load-balancer, + // whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + // The Kubernetes Service itself does load-balance to the pods. + // By default, NativeLB is false. + NativeLB bool `json:"nativeLB,omitempty"` } // +genclient diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressrouteudp.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressrouteudp.go similarity index 87% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressrouteudp.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressrouteudp.go index 3744613465f32cc5972c2356c641c8e65def13ad..18773f43724b54ab8f593f17e8ddb1a1663b7422 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/ingressrouteudp.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/ingressrouteudp.go @@ -33,6 +33,11 @@ type ServiceUDP struct { Port intstr.IntOrString `json:"port"` // Weight defines the weight used when balancing requests between multiple Kubernetes Service. Weight *int `json:"weight,omitempty"` + // NativeLB controls, when creating the load-balancer, + // whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP. + // The Kubernetes Service itself does load-balance to the pods. + // By default, NativeLB is false. + NativeLB bool `json:"nativeLB,omitempty"` } // +genclient diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go similarity index 99% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go index c0d55d28fb273fa563809f59394ae50faa863926..51078f8560a51d61221775179099006b8b94a74a 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/middleware.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middleware.go @@ -1,7 +1,7 @@ package v1alpha1 import ( - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" apiextensionv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/middlewaretcp.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middlewaretcp.go similarity index 96% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/middlewaretcp.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/middlewaretcp.go index 655bf0e26fe1e6119e1398ea7b37049255e39ad2..10799f2953cd0525b5f641f21dbc669c7d81f811 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/middlewaretcp.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/middlewaretcp.go @@ -1,7 +1,7 @@ package v1alpha1 import ( - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/objectreference.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/objectreference.go similarity index 100% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/objectreference.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/objectreference.go diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/register.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/register.go similarity index 94% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/register.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/register.go index e87a2ff65d552bc13af76d8781b3f31154b3d3e4..e4c0d2c75c19a34636878dbdefc94a38b725d65c 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/register.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/register.go @@ -7,7 +7,7 @@ import ( ) // GroupName is the group name for Traefik. -const GroupName = "traefik.containo.us" +const GroupName = "traefik.io" var ( // SchemeBuilder collects the scheme builder functions. @@ -51,6 +51,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &TraefikServiceList{}, &ServersTransport{}, &ServersTransportList{}, + &ServersTransportTCP{}, + &ServersTransportTCPList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/serverstransport.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransport.go similarity index 98% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/serverstransport.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransport.go index 68a3438d2efef06c459b05db4781686c014c4db5..d8ae851decd6fee1e8432a381240db519f38aad4 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/serverstransport.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransport.go @@ -1,7 +1,7 @@ package v1alpha1 import ( - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" ) diff --git a/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransporttcp.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransporttcp.go new file mode 100644 index 0000000000000000000000000000000000000000..202dd39d9ab4dfd047d379d7842e28e6b32717bb --- /dev/null +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/serverstransporttcp.go @@ -0,0 +1,68 @@ +package v1alpha1 + +import ( + "github.com/traefik/traefik/v3/pkg/config/dynamic" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +kubebuilder:storageversion + +// ServersTransportTCP is the CRD implementation of a TCPServersTransport. +// If no tcpServersTransport is specified, a default one named default@internal will be used. +// The default@internal tcpServersTransport can be configured in the static configuration. +// More info: https://doc.traefik.io/traefik/v3.0/routing/services/#serverstransport_3 +type ServersTransportTCP struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ObjectMeta `json:"metadata"` + + Spec ServersTransportTCPSpec `json:"spec"` +} + +// +k8s:deepcopy-gen=true + +// ServersTransportTCPSpec defines the desired state of a ServersTransportTCP. +type ServersTransportTCPSpec struct { + // DialTimeout is the amount of time to wait until a connection to a backend server can be established. + DialTimeout *intstr.IntOrString `json:"dialTimeout,omitempty"` + // DialKeepAlive is the interval between keep-alive probes for an active network connection. If zero, keep-alive probes are sent with a default value (currently 15 seconds), if supported by the protocol and operating system. Network protocols or operating systems that do not support keep-alives ignore this field. If negative, keep-alive probes are disabled. + DialKeepAlive *intstr.IntOrString `json:"dialKeepAlive,omitempty"` + // TerminationDelay defines the delay to wait before fully terminating the connection, after one connected peer has closed its writing capability. + TerminationDelay *intstr.IntOrString `json:"terminationDelay,omitempty"` + // TLS defines the TLS configuration + TLS *TLSClientConfig `description:"Defines the TLS configuration." json:"tls,omitempty"` +} + +// TLSClientConfig defines the desired state of a TLSClientConfig. +type TLSClientConfig struct { + // ServerName defines the server name used to contact the server. + ServerName string `json:"serverName,omitempty"` + // InsecureSkipVerify disables TLS certificate verification. + InsecureSkipVerify bool `json:"insecureSkipVerify,omitempty"` + // RootCAsSecrets defines a list of CA secret used to validate self-signed certificates. + RootCAsSecrets []string `json:"rootCAsSecrets,omitempty"` + // CertificatesSecrets defines a list of secret storing client certificates for mTLS. + CertificatesSecrets []string `json:"certificatesSecrets,omitempty"` + // MaxIdleConnsPerHost controls the maximum idle (keep-alive) to keep per-host. + // PeerCertURI defines the peer cert URI used to match against SAN URI during the peer certificate verification. + PeerCertURI string `json:"peerCertURI,omitempty"` + // Spiffe defines the SPIFFE configuration. + Spiffe *dynamic.Spiffe `json:"spiffe,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ServersTransportTCPList is a collection of ServersTransportTCP resources. +type ServersTransportTCPList struct { + metav1.TypeMeta `json:",inline"` + // Standard object's metadata. + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata + metav1.ListMeta `json:"metadata"` + + // Items is the list of ServersTransportTCP. + Items []ServersTransportTCP `json:"items"` +} diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/service.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go similarity index 98% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/service.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go index 09fafb11be8ff4986dd49e7858bf5f7d5f4e3c29..2e93ced5ddbfa798d206e298674736133b8ae28a 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/service.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/service.go @@ -1,7 +1,7 @@ package v1alpha1 import ( - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go similarity index 100% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsoption.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsoption.go diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsstore.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsstore.go similarity index 98% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsstore.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsstore.go index 2af463df184621efc11ceec403deade246a81d03..2f7bff6221476872b23b9a26d4d975ef87cd42a7 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/tlsstore.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/tlsstore.go @@ -1,7 +1,7 @@ package v1alpha1 import ( - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/tls" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) diff --git a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go similarity index 92% rename from pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go rename to pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go index eaa5d450cb03b8acbc4a0dfbcc6bc39514d67cd9..e8f75cda624f9835f9e16363f68f8456ecdd0ee0 100644 --- a/pkg/provider/kubernetes/crd/traefik/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/provider/kubernetes/crd/traefikio/v1alpha1/zz_generated.deepcopy.go @@ -4,7 +4,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,9 +30,9 @@ THE SOFTWARE. package v1alpha1 import ( - dynamic "github.com/traefik/traefik/v2/pkg/config/dynamic" - tls "github.com/traefik/traefik/v2/pkg/tls" - types "github.com/traefik/traefik/v2/pkg/types" + dynamic "github.com/traefik/traefik/v3/pkg/config/dynamic" + tls "github.com/traefik/traefik/v3/pkg/tls" + types "github.com/traefik/traefik/v3/pkg/types" v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" runtime "k8s.io/apimachinery/pkg/runtime" intstr "k8s.io/apimachinery/pkg/util/intstr" @@ -1181,6 +1181,102 @@ func (in *ServersTransportSpec) DeepCopy() *ServersTransportSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServersTransportTCP) DeepCopyInto(out *ServersTransportTCP) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServersTransportTCP. +func (in *ServersTransportTCP) DeepCopy() *ServersTransportTCP { + if in == nil { + return nil + } + out := new(ServersTransportTCP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServersTransportTCP) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServersTransportTCPList) DeepCopyInto(out *ServersTransportTCPList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ServersTransportTCP, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServersTransportTCPList. +func (in *ServersTransportTCPList) DeepCopy() *ServersTransportTCPList { + if in == nil { + return nil + } + out := new(ServersTransportTCPList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServersTransportTCPList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServersTransportTCPSpec) DeepCopyInto(out *ServersTransportTCPSpec) { + *out = *in + if in.DialTimeout != nil { + in, out := &in.DialTimeout, &out.DialTimeout + *out = new(intstr.IntOrString) + **out = **in + } + if in.DialKeepAlive != nil { + in, out := &in.DialKeepAlive, &out.DialKeepAlive + *out = new(intstr.IntOrString) + **out = **in + } + if in.TerminationDelay != nil { + in, out := &in.TerminationDelay, &out.TerminationDelay + *out = new(intstr.IntOrString) + **out = **in + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(TLSClientConfig) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServersTransportTCPSpec. +func (in *ServersTransportTCPSpec) DeepCopy() *ServersTransportTCPSpec { + if in == nil { + return nil + } + out := new(ServersTransportTCPSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Service) DeepCopyInto(out *Service) { *out = *in @@ -1207,11 +1303,6 @@ func (in *ServiceTCP) DeepCopyInto(out *ServiceTCP) { *out = new(int) **out = **in } - if in.TerminationDelay != nil { - in, out := &in.TerminationDelay, &out.TerminationDelay - *out = new(int) - **out = **in - } if in.ProxyProtocol != nil { in, out := &in.ProxyProtocol, &out.ProxyProtocol *out = new(dynamic.ProxyProtocol) @@ -1285,6 +1376,37 @@ func (in *TLS) DeepCopy() *TLS { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TLSClientConfig) DeepCopyInto(out *TLSClientConfig) { + *out = *in + if in.RootCAsSecrets != nil { + in, out := &in.RootCAsSecrets, &out.RootCAsSecrets + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.CertificatesSecrets != nil { + in, out := &in.CertificatesSecrets, &out.CertificatesSecrets + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Spiffe != nil { + in, out := &in.Spiffe, &out.Spiffe + *out = new(dynamic.Spiffe) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSClientConfig. +func (in *TLSClientConfig) DeepCopy() *TLSClientConfig { + if in == nil { + return nil + } + out := new(TLSClientConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TLSOption) DeepCopyInto(out *TLSOption) { *out = *in diff --git a/pkg/provider/kubernetes/gateway/client_mock_test.go b/pkg/provider/kubernetes/gateway/client_mock_test.go index 010ce663558045026561a53dc63b3a74c19d4575..1003a777c9e93b8507c97f5b17b234acfe2e41db 100644 --- a/pkg/provider/kubernetes/gateway/client_mock_test.go +++ b/pkg/provider/kubernetes/gateway/client_mock_test.go @@ -5,7 +5,7 @@ import ( "os" "path/filepath" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" diff --git a/pkg/provider/kubernetes/gateway/fixtures/httproute/filter_http_to_https.yml b/pkg/provider/kubernetes/gateway/fixtures/httproute/filter_http_to_https.yml new file mode 100644 index 0000000000000000000000000000000000000000..5b8d1607dcccf31048a33549dd4ad0c5ad70d9e7 --- /dev/null +++ b/pkg/provider/kubernetes/gateway/fixtures/httproute/filter_http_to_https.yml @@ -0,0 +1,52 @@ +--- +kind: GatewayClass +apiVersion: gateway.networking.k8s.io/v1alpha2 +metadata: + name: my-gateway-class +spec: + controllerName: traefik.io/gateway-controller + +--- +kind: Gateway +apiVersion: gateway.networking.k8s.io/v1alpha2 +metadata: + name: my-gateway + namespace: default +spec: + gatewayClassName: my-gateway-class + listeners: # Use GatewayClass defaults for listener definition. + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + kinds: + - kind: HTTPRoute + group: gateway.networking.k8s.io + namespaces: + from: Same + +--- +kind: HTTPRoute +apiVersion: gateway.networking.k8s.io/v1alpha2 +metadata: + name: http-app-1 + namespace: default +spec: + parentRefs: + - name: my-gateway + kind: Gateway + group: gateway.networking.k8s.io + hostnames: + - "example.org" + rules: + - backendRefs: + - name: whoami + port: 80 + weight: 1 + kind: Service + group: "" + filters: + - type: RequestRedirect + requestRedirect: + scheme: https + statusCode: 301 diff --git a/pkg/provider/kubernetes/gateway/fixtures/httproute/filter_http_to_https_with_hostname_and_port.yml b/pkg/provider/kubernetes/gateway/fixtures/httproute/filter_http_to_https_with_hostname_and_port.yml new file mode 100644 index 0000000000000000000000000000000000000000..79e875be1cc96ccb241c328c83e3ae5201c4b5fb --- /dev/null +++ b/pkg/provider/kubernetes/gateway/fixtures/httproute/filter_http_to_https_with_hostname_and_port.yml @@ -0,0 +1,52 @@ +--- +kind: GatewayClass +apiVersion: gateway.networking.k8s.io/v1alpha2 +metadata: + name: my-gateway-class +spec: + controllerName: traefik.io/gateway-controller + +--- +kind: Gateway +apiVersion: gateway.networking.k8s.io/v1alpha2 +metadata: + name: my-gateway + namespace: default +spec: + gatewayClassName: my-gateway-class + listeners: # Use GatewayClass defaults for listener definition. + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + kinds: + - kind: HTTPRoute + group: gateway.networking.k8s.io + namespaces: + from: Same + +--- +kind: HTTPRoute +apiVersion: gateway.networking.k8s.io/v1alpha2 +metadata: + name: http-app-1 + namespace: default +spec: + parentRefs: + - name: my-gateway + kind: Gateway + group: gateway.networking.k8s.io + hostnames: + - "example.org" + rules: + - backendRefs: + - name: whoami + port: 80 + weight: 1 + kind: Service + group: "" + filters: + - type: RequestRedirect + requestRedirect: + hostname: example.com + port: 443 diff --git a/pkg/provider/kubernetes/gateway/fixtures/httproute/simple_cross_provider.yml b/pkg/provider/kubernetes/gateway/fixtures/httproute/simple_cross_provider.yml index 3010f3a59f3b4a2d7028d8e66c1f6e16de56cc4a..ff90c82d0d8f2e2c7179b2dfa967c25081cebb00 100644 --- a/pkg/provider/kubernetes/gateway/fixtures/httproute/simple_cross_provider.yml +++ b/pkg/provider/kubernetes/gateway/fixtures/httproute/simple_cross_provider.yml @@ -42,7 +42,7 @@ spec: value: /bar backendRefs: - weight: 1 - group: traefik.containo.us + group: traefik.io kind: TraefikService name: service@file port: 80 diff --git a/pkg/provider/kubernetes/gateway/fixtures/httproute/simple_to_api_internal.yml b/pkg/provider/kubernetes/gateway/fixtures/httproute/simple_to_api_internal.yml index 6fe6d48b6abdfa3fa38fb487c35b6a67b86b3aa6..6426736f6065508bb8a0191eee81b26328f5663e 100644 --- a/pkg/provider/kubernetes/gateway/fixtures/httproute/simple_to_api_internal.yml +++ b/pkg/provider/kubernetes/gateway/fixtures/httproute/simple_to_api_internal.yml @@ -42,7 +42,7 @@ spec: value: /bar backendRefs: - weight: 1 - group: traefik.containo.us + group: traefik.io kind: TraefikService name: api@internal port: 80 diff --git a/pkg/provider/kubernetes/gateway/fixtures/tcproute/simple_cross_provider.yml b/pkg/provider/kubernetes/gateway/fixtures/tcproute/simple_cross_provider.yml index a712ca7396321c3f7c9614ea8bd3bdcd10fc5bcd..be491cf7924ea04ee0fc9b72f5c2e55974e24988 100644 --- a/pkg/provider/kubernetes/gateway/fixtures/tcproute/simple_cross_provider.yml +++ b/pkg/provider/kubernetes/gateway/fixtures/tcproute/simple_cross_provider.yml @@ -39,7 +39,7 @@ spec: rules: - backendRefs: - weight: 1 - group: traefik.containo.us + group: traefik.io kind: TraefikService name: service@file port: 9000 diff --git a/pkg/provider/kubernetes/gateway/fixtures/tlsroute/simple_cross_provider.yml b/pkg/provider/kubernetes/gateway/fixtures/tlsroute/simple_cross_provider.yml index d530c3d0e6efd032341df9405d8f23b98699d43a..4d687b5dea4521f40084cce9ca9ab061fc8aa2b8 100644 --- a/pkg/provider/kubernetes/gateway/fixtures/tlsroute/simple_cross_provider.yml +++ b/pkg/provider/kubernetes/gateway/fixtures/tlsroute/simple_cross_provider.yml @@ -55,7 +55,7 @@ spec: rules: - backendRefs: - weight: 1 - group: traefik.containo.us + group: traefik.io kind: TraefikService name: service@file port: 9000 diff --git a/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_invalid_SNI_matching.yml b/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_invalid_SNI_matching.yml index 004e1a4b9e605c45d04d0cd665d951a560f41a6c..512e39770b24fa2560bd1738eefa5b39cc79d5e7 100644 --- a/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_invalid_SNI_matching.yml +++ b/pkg/provider/kubernetes/gateway/fixtures/tlsroute/with_invalid_SNI_matching.yml @@ -39,7 +39,7 @@ spec: kind: Gateway group: gateway.networking.k8s.io hostnames: - - "*.foo.bar" + - "*.foo.*.bar" rules: - backendRefs: - name: whoamitcp diff --git a/pkg/provider/kubernetes/gateway/kubernetes.go b/pkg/provider/kubernetes/gateway/kubernetes.go index 3f62e98a2c529e72537354763e2ff69131a5b329..170540394238be4896b6fe41b21a31ab2a72d905 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes.go +++ b/pkg/provider/kubernetes/gateway/kubernetes.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "net" + "net/http" "os" "regexp" "sort" @@ -18,13 +19,13 @@ import ( "github.com/mitchellh/hashstructure" "github.com/rs/zerolog/log" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - traefikv1alpha1 "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefik/v1alpha1" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/job" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + traefikv1alpha1 "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd/traefikio/v1alpha1" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/tls" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -183,18 +184,21 @@ func (p *Provider) loadConfigurationFromGateway(ctx context.Context, client Clie if err != nil { logger.Error().Err(err).Msg("Cannot find GatewayClasses") return &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{}, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{}, + ServersTransports: map[string]*dynamic.ServersTransport{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, }, TLS: &dynamic.TLSConfiguration{}, } @@ -270,18 +274,21 @@ func (p *Provider) loadConfigurationFromGateway(ctx context.Context, client Clie func (p *Provider) createGatewayConf(ctx context.Context, client Client, gateway *v1alpha2.Gateway) (*dynamic.Configuration, error) { conf := &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{}, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{}, + ServersTransports: map[string]*dynamic.ServersTransport{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, }, TLS: &dynamic.TLSConfiguration{}, } @@ -750,6 +757,26 @@ func gatewayHTTPRouteToHTTPConf(ctx context.Context, ep string, listener v1alpha continue } + middlewares, err := loadMiddlewares(listener, routerKey, routeRule.Filters) + if err != nil { + // update "ResolvedRefs" status true with "InvalidFilters" reason + conditions = append(conditions, metav1.Condition{ + Type: string(v1alpha2.ListenerConditionResolvedRefs), + Status: metav1.ConditionFalse, + LastTransitionTime: metav1.Now(), + Reason: "InvalidFilters", // TODO check the spec if a proper reason is introduced at some point + Message: fmt.Sprintf("Cannot load HTTPRoute filter %s/%s: %v", route.Namespace, route.Name, err), + }) + + // TODO update the RouteStatus condition / deduplicate conditions on listener + continue + } + + for middlewareName, middleware := range middlewares { + conf.HTTP.Middlewares[middlewareName] = middleware + router.Middlewares = append(router.Middlewares, middlewareName) + } + if len(routeRule.BackendRefs) == 0 { continue } @@ -833,7 +860,7 @@ func gatewayTCPRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. } router := dynamic.TCPRouter{ - Rule: "HostSNI(`*`)", // Gateway listener hostname not available in TCP + Rule: "HostSNI(`*`)", EntryPoints: []string{ep}, } @@ -964,8 +991,16 @@ func gatewayTLSRouteToTCPConf(ctx context.Context, ep string, listener v1alpha2. hostnames := matchingHostnames(listener, route.Spec.Hostnames) if len(hostnames) == 0 && listener.Hostname != nil && *listener.Hostname != "" && len(route.Spec.Hostnames) > 0 { - // TODO update the corresponding route parent status - // https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.TLSRoute + for _, parent := range route.Status.Parents { + parent.Conditions = append(parent.Conditions, metav1.Condition{ + Type: string(v1alpha2.GatewayClassConditionStatusAccepted), + Status: metav1.ConditionFalse, + Reason: string(v1alpha2.ListenerReasonRouteConflict), + Message: fmt.Sprintf("No hostname match between listener: %v and route: %v", listener.Hostname, route.Spec.Hostnames), + LastTransitionTime: metav1.Now(), + }) + } + continue } @@ -1201,7 +1236,7 @@ func hostRule(hostnames []v1alpha2.Hostname) (string, error) { } func hostSNIRule(hostnames []v1alpha2.Hostname) (string, error) { - var matchers []string + rules := make([]string, 0, len(hostnames)) uniqHostnames := map[v1alpha2.Hostname]struct{}{} for _, hostname := range hostnames { @@ -1213,25 +1248,28 @@ func hostSNIRule(hostnames []v1alpha2.Hostname) (string, error) { continue } - h := string(hostname) + host := string(hostname) + uniqHostnames[hostname] = struct{}{} - // TODO support wildcard hostnames with an HostSNI regexp matcher - if strings.Contains(h, "*") { - return "", fmt.Errorf("wildcard hostname is not supported: %q", h) + wildcard := strings.Count(host, "*") + if wildcard == 0 { + rules = append(rules, fmt.Sprintf("HostSNI(`%s`)", host)) + continue } - matchers = append(matchers, fmt.Sprintf("HostSNI(`%s`)", h)) - uniqHostnames[hostname] = struct{}{} + if !strings.HasPrefix(host, "*.") || wildcard > 1 { + return "", fmt.Errorf("invalid rule: %q", host) + } + + host = strings.Replace(regexp.QuoteMeta(host), `\*\.`, `[a-zA-Z0-9-]+\.`, 1) + rules = append(rules, fmt.Sprintf("HostSNIRegexp(`^%s$`)", host)) } - switch len(matchers) { - case 0: + if len(hostnames) == 0 || len(rules) == 0 { return "HostSNI(`*`)", nil - case 1: - return matchers[0], nil - default: - return fmt.Sprintf("(%s)", strings.Join(matchers, " || ")), nil } + + return strings.Join(rules, " || "), nil } func extractRule(routeRule v1alpha2.HTTPRouteRule, hostRule string) (string, error) { @@ -1426,7 +1464,7 @@ func loadServices(client Client, namespace string, backendRefs []v1alpha2.HTTPBa weight := int(pointer.Int32Deref(backendRef.Weight, 1)) - if *backendRef.Group == traefikv1alpha1.GroupName && *backendRef.Kind == kindTraefikService { + if isTraefikService(backendRef.BackendRef) { wrrSvc.Weighted.Services = append(wrrSvc.Weighted.Services, dynamic.WRRService{Name: string(backendRef.Name), Weight: &weight}) continue } @@ -1549,7 +1587,7 @@ func loadTCPServices(client Client, namespace string, backendRefs []v1alpha2.Bac weight := int(pointer.Int32Deref(backendRef.Weight, 1)) - if *backendRef.Group == traefikv1alpha1.GroupName && *backendRef.Kind == kindTraefikService { + if isTraefikService(backendRef) { wrrSvc.Weighted.Services = append(wrrSvc.Weighted.Services, dynamic.TCPWRRService{Name: string(backendRef.Name), Weight: &weight}) continue } @@ -1646,6 +1684,85 @@ func loadTCPServices(client Client, namespace string, backendRefs []v1alpha2.Bac return wrrSvc, services, nil } +func loadMiddlewares(listener v1alpha2.Listener, prefix string, filters []v1alpha2.HTTPRouteFilter) (map[string]*dynamic.Middleware, error) { + middlewares := make(map[string]*dynamic.Middleware) + + // The spec allows for an empty string in which case we should use the + // scheme of the request which in this case is the listener scheme. + var listenerScheme string + switch listener.Protocol { + case v1alpha2.HTTPProtocolType: + listenerScheme = "http" + case v1alpha2.HTTPSProtocolType: + listenerScheme = "https" + default: + return nil, fmt.Errorf("invalid listener protocol %s", listener.Protocol) + } + + for i, filter := range filters { + var middleware *dynamic.Middleware + switch filter.Type { + case v1alpha2.HTTPRouteFilterRequestRedirect: + var err error + middleware, err = createRedirectRegexMiddleware(listenerScheme, filter.RequestRedirect) + if err != nil { + return nil, fmt.Errorf("creating RedirectRegex middleware: %w", err) + } + default: + // As per the spec: + // https://gateway-api.sigs.k8s.io/api-types/httproute/#filters-optional + // In all cases where incompatible or unsupported filters are + // specified, implementations MUST add a warning condition to + // status. + return nil, fmt.Errorf("unsupported filter %s", filter.Type) + } + + middlewareName := provider.Normalize(fmt.Sprintf("%s-%s-%d", prefix, strings.ToLower(string(filter.Type)), i)) + middlewares[middlewareName] = middleware + } + + return middlewares, nil +} + +func createRedirectRegexMiddleware(scheme string, filter *v1alpha2.HTTPRequestRedirectFilter) (*dynamic.Middleware, error) { + // Use the HTTPRequestRedirectFilter scheme if defined. + filterScheme := scheme + if filter.Scheme != nil { + filterScheme = *filter.Scheme + } + + if filterScheme != "http" && filterScheme != "https" { + return nil, fmt.Errorf("invalid scheme %s", filterScheme) + } + + statusCode := http.StatusFound + if filter.StatusCode != nil { + statusCode = *filter.StatusCode + } + + if statusCode != http.StatusMovedPermanently && statusCode != http.StatusFound { + return nil, fmt.Errorf("invalid status code %d", statusCode) + } + + port := "${port}" + if filter.Port != nil { + port = fmt.Sprintf(":%d", *filter.Port) + } + + hostname := "${hostname}" + if filter.Hostname != nil && *filter.Hostname != "" { + hostname = string(*filter.Hostname) + } + + return &dynamic.Middleware{ + RedirectRegex: &dynamic.RedirectRegex{ + Regex: `^[a-z]+:\/\/(?P<userInfo>.+@)?(?P<hostname>\[[\w:\.]+\]|[\w\._-]+)(?P<port>:\d+)?\/(?P<path>.*)`, + Replacement: fmt.Sprintf("%s://${userinfo}%s%s/${path}", filterScheme, hostname, port), + Permanent: statusCode == http.StatusMovedPermanently, + }, + }, nil +} + func getProtocol(portSpec corev1.ServicePort) string { protocol := "http" if portSpec.Port == 443 || strings.HasPrefix(portSpec.Name, "https") { @@ -1685,14 +1802,16 @@ func throttleEvents(ctx context.Context, throttleDuration time.Duration, pool *s return eventsChanBuffered } -func isInternalService(ref v1alpha2.BackendRef) bool { +func isTraefikService(ref v1alpha2.BackendRef) bool { if ref.Kind == nil || ref.Group == nil { return false } - return *ref.Kind == kindTraefikService && - *ref.Group == traefikv1alpha1.GroupName && - strings.HasSuffix(string(ref.Name), "@internal") + return *ref.Group == traefikv1alpha1.GroupName && *ref.Kind == kindTraefikService +} + +func isInternalService(ref v1alpha2.BackendRef) bool { + return isTraefikService(ref) && strings.HasSuffix(string(ref.Name), "@internal") } // makeListenerKey joins protocol, hostname, and port of a listener into a string key. diff --git a/pkg/provider/kubernetes/gateway/kubernetes_test.go b/pkg/provider/kubernetes/gateway/kubernetes_test.go index 44b3ce24927573733a85b0bc8be8bc3f054884ae..f7e2acafe9258bb29b26bad188dbb9df5c2a27a7 100644 --- a/pkg/provider/kubernetes/gateway/kubernetes_test.go +++ b/pkg/provider/kubernetes/gateway/kubernetes_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/tls" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" "sigs.k8s.io/gateway-api/apis/v1alpha2" @@ -34,9 +34,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -59,9 +60,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -84,9 +86,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -109,9 +112,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -134,9 +138,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -159,9 +164,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -184,9 +190,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -209,9 +216,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -234,9 +242,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -259,9 +268,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -284,9 +294,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -309,9 +320,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -334,9 +346,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -359,9 +372,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -384,9 +398,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -410,9 +425,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -435,9 +451,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -460,9 +477,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -494,9 +512,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -519,9 +538,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -577,9 +597,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -608,9 +629,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -670,9 +692,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -738,9 +761,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -796,9 +820,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -854,9 +879,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -912,9 +938,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1001,9 +1028,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1084,9 +1112,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1172,9 +1201,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1255,9 +1285,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1328,9 +1359,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1386,9 +1418,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1475,9 +1508,10 @@ func TestLoadHTTPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -1521,6 +1555,141 @@ func TestLoadHTTPRoutes(t *testing.T) { TLS: &dynamic.TLSConfiguration{}, }, }, + { + desc: "Simple HTTPRoute, redirect HTTP to HTTPS", + paths: []string{"services.yml", "httproute/filter_http_to_https.yml"}, + entryPoints: map[string]Entrypoint{"web": { + Address: ":80", + }}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4": { + EntryPoints: []string{"web"}, + Service: "default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-wrr", + Rule: "Host(`example.org`) && PathPrefix(`/`)", + Middlewares: []string{"default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-requestredirect-0"}, + }, + }, + Middlewares: map[string]*dynamic.Middleware{ + "default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-requestredirect-0": { + RedirectRegex: &dynamic.RedirectRegex{ + Regex: "^[a-z]+:\\/\\/(?P<userInfo>.+@)?(?P<hostname>\\[[\\w:\\.]+\\]|[\\w\\._-]+)(?P<port>:\\d+)?\\/(?P<path>.*)", + Replacement: "https://${userinfo}${hostname}${port}/${path}", + Permanent: true, + }, + }, + }, + Services: map[string]*dynamic.Service{ + "default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-wrr": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "default-whoami-80", + Weight: func(i int) *int { return &i }(1), + }, + }, + }, + }, + "default-whoami-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:80", + }, + { + URL: "http://10.10.0.2:80", + }, + }, + PassHostHeader: pointer.Bool(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, + { + desc: "Simple HTTPRoute, redirect HTTP to HTTPS with hostname", + paths: []string{"services.yml", "httproute/filter_http_to_https_with_hostname_and_port.yml"}, + entryPoints: map[string]Entrypoint{"web": { + Address: ":80", + }}, + expected: &dynamic.Configuration{ + UDP: &dynamic.UDPConfiguration{ + Routers: map[string]*dynamic.UDPRouter{}, + Services: map[string]*dynamic.UDPService{}, + }, + TCP: &dynamic.TCPConfiguration{ + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, + }, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{ + "default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4": { + EntryPoints: []string{"web"}, + Service: "default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-wrr", + Rule: "Host(`example.org`) && PathPrefix(`/`)", + Middlewares: []string{"default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-requestredirect-0"}, + }, + }, + Middlewares: map[string]*dynamic.Middleware{ + "default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-requestredirect-0": { + RedirectRegex: &dynamic.RedirectRegex{ + Regex: "^[a-z]+:\\/\\/(?P<userInfo>.+@)?(?P<hostname>\\[[\\w:\\.]+\\]|[\\w\\._-]+)(?P<port>:\\d+)?\\/(?P<path>.*)", + Replacement: "http://${userinfo}example.com:443/${path}", + }, + }, + }, + Services: map[string]*dynamic.Service{ + "default-http-app-1-my-gateway-web-364ce6ec04c3d49b19c4-wrr": { + Weighted: &dynamic.WeightedRoundRobin{ + Services: []dynamic.WRRService{ + { + Name: "default-whoami-80", + Weight: func(i int) *int { return &i }(1), + }, + }, + }, + }, + "default-whoami-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:80", + }, + { + URL: "http://10.10.0.2:80", + }, + }, + PassHostHeader: pointer.Bool(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + }, + }, + }, + ServersTransports: map[string]*dynamic.ServersTransport{}, + }, + TLS: &dynamic.TLSConfiguration{}, + }, + }, } for _, test := range testCases { @@ -1555,9 +1724,10 @@ func TestLoadTCPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1580,9 +1750,10 @@ func TestLoadTCPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1605,9 +1776,10 @@ func TestLoadTCPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1630,9 +1802,10 @@ func TestLoadTCPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1655,9 +1828,10 @@ func TestLoadTCPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1680,9 +1854,10 @@ func TestLoadTCPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1705,9 +1880,10 @@ func TestLoadTCPRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1762,6 +1938,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1845,6 +2022,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1937,6 +2115,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1995,6 +2174,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2048,6 +2228,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2111,6 +2292,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2192,6 +2374,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2246,6 +2429,7 @@ func TestLoadTCPRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2290,9 +2474,10 @@ func TestLoadTLSRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2315,9 +2500,10 @@ func TestLoadTLSRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2340,9 +2526,10 @@ func TestLoadTLSRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2365,9 +2552,10 @@ func TestLoadTLSRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2390,9 +2578,10 @@ func TestLoadTLSRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2415,9 +2604,10 @@ func TestLoadTLSRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2448,9 +2638,10 @@ func TestLoadTLSRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2473,9 +2664,10 @@ func TestLoadTLSRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2531,6 +2723,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2597,6 +2790,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2654,6 +2848,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2740,6 +2935,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2808,6 +3004,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2874,6 +3071,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2931,6 +3129,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2988,6 +3187,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3011,10 +3211,10 @@ func TestLoadTLSRoutes(t *testing.T) { }, TCP: &dynamic.TCPConfiguration{ Routers: map[string]*dynamic.TCPRouter{ - "default-tls-app-1-my-gateway-tls-dfc5c7506ac1b172c8b7": { + "default-tls-app-1-my-gateway-tls-d5342d75658583f03593": { EntryPoints: []string{"tls"}, - Service: "default-tls-app-1-my-gateway-tls-dfc5c7506ac1b172c8b7-wrr-0", - Rule: "(HostSNI(`foo.example.com`) || HostSNI(`bar.example.com`))", + Service: "default-tls-app-1-my-gateway-tls-d5342d75658583f03593-wrr-0", + Rule: "HostSNI(`foo.example.com`) || HostSNI(`bar.example.com`)", TLS: &dynamic.RouterTCPTLSConfig{ Passthrough: true, }, @@ -3022,7 +3222,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, Middlewares: map[string]*dynamic.TCPMiddleware{}, Services: map[string]*dynamic.TCPService{ - "default-tls-app-1-my-gateway-tls-dfc5c7506ac1b172c8b7-wrr-0": { + "default-tls-app-1-my-gateway-tls-d5342d75658583f03593-wrr-0": { Weighted: &dynamic.TCPWeightedRoundRobin{ Services: []dynamic.TCPWRRService{ { @@ -3045,6 +3245,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3102,6 +3303,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3189,6 +3391,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3246,6 +3449,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3339,6 +3543,7 @@ func TestLoadTLSRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3383,9 +3588,10 @@ func TestLoadMixedRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3408,9 +3614,10 @@ func TestLoadMixedRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3433,9 +3640,10 @@ func TestLoadMixedRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3458,9 +3666,10 @@ func TestLoadMixedRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3553,6 +3762,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3635,9 +3845,10 @@ func TestLoadMixedRoutes(t *testing.T) { Services: map[string]*dynamic.UDPService{}, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -3730,6 +3941,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -3923,6 +4135,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -4120,6 +4333,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -4251,6 +4465,7 @@ func TestLoadMixedRoutes(t *testing.T) { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -4700,6 +4915,11 @@ func Test_hostSNIRule(t *testing.T) { hostnames: []v1alpha2.Hostname{"*"}, expectError: true, }, + { + desc: "Supported wildcard", + hostnames: []v1alpha2.Hostname{"*.foo"}, + expectedRule: "HostSNIRegexp(`^[a-zA-Z0-9-]+\\.foo$`)", + }, { desc: "Multiple malformed wildcard", hostnames: []v1alpha2.Hostname{"*.foo.*"}, @@ -4708,7 +4928,7 @@ func Test_hostSNIRule(t *testing.T) { { desc: "Some empty hostnames", hostnames: []v1alpha2.Hostname{"foo", "", "bar"}, - expectedRule: "(HostSNI(`foo`) || HostSNI(`bar`))", + expectedRule: "HostSNI(`foo`) || HostSNI(`bar`)", }, { desc: "Valid hostname", @@ -4718,12 +4938,17 @@ func Test_hostSNIRule(t *testing.T) { { desc: "Multiple valid hostnames", hostnames: []v1alpha2.Hostname{"foo", "bar"}, - expectedRule: "(HostSNI(`foo`) || HostSNI(`bar`))", + expectedRule: "HostSNI(`foo`) || HostSNI(`bar`)", + }, + { + desc: "Multiple valid hostnames with wildcard", + hostnames: []v1alpha2.Hostname{"bar.foo", "foo.foo", "*.foo"}, + expectedRule: "HostSNI(`bar.foo`) || HostSNI(`foo.foo`) || HostSNIRegexp(`^[a-zA-Z0-9-]+\\.foo$`)", }, { desc: "Multiple overlapping hostnames", hostnames: []v1alpha2.Hostname{"foo", "bar", "foo", "baz"}, - expectedRule: "(HostSNI(`foo`) || HostSNI(`bar`) || HostSNI(`baz`))", + expectedRule: "HostSNI(`foo`) || HostSNI(`bar`) || HostSNI(`baz`)", }, } diff --git a/pkg/provider/kubernetes/ingress/annotations.go b/pkg/provider/kubernetes/ingress/annotations.go index 25807cdd250ad1dc73d732bf2a20cf6838783204..134b2eda2d36f8e60cb54c576b82d662bf76b8db 100644 --- a/pkg/provider/kubernetes/ingress/annotations.go +++ b/pkg/provider/kubernetes/ingress/annotations.go @@ -4,8 +4,8 @@ import ( "regexp" "strings" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/label" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/label" ) const ( @@ -45,6 +45,7 @@ type ServiceIng struct { ServersTransport string `json:"serversTransport,omitempty"` PassHostHeader *bool `json:"passHostHeader"` Sticky *dynamic.Sticky `json:"sticky,omitempty" label:"allowEmpty"` + NativeLB bool `json:"nativeLB,omitempty"` } // SetDefaults sets the default values. diff --git a/pkg/provider/kubernetes/ingress/annotations_test.go b/pkg/provider/kubernetes/ingress/annotations_test.go index 075e76f902ea67f4eb4d9fa1d5d9d1f559f8a562..ee77647f3ace6b737612412584e750df860c6f95 100644 --- a/pkg/provider/kubernetes/ingress/annotations_test.go +++ b/pkg/provider/kubernetes/ingress/annotations_test.go @@ -5,8 +5,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/types" ) func Test_parseRouterConfig(t *testing.T) { @@ -106,6 +106,7 @@ func Test_parseServiceConfig(t *testing.T) { "traefik.ingress.kubernetes.io/service.serversscheme": "protocol", "traefik.ingress.kubernetes.io/service.serverstransport": "foobar@file", "traefik.ingress.kubernetes.io/service.passhostheader": "true", + "traefik.ingress.kubernetes.io/service.nativelb": "true", "traefik.ingress.kubernetes.io/service.sticky.cookie": "true", "traefik.ingress.kubernetes.io/service.sticky.cookie.httponly": "true", "traefik.ingress.kubernetes.io/service.sticky.cookie.name": "foobar", @@ -125,6 +126,7 @@ func Test_parseServiceConfig(t *testing.T) { ServersScheme: "protocol", ServersTransport: "foobar@file", PassHostHeader: Bool(true), + NativeLB: true, }, }, }, diff --git a/pkg/provider/kubernetes/ingress/client.go b/pkg/provider/kubernetes/ingress/client.go index eccd396571a9b331ed25b6d327e5ff61d58f86ca..11854c12b234ef00ea1b4abcfc7b5d0d2efd1f3b 100644 --- a/pkg/provider/kubernetes/ingress/client.go +++ b/pkg/provider/kubernetes/ingress/client.go @@ -11,8 +11,8 @@ import ( "github.com/hashicorp/go-version" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" - traefikversion "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s" + traefikversion "github.com/traefik/traefik/v3/pkg/version" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" networkingv1beta1 "k8s.io/api/networking/v1beta1" @@ -50,15 +50,16 @@ type Client interface { } type clientWrapper struct { - clientset kubernetes.Interface - factoriesKube map[string]informers.SharedInformerFactory - factoriesSecret map[string]informers.SharedInformerFactory - factoriesIngress map[string]informers.SharedInformerFactory - clusterFactory informers.SharedInformerFactory - ingressLabelSelector string - isNamespaceAll bool - watchedNamespaces []string - serverVersion *version.Version + clientset kubernetes.Interface + factoriesKube map[string]informers.SharedInformerFactory + factoriesSecret map[string]informers.SharedInformerFactory + factoriesIngress map[string]informers.SharedInformerFactory + clusterFactory informers.SharedInformerFactory + ingressLabelSelector string + isNamespaceAll bool + disableIngressClassInformer bool + watchedNamespaces []string + serverVersion *version.Version } // newInClusterClient returns a new Provider client that is expected to run @@ -214,7 +215,7 @@ func (c *clientWrapper) WatchAll(namespaces []string, stopCh <-chan struct{}) (< } } - if supportsIngressClass(serverVersion) { + if !c.disableIngressClassInformer && supportsIngressClass(serverVersion) { c.clusterFactory = informers.NewSharedInformerFactoryWithOptions(c.clientset, resyncPeriod) if supportsNetworkingV1Ingress(serverVersion) { diff --git a/pkg/provider/kubernetes/ingress/client_mock_test.go b/pkg/provider/kubernetes/ingress/client_mock_test.go index 6cc6ef13809c8d52e472a0f740417d5cef40308f..6d91c37c8509e7a6dfef3027dc5289ea1d7861ed 100644 --- a/pkg/provider/kubernetes/ingress/client_mock_test.go +++ b/pkg/provider/kubernetes/ingress/client_mock_test.go @@ -5,7 +5,7 @@ import ( "os" "github.com/hashicorp/go-version" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/k8s" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/k8s" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" networkingv1beta1 "k8s.io/api/networking/v1beta1" diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-native-service-lb_ingress.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-native-service-lb_ingress.yml new file mode 100644 index 0000000000000000000000000000000000000000..f9645ad09ffc380ae1b9a6d19375cb6d9dc11a1f --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-native-service-lb_ingress.yml @@ -0,0 +1,15 @@ +kind: Ingress +apiVersion: networking.k8s.io/v1beta1 +metadata: + name: "" + namespace: testing + +spec: + rules: + - host: traefik.tchouk + http: + paths: + - path: /bar + backend: + serviceName: service1 + servicePort: 8080 diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-native-service-lb_service.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-native-service-lb_service.yml new file mode 100644 index 0000000000000000000000000000000000000000..e394301fc7aae064eb10d2e24391aeeb9e97086d --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-with-native-service-lb_service.yml @@ -0,0 +1,15 @@ +kind: Service +apiVersion: v1 +metadata: + name: service1 + namespace: testing + annotations: + traefik.ingress.kubernetes.io/service.nativelb: "true" + +spec: + ports: + - port: 8080 + clusterIP: 10.0.0.1 + type: ClusterIP + externalName: traefik.wtf + diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index 95a71c12d671e188ea94228e8288ce561cd77f12..9bab326a25cc05874db24484ce58ce552c3fad91 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -18,12 +18,12 @@ import ( "github.com/mitchellh/hashstructure" "github.com/rs/zerolog/log" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/job" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/tls" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" "k8s.io/apimachinery/pkg/labels" @@ -48,6 +48,7 @@ type Provider struct { ThrottleDuration ptypes.Duration `description:"Ingress refresh throttle duration" json:"throttleDuration,omitempty" toml:"throttleDuration,omitempty" yaml:"throttleDuration,omitempty" export:"true"` AllowEmptyServices bool `description:"Allow creation of services without endpoints." json:"allowEmptyServices,omitempty" toml:"allowEmptyServices,omitempty" yaml:"allowEmptyServices,omitempty" export:"true"` AllowExternalNameServices bool `description:"Allow ExternalName services." json:"allowExternalNameServices,omitempty" toml:"allowExternalNameServices,omitempty" yaml:"allowExternalNameServices,omitempty" export:"true"` + DisableIngressClassLookup bool `description:"Disables the lookup of IngressClasses." json:"disableIngressClassLookup,omitempty" toml:"disableIngressClassLookup,omitempty" yaml:"disableIngressClassLookup,omitempty" export:"true"` lastConfiguration safe.Safe } @@ -91,6 +92,7 @@ func (p *Provider) newK8sClient(ctx context.Context) (*clientWrapper, error) { } cl.ingressLabelSelector = p.LabelSelector + cl.disableIngressClassInformer = p.DisableIngressClassLookup return cl, nil } @@ -195,7 +197,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl var ingressClasses []*networkingv1.IngressClass - if supportsIngressClass(serverVersion) { + if !p.DisableIngressClassLookup && supportsIngressClass(serverVersion) { ics, err := client.GetIngressClasses() if err != nil { log.Ctx(ctx).Warn().Err(err).Msg("Failed to list ingress classes") @@ -543,6 +545,21 @@ func (p *Provider) loadService(client Client, namespace string, backend networki if svcConfig.Service.ServersTransport != "" { svc.LoadBalancer.ServersTransport = svcConfig.Service.ServersTransport } + + if svcConfig.Service.NativeLB { + address, err := getNativeServiceAddress(*service, portSpec) + if err != nil { + return nil, fmt.Errorf("getting native Kubernetes Service address: %w", err) + } + + protocol := getProtocol(portSpec, portSpec.Name, svcConfig) + + svc.LoadBalancer.Servers = []dynamic.Server{ + {URL: fmt.Sprintf("%s://%s", protocol, address)}, + } + + return svc, nil + } } if service.Spec.Type == corev1.ServiceTypeExternalName { @@ -592,6 +609,18 @@ func (p *Provider) loadService(client Client, namespace string, backend networki return svc, nil } +func getNativeServiceAddress(service corev1.Service, svcPort corev1.ServicePort) (string, error) { + if service.Spec.ClusterIP == "None" { + return "", fmt.Errorf("no clusterIP on headless service: %s/%s", service.Namespace, service.Name) + } + + if service.Spec.ClusterIP == "" { + return "", fmt.Errorf("no clusterIP found for service: %s/%s", service.Namespace, service.Name) + } + + return net.JoinHostPort(service.Spec.ClusterIP, strconv.Itoa(int(svcPort.Port))), nil +} + func getProtocol(portSpec corev1.ServicePort, portName string, svcConfig *ServiceConfig) string { if svcConfig != nil && svcConfig.Service != nil && svcConfig.Service.ServersScheme != "" { return svcConfig.Service.ServersScheme diff --git a/pkg/provider/kubernetes/ingress/kubernetes_test.go b/pkg/provider/kubernetes/ingress/kubernetes_test.go index 3b032f9961adbe437ab22c451f4a9cee0c4fe917..9a3e4e05f24322ac83f3f1b7c64e7c12d2f244e7 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes_test.go +++ b/pkg/provider/kubernetes/ingress/kubernetes_test.go @@ -5,16 +5,17 @@ import ( "errors" "math" "os" + "path/filepath" "strings" "testing" "time" "github.com/stretchr/testify/assert" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" corev1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -26,11 +27,12 @@ func Bool(v bool) *bool { return &v } func TestLoadConfigurationFromIngresses(t *testing.T) { testCases := []struct { - desc string - ingressClass string - serverVersion string - expected *dynamic.Configuration - allowEmptyServices bool + desc string + ingressClass string + serverVersion string + expected *dynamic.Configuration + allowEmptyServices bool + disableIngressClassLookup bool }{ { desc: "Empty ingresses", @@ -1392,6 +1394,40 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, }, }, + { + // Duplicate test case with the same fixture as the one above, but with the disableIngressClassLookup option to true. + // Showing that disabling the ingressClass discovery still allow the discovery of ingresses with ingress annotation. + desc: "v18 Ingress with ingress annotation", + serverVersion: "v1.18", + disableIngressClassLookup: true, + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{ + "testing-bar": { + Rule: "PathPrefix(`/bar`)", + Service: "testing-service1-80", + }, + }, + Services: map[string]*dynamic.Service{ + "testing-service1-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + }, + }, + }, + }, + }, + }, + }, { desc: "v18 Ingress with ingressClasses filter", serverVersion: "v1.18", @@ -1424,6 +1460,22 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, }, }, + { + // Duplicate test case with the same fixture as the one above, but with the disableIngressClassLookup option to true. + // Showing that disabling the ingressClass discovery avoid discovering Ingresses with an IngressClass. + desc: "v18 Ingress with ingressClasses filter", + serverVersion: "v1.18", + ingressClass: "traefik-lb2", + disableIngressClassLookup: true, + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{}, + Services: map[string]*dynamic.Service{}, + }, + }, + }, { desc: "v19 Ingress with prefix pathType", serverVersion: "v1.19", @@ -1610,6 +1662,39 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, }, }, + { + // Duplicate test case with the same fixture as the one above, but with the disableIngressClassLookup option to true. + // Showing that disabling the ingressClass discovery still allow the discovery of ingresses with ingress annotation. + desc: "v19 Ingress with ingress annotation", + serverVersion: "v1.19", + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{ + "testing-bar": { + Rule: "PathPrefix(`/bar`)", + Service: "testing-service1-80", + }, + }, + Services: map[string]*dynamic.Service{ + "testing-service1-80": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + PassHostHeader: Bool(true), + ResponseForwarding: &dynamic.ResponseForwarding{ + FlushInterval: ptypes.Duration(100 * time.Millisecond), + }, + Servers: []dynamic.Server{ + { + URL: "http://10.10.0.1:8080", + }, + }, + }, + }, + }, + }, + }, + }, { desc: "v19 Ingress with ingressClass", serverVersion: "v1.19", @@ -1641,6 +1726,21 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, }, }, + { + // Duplicate test case with the same fixture as the one above, but with the disableIngressClassLookup option to true. + // Showing that disabling the ingressClass discovery avoid discovering Ingresses with an IngressClass. + desc: "v19 Ingress with ingressClass", + disableIngressClassLookup: true, + serverVersion: "v1.19", + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{}, + Services: map[string]*dynamic.Service{}, + }, + }, + }, { desc: "v19 Ingress with ingressClassv1", serverVersion: "v1.19", @@ -1783,7 +1883,11 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { } clientMock := newClientMock(serverVersion, paths...) - p := Provider{IngressClass: test.ingressClass, AllowEmptyServices: test.allowEmptyServices} + p := Provider{ + IngressClass: test.ingressClass, + AllowEmptyServices: test.allowEmptyServices, + DisableIngressClassLookup: test.disableIngressClassLookup, + } conf := p.loadConfigurationFromIngresses(context.Background(), clientMock) assert.Equal(t, test.expected, conf) @@ -1948,8 +2052,88 @@ func TestLoadConfigurationFromIngressesWithExternalNameServices(t *testing.T) { } } +func TestLoadConfigurationFromIngressesWithNativeLB(t *testing.T) { + testCases := []struct { + desc string + ingressClass string + serverVersion string + expected *dynamic.Configuration + }{ + { + desc: "Ingress with native service lb", + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Middlewares: map[string]*dynamic.Middleware{}, + Routers: map[string]*dynamic.Router{ + "testing-traefik-tchouk-bar": { + Rule: "Host(`traefik.tchouk`) && PathPrefix(`/bar`)", + Service: "testing-service1-8080", + }, + }, + Services: map[string]*dynamic.Service{ + "testing-service1-8080": { + LoadBalancer: &dynamic.ServersLoadBalancer{ + ResponseForwarding: &dynamic.ResponseForwarding{FlushInterval: dynamic.DefaultFlushInterval}, + PassHostHeader: Bool(true), + Servers: []dynamic.Server{ + { + URL: "http://10.0.0.1:8080", + }, + }, + }, + }, + }, + }, + }, + }, + } + + for _, test := range testCases { + test := test + + t.Run(test.desc, func(t *testing.T) { + t.Parallel() + + var paths []string + _, err := os.Stat(generateTestFilename("_ingress", test.desc)) + if err == nil { + paths = append(paths, generateTestFilename("_ingress", test.desc)) + } + _, err = os.Stat(generateTestFilename("_endpoint", test.desc)) + if err == nil { + paths = append(paths, generateTestFilename("_endpoint", test.desc)) + } + _, err = os.Stat(generateTestFilename("_service", test.desc)) + if err == nil { + paths = append(paths, generateTestFilename("_service", test.desc)) + } + _, err = os.Stat(generateTestFilename("_secret", test.desc)) + if err == nil { + paths = append(paths, generateTestFilename("_secret", test.desc)) + } + _, err = os.Stat(generateTestFilename("_ingressclass", test.desc)) + if err == nil { + paths = append(paths, generateTestFilename("_ingressclass", test.desc)) + } + + serverVersion := test.serverVersion + if serverVersion == "" { + serverVersion = "v1.17" + } + + clientMock := newClientMock(serverVersion, paths...) + + p := Provider{IngressClass: test.ingressClass} + conf := p.loadConfigurationFromIngresses(context.Background(), clientMock) + + assert.Equal(t, test.expected, conf) + }) + } +} + func generateTestFilename(suffix, desc string) string { - return "./fixtures/" + strings.ReplaceAll(desc, " ", "-") + suffix + ".yml" + return filepath.Join("fixtures", strings.ReplaceAll(desc, " ", "-")+suffix+".yml") } func TestGetCertificates(t *testing.T) { diff --git a/pkg/provider/kubernetes/k8s/parser.go b/pkg/provider/kubernetes/k8s/parser.go index 6b1f43b76cfdb0016cd56a08c83022738f122f18..6cea900dca805338df38b29852fb08ee8fc46c7a 100644 --- a/pkg/provider/kubernetes/k8s/parser.go +++ b/pkg/provider/kubernetes/k8s/parser.go @@ -12,7 +12,7 @@ import ( // MustParseYaml parses a YAML to objects. func MustParseYaml(content []byte) []runtime.Object { - acceptedK8sTypes := regexp.MustCompile(`^(Namespace|Deployment|Endpoints|Service|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|MiddlewareTCP|Secret|TLSOption|TLSStore|TraefikService|IngressClass|ServersTransport|GatewayClass|Gateway|HTTPRoute|TCPRoute|TLSRoute)$`) + acceptedK8sTypes := regexp.MustCompile(`^(Namespace|Deployment|Endpoints|Service|Ingress|IngressRoute|IngressRouteTCP|IngressRouteUDP|Middleware|MiddlewareTCP|Secret|TLSOption|TLSStore|TraefikService|IngressClass|ServersTransport|ServersTransportTCP|GatewayClass|Gateway|HTTPRoute|TCPRoute|TLSRoute)$`) files := strings.Split(string(content), "---\n") retVal := make([]runtime.Object, 0, len(files)) diff --git a/pkg/provider/kv/consul/consul.go b/pkg/provider/kv/consul/consul.go index 4a537c78f93f951cab229d76e75d51629e6d0a94..2a5fdfd497fa9b0a323aeb48e3a6682ed6b3fcb5 100644 --- a/pkg/provider/kv/consul/consul.go +++ b/pkg/provider/kv/consul/consul.go @@ -7,9 +7,9 @@ import ( "time" "github.com/kvtools/consul" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/kv" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/kv" + "github.com/traefik/traefik/v3/pkg/types" ) // providerName is the Consul provider name. diff --git a/pkg/provider/kv/etcd/etcd.go b/pkg/provider/kv/etcd/etcd.go index 7cf027fedb9afb7ec18998c28be9e96a39742b78..9da0610761fef66f9ae0109c855f684c8194bdfb 100644 --- a/pkg/provider/kv/etcd/etcd.go +++ b/pkg/provider/kv/etcd/etcd.go @@ -6,9 +6,9 @@ import ( "time" "github.com/kvtools/etcdv3" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/kv" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/kv" + "github.com/traefik/traefik/v3/pkg/types" ) var _ provider.Provider = (*Provider)(nil) diff --git a/pkg/provider/kv/kv.go b/pkg/provider/kv/kv.go index f6697b82193a85a56adbb04cf8d4e4950d1f34e1..fd2671306ca430a155f9885d36de0c609c8ed4c1 100644 --- a/pkg/provider/kv/kv.go +++ b/pkg/provider/kv/kv.go @@ -11,11 +11,11 @@ import ( "github.com/kvtools/valkeyrie" "github.com/kvtools/valkeyrie/store" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/kv" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/kv" + "github.com/traefik/traefik/v3/pkg/job" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/safe" ) // Provider holds configurations of the provider. diff --git a/pkg/provider/kv/kv_test.go b/pkg/provider/kv/kv_test.go index f577da7e35ae0aaf1a4686d2fb9d7ce137104e6e..8ba2cde9960bfa4ad5a6a8f2c93bc02249b876b0 100644 --- a/pkg/provider/kv/kv_test.go +++ b/pkg/provider/kv/kv_test.go @@ -10,9 +10,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" ) func Test_buildConfiguration(t *testing.T) { @@ -226,7 +226,6 @@ func Test_buildConfiguration(t *testing.T) { "traefik/tcp/routers/TCPRouter1/tls/passthrough": "true", "traefik/tcp/routers/TCPRouter1/tls/options": "foobar", "traefik/tcp/routers/TCPRouter1/tls/certResolver": "foobar", - "traefik/tcp/services/TCPService01/loadBalancer/terminationDelay": "42", "traefik/tcp/services/TCPService01/loadBalancer/servers/0/address": "foobar", "traefik/tcp/services/TCPService01/loadBalancer/servers/1/address": "foobar", "traefik/tcp/services/TCPService02/weighted/services/0/name": "foobar", @@ -756,7 +755,6 @@ func Test_buildConfiguration(t *testing.T) { Services: map[string]*dynamic.TCPService{ "TCPService01": { LoadBalancer: &dynamic.TCPServersLoadBalancer{ - TerminationDelay: func(v int) *int { return &v }(42), Servers: []dynamic.TCPServer{ {Address: "foobar"}, {Address: "foobar"}, diff --git a/pkg/provider/kv/redis/redis.go b/pkg/provider/kv/redis/redis.go index 23f432bb1e63389e163eb1f4fc3c173ca222fda2..ddd7178cbee02b08afdb7d9b82e17753e52e841a 100644 --- a/pkg/provider/kv/redis/redis.go +++ b/pkg/provider/kv/redis/redis.go @@ -5,9 +5,9 @@ import ( "fmt" "github.com/kvtools/redis" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/kv" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/kv" + "github.com/traefik/traefik/v3/pkg/types" ) var _ provider.Provider = (*Provider)(nil) diff --git a/pkg/provider/kv/zk/zk.go b/pkg/provider/kv/zk/zk.go index 28b7fee1201168ccfe43583dd68e256b4a9d8e20..9d66cee34a5c0d102d1d9da7e996927bf5ea3e4e 100644 --- a/pkg/provider/kv/zk/zk.go +++ b/pkg/provider/kv/zk/zk.go @@ -4,8 +4,8 @@ import ( "time" "github.com/kvtools/zookeeper" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/kv" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/kv" ) var _ provider.Provider = (*Provider)(nil) diff --git a/pkg/provider/marathon/builder_test.go b/pkg/provider/marathon/builder_test.go deleted file mode 100644 index e18110787ec408006929f6ae66f709944b17d080..0000000000000000000000000000000000000000 --- a/pkg/provider/marathon/builder_test.go +++ /dev/null @@ -1,205 +0,0 @@ -package marathon - -import ( - "strings" - "time" - - "github.com/gambol99/go-marathon" -) - -const testTaskName = "taskID" - -// Functions related to building applications. - -func withApplications(apps ...marathon.Application) *marathon.Applications { - return &marathon.Applications{Apps: apps} -} - -func application(ops ...func(*marathon.Application)) marathon.Application { - app := marathon.Application{} - app.EmptyLabels() - app.Deployments = []map[string]string{} - app.ReadinessChecks = &[]marathon.ReadinessCheck{} - app.ReadinessCheckResults = &[]marathon.ReadinessCheckResult{} - - for _, op := range ops { - op(&app) - } - - return app -} - -func appID(name string) func(*marathon.Application) { - return func(app *marathon.Application) { - app.Name(name) - } -} - -func appPorts(ports ...int) func(*marathon.Application) { - return func(app *marathon.Application) { - app.Ports = append(app.Ports, ports...) - } -} - -func withLabel(key, value string) func(*marathon.Application) { - return func(app *marathon.Application) { - app.AddLabel(key, value) - } -} - -func constraint(value string) func(*marathon.Application) { - return func(app *marathon.Application) { - app.AddConstraint(strings.Split(value, ":")...) - } -} - -func portDefinition(port int, name string) func(*marathon.Application) { - return func(app *marathon.Application) { - app.AddPortDefinition(marathon.PortDefinition{ - Port: &port, - Name: name, - }) - } -} - -func bridgeNetwork() func(*marathon.Application) { - return func(app *marathon.Application) { - app.SetNetwork("bridge", marathon.BridgeNetworkMode) - } -} - -func containerNetwork() func(*marathon.Application) { - return func(app *marathon.Application) { - app.SetNetwork("cni", marathon.ContainerNetworkMode) - } -} - -func ipAddrPerTask(port int) func(*marathon.Application) { - return func(app *marathon.Application) { - p := marathon.Port{ - Number: port, - Name: "port", - } - disc := marathon.Discovery{} - disc.AddPort(p) - ipAddr := marathon.IPAddressPerTask{} - ipAddr.SetDiscovery(disc) - app.SetIPAddressPerTask(ipAddr) - } -} - -func deployments(ids ...string) func(*marathon.Application) { - return func(app *marathon.Application) { - for _, id := range ids { - app.Deployments = append(app.Deployments, map[string]string{ - "ID": id, - }) - } - } -} - -func readinessCheck(timeout time.Duration) func(*marathon.Application) { - return func(app *marathon.Application) { - app.ReadinessChecks = &[]marathon.ReadinessCheck{ - { - Path: "/ready", - TimeoutSeconds: int(timeout.Seconds()), - }, - } - } -} - -func readinessCheckResult(taskID string, ready bool) func(*marathon.Application) { - return func(app *marathon.Application) { - *app.ReadinessCheckResults = append(*app.ReadinessCheckResults, marathon.ReadinessCheckResult{ - TaskID: taskID, - Ready: ready, - }) - } -} - -func withTasks(tasks ...marathon.Task) func(*marathon.Application) { - return func(application *marathon.Application) { - for _, task := range tasks { - tu := task - application.Tasks = append(application.Tasks, &tu) - } - } -} - -// Functions related to building tasks. - -func task(ops ...func(*marathon.Task)) marathon.Task { - t := &marathon.Task{ - ID: testTaskName, - // The vast majority of tests expect the task state to be TASK_RUNNING. - State: string(taskStateRunning), - } - - for _, op := range ops { - op(t) - } - - return *t -} - -func withTaskID(id string) func(*marathon.Task) { - return func(task *marathon.Task) { - task.ID = id - } -} - -func localhostTask(ops ...func(*marathon.Task)) marathon.Task { - t := task( - host("localhost"), - ipAddresses("127.0.0.1"), - taskState(taskStateRunning), - ) - - for _, op := range ops { - op(&t) - } - - return t -} - -func taskPorts(ports ...int) func(*marathon.Task) { - return func(t *marathon.Task) { - t.Ports = append(t.Ports, ports...) - } -} - -func taskState(state TaskState) func(*marathon.Task) { - return func(t *marathon.Task) { - t.State = string(state) - } -} - -func host(h string) func(*marathon.Task) { - return func(t *marathon.Task) { - t.Host = h - } -} - -func ipAddresses(addresses ...string) func(*marathon.Task) { - return func(t *marathon.Task) { - for _, addr := range addresses { - t.IPAddresses = append(t.IPAddresses, &marathon.IPAddress{ - IPAddress: addr, - Protocol: "tcp", - }) - } - } -} - -func startedAt(timestamp string) func(*marathon.Task) { - return func(t *marathon.Task) { - t.StartedAt = timestamp - } -} - -func startedAtFromNow(offset time.Duration) func(*marathon.Task) { - return func(t *marathon.Task) { - t.StartedAt = time.Now().Add(-offset).Format(time.RFC3339) - } -} diff --git a/pkg/provider/marathon/config.go b/pkg/provider/marathon/config.go deleted file mode 100644 index 9395053519a425739fc25308def8cf0c816acfd8..0000000000000000000000000000000000000000 --- a/pkg/provider/marathon/config.go +++ /dev/null @@ -1,474 +0,0 @@ -package marathon - -import ( - "context" - "errors" - "fmt" - "math" - "net" - "strconv" - "strings" - - "github.com/gambol99/go-marathon" - "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/label" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/constraints" -) - -func (p *Provider) buildConfiguration(ctx context.Context, applications *marathon.Applications) *dynamic.Configuration { - configurations := make(map[string]*dynamic.Configuration) - - for _, app := range applications.Apps { - logger := log.Ctx(ctx).With().Str("applicationID", app.ID).Logger() - ctxApp := logger.WithContext(ctx) - - extraConf, err := p.getConfiguration(app) - if err != nil { - logger.Error().Err(err).Msg("Skip application") - continue - } - - labels := stringValueMap(app.Labels) - - if app.Constraints != nil { - for i, constraintParts := range *app.Constraints { - key := constraints.MarathonConstraintPrefix + "-" + strconv.Itoa(i) - labels[key] = strings.Join(constraintParts, ":") - } - } - - if !p.keepApplication(ctxApp, extraConf, labels) { - continue - } - - confFromLabel, err := label.DecodeConfiguration(labels) - if err != nil { - logger.Error().Err(err).Send() - continue - } - - var tcpOrUDP bool - if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 { - tcpOrUDP = true - - err := p.buildTCPServiceConfiguration(ctxApp, app, extraConf, confFromLabel.TCP) - if err != nil { - logger.Error().Err(err).Send() - continue - } - provider.BuildTCPRouterConfiguration(ctxApp, confFromLabel.TCP) - } - - if len(confFromLabel.UDP.Routers) > 0 || len(confFromLabel.UDP.Services) > 0 { - tcpOrUDP = true - - err := p.buildUDPServiceConfiguration(ctxApp, app, extraConf, confFromLabel.UDP) - if err != nil { - logger.Error().Err(err).Send() - } else { - provider.BuildUDPRouterConfiguration(ctxApp, confFromLabel.UDP) - } - } - - if tcpOrUDP && len(confFromLabel.HTTP.Routers) == 0 && - len(confFromLabel.HTTP.Middlewares) == 0 && - len(confFromLabel.HTTP.Services) == 0 { - configurations[app.ID] = confFromLabel - continue - } - - err = p.buildServiceConfiguration(ctxApp, app, extraConf, confFromLabel.HTTP) - if err != nil { - logger.Error().Err(err).Send() - continue - } - - model := struct { - Name string - Labels map[string]string - }{ - Name: app.ID, - Labels: labels, - } - - serviceName := getServiceName(app) - - provider.BuildRouterConfiguration(ctxApp, confFromLabel.HTTP, serviceName, p.defaultRuleTpl, model) - - configurations[app.ID] = confFromLabel - } - - return provider.Merge(ctx, configurations) -} - -func getServiceName(app marathon.Application) string { - return strings.ReplaceAll(strings.TrimPrefix(app.ID, "/"), "/", "_") -} - -func (p *Provider) buildServiceConfiguration(ctx context.Context, app marathon.Application, extraConf configuration, conf *dynamic.HTTPConfiguration) error { - appName := getServiceName(app) - - logger := log.Ctx(ctx).With().Str("applicationName", appName).Logger() - - if len(conf.Services) == 0 { - conf.Services = make(map[string]*dynamic.Service) - lb := &dynamic.ServersLoadBalancer{} - lb.SetDefaults() - conf.Services[appName] = &dynamic.Service{ - LoadBalancer: lb, - } - } - - for serviceName, service := range conf.Services { - var servers []dynamic.Server - - defaultServer := dynamic.Server{} - defaultServer.SetDefaults() - - if len(service.LoadBalancer.Servers) > 0 { - defaultServer = service.LoadBalancer.Servers[0] - } - - for _, task := range app.Tasks { - if !p.taskFilter(ctx, *task, app) { - continue - } - server, err := p.getServer(app, *task, extraConf, defaultServer) - if err != nil { - logger.Error().Err(err).Msg("Skip task") - continue - } - servers = append(servers, server) - } - if len(servers) == 0 { - return fmt.Errorf("no server for the service %s", serviceName) - } - service.LoadBalancer.Servers = servers - } - - return nil -} - -func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, app marathon.Application, extraConf configuration, conf *dynamic.TCPConfiguration) error { - appName := getServiceName(app) - - logger := log.Ctx(ctx).With().Str("applicationName", appName).Logger() - - if len(conf.Services) == 0 { - conf.Services = make(map[string]*dynamic.TCPService) - lb := &dynamic.TCPServersLoadBalancer{} - lb.SetDefaults() - conf.Services[appName] = &dynamic.TCPService{ - LoadBalancer: lb, - } - } - - for serviceName, service := range conf.Services { - var servers []dynamic.TCPServer - - defaultServer := dynamic.TCPServer{} - - if len(service.LoadBalancer.Servers) > 0 { - defaultServer = service.LoadBalancer.Servers[0] - } - - for _, task := range app.Tasks { - if p.taskFilter(ctx, *task, app) { - server, err := p.getTCPServer(app, *task, extraConf, defaultServer) - if err != nil { - logger.Error().Err(err).Msg("Skip task") - continue - } - servers = append(servers, server) - } - } - if len(servers) == 0 { - return fmt.Errorf("no server for the service %s", serviceName) - } - service.LoadBalancer.Servers = servers - } - - return nil -} - -func (p *Provider) buildUDPServiceConfiguration(ctx context.Context, app marathon.Application, extraConf configuration, conf *dynamic.UDPConfiguration) error { - appName := getServiceName(app) - logger := log.Ctx(ctx).With().Str("applicationName", appName).Logger() - - if len(conf.Services) == 0 { - conf.Services = make(map[string]*dynamic.UDPService) - lb := &dynamic.UDPServersLoadBalancer{} - - conf.Services[appName] = &dynamic.UDPService{ - LoadBalancer: lb, - } - } - - for serviceName, service := range conf.Services { - var servers []dynamic.UDPServer - - defaultServer := dynamic.UDPServer{} - - if len(service.LoadBalancer.Servers) > 0 { - defaultServer = service.LoadBalancer.Servers[0] - } - - for _, task := range app.Tasks { - if p.taskFilter(ctx, *task, app) { - server, err := p.getUDPServer(app, *task, extraConf, defaultServer) - if err != nil { - logger.Error().Err(err).Msg("Skip task") - continue - } - servers = append(servers, server) - } - } - if len(servers) == 0 { - return fmt.Errorf("no server for the service %s", serviceName) - } - service.LoadBalancer.Servers = servers - } - - return nil -} - -func (p *Provider) keepApplication(ctx context.Context, extraConf configuration, labels map[string]string) bool { - logger := log.Ctx(ctx) - - // Filter disabled application. - if !extraConf.Enable { - logger.Debug().Msg("Filtering disabled Marathon application") - return false - } - - // Filter by constraints. - matches, err := constraints.MatchLabels(labels, p.Constraints) - if err != nil { - logger.Error().Err(err).Msg("Error matching constraints expression") - return false - } - if !matches { - logger.Debug().Msgf("Marathon application filtered by constraint expression: %q", p.Constraints) - return false - } - - return true -} - -func (p *Provider) taskFilter(ctx context.Context, task marathon.Task, application marathon.Application) bool { - if task.State != string(taskStateRunning) { - return false - } - - if ready := p.readyChecker.Do(task, application); !ready { - log.Ctx(ctx).Info().Msgf("Filtering unready task %s from application %s", task.ID, application.ID) - return false - } - - return true -} - -func (p *Provider) getTCPServer(app marathon.Application, task marathon.Task, extraConf configuration, defaultServer dynamic.TCPServer) (dynamic.TCPServer, error) { - host, err := p.getServerHost(task, app, extraConf) - if len(host) == 0 { - return dynamic.TCPServer{}, err - } - - port, err := getPort(task, app, defaultServer.Port) - if err != nil { - return dynamic.TCPServer{}, err - } - - server := dynamic.TCPServer{ - Address: net.JoinHostPort(host, port), - } - - return server, nil -} - -func (p *Provider) getUDPServer(app marathon.Application, task marathon.Task, extraConf configuration, defaultServer dynamic.UDPServer) (dynamic.UDPServer, error) { - host, err := p.getServerHost(task, app, extraConf) - if len(host) == 0 { - return dynamic.UDPServer{}, err - } - - port, err := getPort(task, app, defaultServer.Port) - if err != nil { - return dynamic.UDPServer{}, err - } - - server := dynamic.UDPServer{ - Address: net.JoinHostPort(host, port), - } - - return server, nil -} - -func (p *Provider) getServer(app marathon.Application, task marathon.Task, extraConf configuration, defaultServer dynamic.Server) (dynamic.Server, error) { - host, err := p.getServerHost(task, app, extraConf) - if len(host) == 0 { - return dynamic.Server{}, err - } - - port, err := getPort(task, app, defaultServer.Port) - if err != nil { - return dynamic.Server{}, err - } - - server := dynamic.Server{ - URL: fmt.Sprintf("%s://%s", defaultServer.Scheme, net.JoinHostPort(host, port)), - } - - return server, nil -} - -func (p *Provider) getServerHost(task marathon.Task, app marathon.Application, extraConf configuration) (string, error) { - networks := app.Networks - var hostFlag bool - - if networks == nil { - hostFlag = app.IPAddressPerTask == nil - } else { - hostFlag = (*networks)[0].Mode != marathon.ContainerNetworkMode - } - - if hostFlag || p.ForceTaskHostname { - if len(task.Host) == 0 { - return "", fmt.Errorf("host is undefined for task %q app %q", task.ID, app.ID) - } - return task.Host, nil - } - - numTaskIPAddresses := len(task.IPAddresses) - switch numTaskIPAddresses { - case 0: - return "", fmt.Errorf("missing IP address for Marathon application %s on task %s", app.ID, task.ID) - case 1: - return task.IPAddresses[0].IPAddress, nil - default: - if extraConf.Marathon.IPAddressIdx == math.MinInt32 { - return "", fmt.Errorf("found %d task IP addresses but missing IP address index for Marathon application %s on task %s", - numTaskIPAddresses, app.ID, task.ID) - } - if extraConf.Marathon.IPAddressIdx < 0 || extraConf.Marathon.IPAddressIdx > numTaskIPAddresses { - return "", fmt.Errorf("cannot use IP address index to select from %d task IP addresses for Marathon application %s on task %s", - numTaskIPAddresses, app.ID, task.ID) - } - - return task.IPAddresses[extraConf.Marathon.IPAddressIdx].IPAddress, nil - } -} - -func getPort(task marathon.Task, app marathon.Application, serverPort string) (string, error) { - port, err := processPorts(app, task, serverPort) - if err != nil { - return "", fmt.Errorf("unable to process ports for %s %s: %w", app.ID, task.ID, err) - } - - return strconv.Itoa(port), nil -} - -// processPorts returns the configured port. -// An explicitly specified port is preferred. If none is specified, it selects -// one of the available port. The first such found port is returned unless an -// optional index is provided. -func processPorts(app marathon.Application, task marathon.Task, serverPort string) (int, error) { - if len(serverPort) > 0 && !(strings.HasPrefix(serverPort, "index:") || strings.HasPrefix(serverPort, "name:")) { - port, err := strconv.Atoi(serverPort) - if err != nil { - return 0, err - } - - if port <= 0 { - return 0, fmt.Errorf("explicitly specified port %d must be greater than zero", port) - } else if port > 0 { - return port, nil - } - } - - if strings.HasPrefix(serverPort, "name:") { - name := strings.TrimPrefix(serverPort, "name:") - port := retrieveNamedPort(app, name) - - if port == 0 { - return 0, fmt.Errorf("no port with name %s", name) - } - - return port, nil - } - - ports := retrieveAvailablePorts(app, task) - if len(ports) == 0 { - return 0, errors.New("no port found") - } - - portIndex := 0 - if strings.HasPrefix(serverPort, "index:") { - indexString := strings.TrimPrefix(serverPort, "index:") - index, err := strconv.Atoi(indexString) - if err != nil { - return 0, err - } - - if index < 0 || index > len(ports)-1 { - return 0, fmt.Errorf("index %d must be within range (0, %d)", index, len(ports)-1) - } - - portIndex = index - } - - return ports[portIndex], nil -} - -func retrieveNamedPort(app marathon.Application, name string) int { - // Using port definition if available - if app.PortDefinitions != nil && len(*app.PortDefinitions) > 0 { - for _, def := range *app.PortDefinitions { - if def.Port != nil && *def.Port > 0 && def.Name == name { - return *def.Port - } - } - } - - // If using IP-per-task using this port definition - if app.IPAddressPerTask != nil && app.IPAddressPerTask.Discovery != nil && len(*(app.IPAddressPerTask.Discovery.Ports)) > 0 { - for _, def := range *(app.IPAddressPerTask.Discovery.Ports) { - if def.Number > 0 && def.Name == name { - return def.Number - } - } - } - - return 0 -} - -func retrieveAvailablePorts(app marathon.Application, task marathon.Task) []int { - // Using default port configuration - if len(task.Ports) > 0 { - return task.Ports - } - - // Using port definition if available - if app.PortDefinitions != nil && len(*app.PortDefinitions) > 0 { - var ports []int - for _, def := range *app.PortDefinitions { - if def.Port != nil { - ports = append(ports, *def.Port) - } - } - return ports - } - - // If using IP-per-task using this port definition - if app.IPAddressPerTask != nil && app.IPAddressPerTask.Discovery != nil && len(*(app.IPAddressPerTask.Discovery.Ports)) > 0 { - var ports []int - for _, def := range *(app.IPAddressPerTask.Discovery.Ports) { - ports = append(ports, def.Number) - } - return ports - } - - return []int{} -} diff --git a/pkg/provider/marathon/config_test.go b/pkg/provider/marathon/config_test.go deleted file mode 100644 index 4e5b4d563c27e07711c5ac2006ab5190364989c0..0000000000000000000000000000000000000000 --- a/pkg/provider/marathon/config_test.go +++ /dev/null @@ -1,2413 +0,0 @@ -package marathon - -import ( - "context" - "math" - "testing" - "time" - - "github.com/gambol99/go-marathon" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" -) - -func Int(v int) *int { return &v } -func Bool(v bool) *bool { return &v } - -func TestGetConfigurationAPIErrors(t *testing.T) { - fakeClient := newFakeClient(true, marathon.Applications{}) - - p := &Provider{ - marathonClient: fakeClient, - } - - actualConfig := p.getConfigurations(context.Background()) - fakeClient.AssertExpectations(t) - - if actualConfig != nil { - t.Errorf("configuration should have been nil, got %v", actualConfig) - } -} - -func TestBuildConfiguration(t *testing.T) { - testCases := []struct { - desc string - applications *marathon.Applications - constraints string - defaultRule string - expected *dynamic.Configuration - }{ - { - desc: "simple application", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "filtered task", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80), taskState(taskStateStaging))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "multiple ports", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "with basic auth", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - withLabel("traefik.http.middlewares.Middleware1.basicauth.users", "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), - withLabel("traefik.http.routers.app.middlewares", "Middleware1"), - withTasks(localhostTask(taskPorts(80))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - Middlewares: []string{"Middleware1"}, - }, - }, - Middlewares: map[string]*dynamic.Middleware{ - "Middleware1": { - BasicAuth: &dynamic.BasicAuth{ - Users: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - }, - }, - }, - Services: map[string]*dynamic.Service{ - "app": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "TCP with IP allowlist", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - - withLabel("traefik.tcp.routers.Test.rule", "HostSNI(`foo.bar`)"), - withLabel("traefik.tcp.middlewares.Middleware1.ipallowlist.sourcerange", "foobar, fiibar"), - withLabel("traefik.tcp.routers.Test.middlewares", "Middleware1"), - withTasks(localhostTask(taskPorts(80))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "Test": { - Service: "app", - Rule: "HostSNI(`foo.bar`)", - Middlewares: []string{"Middleware1"}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{ - "Middleware1": { - IPAllowList: &dynamic.TCPIPAllowList{ - SourceRange: []string{"foobar", "fiibar"}, - }, - }, - }, - Services: map[string]*dynamic.TCPService{ - "app": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:80", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "2 applications in the same service", - applications: withApplications( - application( - appID("/foo-v000"), - withTasks(localhostTask(taskPorts(8080))), - - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"), - withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"), - ), - application( - appID("/foo-v001"), - withTasks(localhostTask(taskPorts(8081))), - - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"), - withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"), - ), - ), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:8080", - }, - { - URL: "http://localhost:8081", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "2 applications with 2 tasks in the same service", - applications: withApplications( - application( - appID("/foo-v000"), - withTasks(localhostTask(taskPorts(8080))), - withTasks(localhostTask(taskPorts(8081))), - - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"), - withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"), - ), - application( - appID("/foo-v001"), - withTasks(localhostTask(taskPorts(8082))), - withTasks(localhostTask(taskPorts(8083))), - - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "index:0"), - withLabel("traefik.http.routers.Router1.rule", "Host(`app.marathon.localhost`)"), - ), - ), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:8080", - }, - { - URL: "http://localhost:8081", - }, - { - URL: "http://localhost:8082", - }, - { - URL: "http://localhost:8083", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "2 applications", - applications: withApplications( - application( - appID("/foo"), - withTasks(localhostTask(taskPorts(8080))), - ), - application( - appID("/bar"), - withTasks(localhostTask(taskPorts(8081))), - ), - ), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "foo": { - Service: "foo", - Rule: "Host(`foo.marathon.localhost`)", - }, - "bar": { - Service: "bar", - Rule: "Host(`bar.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "foo": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:8080", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - "bar": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:8081", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two tasks no labels", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80)), localhostTask(taskPorts(81))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - { - URL: "http://localhost:81", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "simple application with label on service", - applications: withApplications( - application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "Service1", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": {LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }}, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with labels", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.routers.Router1.service", "Service1"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`foo.com`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with rule label", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "app", - Rule: "Host(`foo.com`)", - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with rule label and one service", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`foo.com`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with rule label and two services", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), - withLabel("traefik.http.services.Service2.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "Service2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with same service name and different passhostheader", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "false"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "Service1", - Rule: "Host(`app.marathon.localhost`)", - }, - "app2": { - Service: "Service1", - Rule: "Host(`app2.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with two identical middleware", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.middlewares.Middleware1.inflightreq.amount", "42"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.middlewares.Middleware1.inflightreq.amount", "42"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - "app2": { - Service: "app2", - Rule: "Host(`app2.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{ - "Middleware1": { - InFlightReq: &dynamic.InFlightReq{ - Amount: 42, - }, - }, - }, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "app2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with two different middlewares", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.middlewares.Middleware1.inflightreq.amount", "42"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.middlewares.Middleware1.inflightreq.amount", "41"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - "app2": { - Service: "app2", - Rule: "Host(`app2.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "app2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with two different routers with same name", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`bar.com`)"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "app2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with two identical routers with same name", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.LoadBalancer.passhostheader", "true"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - withLabel("traefik.http.services.Service1.LoadBalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`foo.com`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two apps with two identical routers with same name", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - ), - application( - appID("/app2"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.routers.Router1.rule", "Host(`foo.com`)"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "app2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with wrong label", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.wrong.label", "tchouk"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with label port", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.LoadBalancer.server.scheme", "h2c"), - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", "90"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "Service1", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "h2c://localhost:90", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with label port on two services", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.http.services.Service1.LoadBalancer.server.port", ""), - withLabel("traefik.http.services.Service2.LoadBalancer.server.port", "8080"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "Service2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:8080", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app without port", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask()), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app without port with middleware", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask()), - withLabel("traefik.http.middlewares.Middleware1.basicauth.users", "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with traefik.enable=false", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask()), - withLabel("traefik.enable", "false"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with traefik.enable=false", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask()), - withLabel("traefik.enable", "false"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with non matching constraint", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tags", "foo"), - )), - constraints: `Label("traefik.tags", "bar")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with non matching marathon constraint", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - constraint("rack_id:CLUSTER:rack-1"), - )), - constraints: `MarathonConstraint("rack_id:CLUSTER:rack-2")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with matching marathon constraint", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - constraint("rack_id:CLUSTER:rack-1"), - )), - constraints: `MarathonConstraint("rack_id:CLUSTER:rack-1")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with matching constraint", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tags", "bar"), - )), - constraints: `Label("traefik.tags", "bar")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "app", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with group as subdomain rule", - defaultRule: `Host("{{ .Name | trimPrefix "/" | splitList "/" | strsToItfs | reverse | join "." }}.marathon.localhost")`, - applications: withApplications( - application( - appID("/a/b/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "a_b_app": { - Service: "a_b_app", - Rule: `Host("app.b.a.marathon.localhost")`, - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "a_b_app": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with tcp labels", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tcp.routers.foo.rule", "HostSNI(`foo.bar`)"), - withLabel("traefik.tcp.routers.foo.tls", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "app", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "app": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:80", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with udp labels", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.udp.routers.foo.entrypoints", "mydns"), - )), - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "app", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "app": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "localhost:80", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with tcp labels without rule", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tcp.routers.foo.tls", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "app": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:80", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with tcp labels with port", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tcp.routers.foo.rule", "HostSNI(`foo.bar`)"), - withLabel("traefik.tcp.routers.foo.tls", "true"), - withLabel("traefik.tcp.services.foo.loadbalancer.server.port", "8080"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "foo", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:8080", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with udp labels with port", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.udp.routers.foo.entrypoints", "mydns"), - withLabel("traefik.udp.services.foo.loadbalancer.server.port", "8080"), - )), - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "foo", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "foo": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "localhost:8080", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with tcp labels with port, with termination delay", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tcp.routers.foo.rule", "HostSNI(`foo.bar`)"), - withLabel("traefik.tcp.routers.foo.tls", "true"), - withLabel("traefik.tcp.services.foo.loadbalancer.server.port", "8080"), - withLabel("traefik.tcp.services.foo.loadbalancer.terminationdelay", "200"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "foo", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:8080", - }, - }, - TerminationDelay: Int(200), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with tcp labels with port and http service", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.tcp.routers.foo.rule", "HostSNI(`foo.bar`)"), - withLabel("traefik.tcp.routers.foo.tls", "true"), - withLabel("traefik.tcp.services.foo.loadbalancer.server.port", "8080"), - withLabel("traefik.http.services.bar.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "foo", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "localhost:8080", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "bar", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "bar": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one app with udp labels with port and http service", - applications: withApplications( - application( - appID("/app"), - appPorts(80, 81), - withTasks(localhostTask(taskPorts(80, 81))), - withLabel("traefik.udp.routers.foo.entrypoints", "mydns"), - withLabel("traefik.udp.services.foo.loadbalancer.server.port", "8080"), - withLabel("traefik.http.services.bar.loadbalancer.passhostheader", "true"), - )), - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "foo", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "foo": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "localhost:8080", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "app": { - Service: "bar", - Rule: "Host(`app.marathon.localhost`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "bar": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://localhost:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - defaultRule := "Host(`{{ normalize .Name }}.marathon.localhost`)" - if len(test.defaultRule) > 0 { - defaultRule = test.defaultRule - } - - p := &Provider{ - DefaultRule: defaultRule, - ExposedByDefault: true, - } - p.Constraints = test.constraints - - err := p.Init() - require.NoError(t, err) - - actualConfig := p.buildConfiguration(context.Background(), test.applications) - - assert.NotNil(t, actualConfig) - assert.Equal(t, test.expected, actualConfig) - }) - } -} - -func TestApplicationFilterEnabled(t *testing.T) { - testCases := []struct { - desc string - exposedByDefault bool - enabledLabel string - expected bool - }{ - { - desc: "exposed and tolerated by valid label value", - exposedByDefault: true, - enabledLabel: "true", - expected: true, - }, - { - desc: "exposed but overridden by label", - exposedByDefault: true, - enabledLabel: "false", - expected: false, - }, - { - desc: "non-exposed but overridden by label", - exposedByDefault: false, - enabledLabel: "true", - expected: true, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - provider := &Provider{ExposedByDefault: true} - - app := application(withLabel("traefik.enable", test.enabledLabel)) - - extraConf, err := provider.getConfiguration(app) - require.NoError(t, err) - - if provider.keepApplication(context.Background(), extraConf, stringValueMap(app.Labels)) != test.expected { - t.Errorf("got unexpected filtering = %t", !test.expected) - } - }) - } -} - -func TestGetServer(t *testing.T) { - type expected struct { - server dynamic.Server - error string - } - - testCases := []struct { - desc string - provider Provider - app marathon.Application - extraConf configuration - defaultServer dynamic.Server - expected expected - }{ - { - desc: "undefined host", - provider: Provider{}, - app: application(), - extraConf: configuration{}, - defaultServer: dynamic.Server{}, - expected: expected{ - error: `host is undefined for task "taskID" app ""`, - }, - }, - { - desc: "with task port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:80", - }, - }, - }, - { - desc: "without task port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask()), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - error: "unable to process ports for /app taskID: no port found", - }, - }, - { - desc: "with default server port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "88", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:88", - }, - }, - }, - { - desc: "with invalid default server port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "aaaa", - }, - expected: expected{ - error: `unable to process ports for /app taskID: strconv.Atoi: parsing "aaaa": invalid syntax`, - }, - }, - { - desc: "with negative default server port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "-6", - }, - expected: expected{ - error: `unable to process ports for /app taskID: explicitly specified port -6 must be greater than zero`, - }, - }, - { - desc: "with port index", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80, 81))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "index:1", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:81", - }, - }, - }, - { - desc: "with out of range port index", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80, 81))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "index:2", - }, - expected: expected{ - error: "unable to process ports for /app taskID: index 2 must be within range (0, 1)", - }, - }, - { - desc: "with invalid port index", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80, 81))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "index:aaa", - }, - expected: expected{ - error: `unable to process ports for /app taskID: strconv.Atoi: parsing "aaa": invalid syntax`, - }, - }, - { - desc: "with port name", - provider: Provider{}, - app: application( - appID("/app"), - portDefinition(80, "fist-port"), - portDefinition(81, "second-port"), - portDefinition(82, "third-port"), - withTasks(localhostTask()), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "name:third-port", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:82", - }, - }, - }, - { - desc: "with port name not found", - provider: Provider{}, - app: application( - appID("/app"), - portDefinition(80, "fist-port"), - portDefinition(81, "second-port"), - portDefinition(82, "third-port"), - withTasks(localhostTask()), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - Port: "name:other-name", - }, - expected: expected{ - error: `unable to process ports for /app taskID: no port with name other-name`, - }, - }, - { - desc: "with application port and no task port", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - portDefinition(80, "http"), - withTasks(localhostTask()), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:80", - }, - }, - }, - { - desc: "with IP per task", - provider: Provider{}, - app: application( - appID("/app"), - appPorts(80), - ipAddrPerTask(88), - withTasks(localhostTask()), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://127.0.0.1:88", - }, - }, - }, - { - desc: "with container network", - provider: Provider{}, - app: application( - containerNetwork(), - appID("/app"), - appPorts(80), - withTasks(localhostTask(taskPorts(80, 81))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://127.0.0.1:80", - }, - }, - }, - { - desc: "with bridge network", - provider: Provider{}, - app: application( - bridgeNetwork(), - appID("/app"), - appPorts(83), - withTasks(localhostTask(taskPorts(80, 81))), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://localhost:80", - }, - }, - }, - { - desc: "with several IP addresses on task", - provider: Provider{}, - app: application( - ipAddrPerTask(88), - appID("/app"), - appPorts(83), - withTasks( - task( - withTaskID("myTask"), - host("localhost"), - ipAddresses("127.0.0.1", "127.0.0.2"), - taskState(taskStateRunning), - )), - ), - extraConf: configuration{ - Marathon: specificConfiguration{ - IPAddressIdx: 0, - }, - }, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - server: dynamic.Server{ - URL: "http://127.0.0.1:88", - }, - }, - }, - { - desc: "with several IP addresses on task, undefined [MinInt32] IPAddressIdx", - provider: Provider{}, - app: application( - ipAddrPerTask(88), - appID("/app"), - appPorts(83), - withTasks( - task( - host("localhost"), - ipAddresses("127.0.0.1", "127.0.0.2"), - taskState(taskStateRunning), - )), - ), - extraConf: configuration{ - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - error: "found 2 task IP addresses but missing IP address index for Marathon application /app on task taskID", - }, - }, - { - desc: "with several IP addresses on task, IPAddressIdx out of range", - provider: Provider{}, - app: application( - ipAddrPerTask(88), - appID("/app"), - appPorts(83), - withTasks( - task( - host("localhost"), - ipAddresses("127.0.0.1", "127.0.0.2"), - taskState(taskStateRunning), - )), - ), - extraConf: configuration{ - Marathon: specificConfiguration{ - IPAddressIdx: 3, - }, - }, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - error: "cannot use IP address index to select from 2 task IP addresses for Marathon application /app on task taskID", - }, - }, - { - desc: "with task without IP address", - provider: Provider{}, - app: application( - ipAddrPerTask(88), - appID("/app"), - appPorts(83), - withTasks( - task( - host("localhost"), - taskState(taskStateRunning), - )), - ), - extraConf: configuration{}, - defaultServer: dynamic.Server{ - Scheme: "http", - }, - expected: expected{ - error: "missing IP address for Marathon application /app on task taskID", - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - task := task() - if len(test.app.Tasks) > 0 { - task = *test.app.Tasks[0] - } - - server, err := test.provider.getServer(test.app, task, test.extraConf, test.defaultServer) - if len(test.expected.error) > 0 { - require.EqualError(t, err, test.expected.error) - } else { - require.NoError(t, err) - - assert.Equal(t, test.expected.server, server) - } - }) - } -} diff --git a/pkg/provider/marathon/fake_client_test.go b/pkg/provider/marathon/fake_client_test.go deleted file mode 100644 index c309414825d645f04ea84838099bd0c747c8ba58..0000000000000000000000000000000000000000 --- a/pkg/provider/marathon/fake_client_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package marathon - -import ( - "errors" - - "github.com/gambol99/go-marathon" - "github.com/stretchr/testify/mock" - "github.com/traefik/traefik/v2/pkg/provider/marathon/mocks" -) - -type fakeClient struct { - mocks.Marathon -} - -func newFakeClient(applicationsError bool, applications marathon.Applications) *fakeClient { - // create an instance of our test object - fakeClient := new(fakeClient) - if applicationsError { - fakeClient.On("Applications", mock.Anything).Return(nil, errors.New("fake Marathon server error")) - } else { - fakeClient.On("Applications", mock.Anything).Return(&applications, nil) - } - return fakeClient -} diff --git a/pkg/provider/marathon/label.go b/pkg/provider/marathon/label.go deleted file mode 100644 index f6da87870413deeda47109ae740e85e70ede8f20..0000000000000000000000000000000000000000 --- a/pkg/provider/marathon/label.go +++ /dev/null @@ -1,42 +0,0 @@ -package marathon - -import ( - "math" - - "github.com/gambol99/go-marathon" - "github.com/traefik/traefik/v2/pkg/config/label" -) - -type configuration struct { - Enable bool - Marathon specificConfiguration -} - -type specificConfiguration struct { - IPAddressIdx int -} - -func (p *Provider) getConfiguration(app marathon.Application) (configuration, error) { - labels := stringValueMap(app.Labels) - - conf := configuration{ - Enable: p.ExposedByDefault, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - } - - err := label.Decode(labels, &conf, "traefik.marathon.", "traefik.enable") - if err != nil { - return configuration{}, err - } - - return conf, nil -} - -func stringValueMap(mp *map[string]string) map[string]string { - if mp != nil { - return *mp - } - return make(map[string]string) -} diff --git a/pkg/provider/marathon/label_test.go b/pkg/provider/marathon/label_test.go deleted file mode 100644 index 472b91d2329e3ccdb2aabde478d11ffdfe08e314..0000000000000000000000000000000000000000 --- a/pkg/provider/marathon/label_test.go +++ /dev/null @@ -1,136 +0,0 @@ -package marathon - -import ( - "math" - "testing" - - "github.com/gambol99/go-marathon" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestGetConfiguration(t *testing.T) { - testCases := []struct { - desc string - app marathon.Application - p Provider - expected configuration - }{ - { - desc: "Empty labels", - app: marathon.Application{ - Constraints: &[][]string{}, - Labels: &map[string]string{}, - }, - p: Provider{ - ExposedByDefault: false, - }, - expected: configuration{ - Enable: false, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - }, - { - desc: "label enable", - app: marathon.Application{ - Constraints: &[][]string{}, - Labels: &map[string]string{ - "traefik.enable": "true", - }, - }, - p: Provider{ - ExposedByDefault: false, - }, - expected: configuration{ - Enable: true, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - }, - { - desc: "Use ip address index", - app: marathon.Application{ - Constraints: &[][]string{}, - Labels: &map[string]string{ - "traefik.marathon.IPAddressIdx": "4", - }, - }, - p: Provider{ - ExposedByDefault: false, - }, - expected: configuration{ - Enable: false, - Marathon: specificConfiguration{ - IPAddressIdx: 4, - }, - }, - }, - { - desc: "Use marathon constraints", - app: marathon.Application{ - Constraints: &[][]string{ - {"key", "value"}, - }, - Labels: &map[string]string{}, - }, - p: Provider{ - ExposedByDefault: false, - }, - expected: configuration{ - Enable: false, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - }, - { - desc: "ExposedByDefault and no enable label", - app: marathon.Application{ - Constraints: &[][]string{}, - Labels: &map[string]string{}, - }, - p: Provider{ - ExposedByDefault: true, - }, - expected: configuration{ - Enable: true, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - }, - { - desc: "ExposedByDefault and enable label false", - app: marathon.Application{ - Constraints: &[][]string{}, - Labels: &map[string]string{ - "traefik.enable": "false", - }, - }, - p: Provider{ - ExposedByDefault: true, - }, - expected: configuration{ - Enable: false, - Marathon: specificConfiguration{ - IPAddressIdx: math.MinInt32, - }, - }, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - extraConf, err := test.p.getConfiguration(test.app) - require.NoError(t, err) - - assert.Equal(t, test.expected, extraConf) - }) - } -} diff --git a/pkg/provider/marathon/marathon.go b/pkg/provider/marathon/marathon.go deleted file mode 100644 index d4e8cccd83765aec81ee53d46326604a1dc2f617..0000000000000000000000000000000000000000 --- a/pkg/provider/marathon/marathon.go +++ /dev/null @@ -1,221 +0,0 @@ -package marathon - -import ( - "context" - "fmt" - "net" - "net/http" - "net/url" - "text/template" - "time" - - "github.com/cenkalti/backoff/v4" - "github.com/gambol99/go-marathon" - "github.com/rs/zerolog" - "github.com/rs/zerolog/log" - ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" -) - -const ( - // DefaultTemplateRule The default template for the default rule. - DefaultTemplateRule = "Host(`{{ normalize .Name }}`)" - marathonEventIDs = marathon.EventIDApplications | - marathon.EventIDAddHealthCheck | - marathon.EventIDDeploymentSuccess | - marathon.EventIDDeploymentFailed | - marathon.EventIDDeploymentInfo | - marathon.EventIDDeploymentStepSuccess | - marathon.EventIDDeploymentStepFailed -) - -// TaskState denotes the Mesos state a task can have. -type TaskState string - -const ( - taskStateRunning TaskState = "TASK_RUNNING" - taskStateStaging TaskState = "TASK_STAGING" -) - -var _ provider.Provider = (*Provider)(nil) - -// Provider holds configuration of the provider. -type Provider struct { - Constraints string `description:"Constraints is an expression that Traefik matches against the application's labels to determine whether to create any route for that application." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` - Trace bool `description:"Display additional provider logs." json:"trace,omitempty" toml:"trace,omitempty" yaml:"trace,omitempty" export:"true"` - Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"` - Endpoint string `description:"Marathon server endpoint. You can also specify multiple endpoint for Marathon." json:"endpoint,omitempty" toml:"endpoint,omitempty" yaml:"endpoint,omitempty"` - DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` - ExposedByDefault bool `description:"Expose Marathon apps by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` - DCOSToken string `description:"DCOSToken for DCOS environment, This will override the Authorization header." json:"dcosToken,omitempty" toml:"dcosToken,omitempty" yaml:"dcosToken,omitempty" loggable:"false"` - TLS *types.ClientTLS `description:"Enable TLS support." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"` - DialerTimeout ptypes.Duration `description:"Set a dialer timeout for Marathon." json:"dialerTimeout,omitempty" toml:"dialerTimeout,omitempty" yaml:"dialerTimeout,omitempty" export:"true"` - ResponseHeaderTimeout ptypes.Duration `description:"Set a response header timeout for Marathon." json:"responseHeaderTimeout,omitempty" toml:"responseHeaderTimeout,omitempty" yaml:"responseHeaderTimeout,omitempty" export:"true"` - TLSHandshakeTimeout ptypes.Duration `description:"Set a TLS handshake timeout for Marathon." json:"tlsHandshakeTimeout,omitempty" toml:"tlsHandshakeTimeout,omitempty" yaml:"tlsHandshakeTimeout,omitempty" export:"true"` - KeepAlive ptypes.Duration `description:"Set a TCP Keep Alive time." json:"keepAlive,omitempty" toml:"keepAlive,omitempty" yaml:"keepAlive,omitempty" export:"true"` - ForceTaskHostname bool `description:"Force to use the task's hostname." json:"forceTaskHostname,omitempty" toml:"forceTaskHostname,omitempty" yaml:"forceTaskHostname,omitempty" export:"true"` - Basic *Basic `description:"Enable basic authentication." json:"basic,omitempty" toml:"basic,omitempty" yaml:"basic,omitempty" export:"true"` - RespectReadinessChecks bool `description:"Filter out tasks with non-successful readiness checks during deployments." json:"respectReadinessChecks,omitempty" toml:"respectReadinessChecks,omitempty" yaml:"respectReadinessChecks,omitempty" export:"true"` - readyChecker *readinessChecker - marathonClient marathon.Marathon - defaultRuleTpl *template.Template -} - -// SetDefaults sets the default values. -func (p *Provider) SetDefaults() { - p.Watch = true - p.Endpoint = "http://127.0.0.1:8080" - p.ExposedByDefault = true - p.DialerTimeout = ptypes.Duration(5 * time.Second) - p.ResponseHeaderTimeout = ptypes.Duration(60 * time.Second) - p.TLSHandshakeTimeout = ptypes.Duration(5 * time.Second) - p.KeepAlive = ptypes.Duration(10 * time.Second) - p.DefaultRule = DefaultTemplateRule -} - -// Basic holds basic authentication specific configurations. -type Basic struct { - HTTPBasicAuthUser string `description:"Basic authentication User." json:"httpBasicAuthUser,omitempty" toml:"httpBasicAuthUser,omitempty" yaml:"httpBasicAuthUser,omitempty" loggable:"false"` - HTTPBasicPassword string `description:"Basic authentication Password." json:"httpBasicPassword,omitempty" toml:"httpBasicPassword,omitempty" yaml:"httpBasicPassword,omitempty" loggable:"false"` -} - -// Init the provider. -func (p *Provider) Init() error { - fm := template.FuncMap{ - "strsToItfs": func(values []string) []interface{} { - var r []interface{} - for _, v := range values { - r = append(r, v) - } - return r - }, - } - - defaultRuleTpl, err := provider.MakeDefaultRuleTemplate(p.DefaultRule, fm) - if err != nil { - return fmt.Errorf("error while parsing default rule: %w", err) - } - - p.defaultRuleTpl = defaultRuleTpl - return nil -} - -// Provide allows the marathon provider to provide configurations to traefik -// using the given configuration channel. -func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error { - logger := log.With().Str(logs.ProviderName, "marathon").Logger() - ctx := logger.WithContext(context.Background()) - - operation := func() error { - confg := marathon.NewDefaultConfig() - confg.URL = p.Endpoint - confg.EventsTransport = marathon.EventsTransportSSE - - if p.Trace { - confg.LogOutput = logs.NoLevel(logger, zerolog.DebugLevel) - } - - if p.Basic != nil { - confg.HTTPBasicAuthUser = p.Basic.HTTPBasicAuthUser - confg.HTTPBasicPassword = p.Basic.HTTPBasicPassword - } - var rc *readinessChecker - if p.RespectReadinessChecks { - logger.Debug().Msg("Enabling Marathon readiness checker") - rc = defaultReadinessChecker(p.Trace) - } - p.readyChecker = rc - - if len(p.DCOSToken) > 0 { - confg.DCOSToken = p.DCOSToken - } - TLSConfig, err := p.TLS.CreateTLSConfig(ctx) - if err != nil { - return fmt.Errorf("unable to create client TLS configuration: %w", err) - } - confg.HTTPClient = &http.Client{ - Transport: &http.Transport{ - DialContext: (&net.Dialer{ - KeepAlive: time.Duration(p.KeepAlive), - Timeout: time.Duration(p.DialerTimeout), - }).DialContext, - ResponseHeaderTimeout: time.Duration(p.ResponseHeaderTimeout), - TLSHandshakeTimeout: time.Duration(p.TLSHandshakeTimeout), - TLSClientConfig: TLSConfig, - }, - } - client, err := marathon.NewClient(confg) - if err != nil { - logger.Error().Err(err).Msg("Failed to create a client for marathon") - return err - } - p.marathonClient = client - - if p.Watch { - update, err := client.AddEventsListener(marathonEventIDs) - if err != nil { - logger.Error().Err(err).Msg("Failed to register for events") - return err - } - pool.GoCtx(func(ctxPool context.Context) { - defer close(update) - for { - select { - case <-ctxPool.Done(): - return - case event := <-update: - logger.Debug().Msgf("Received provider event %s", event) - - conf := p.getConfigurations(ctx) - if conf != nil { - configurationChan <- dynamic.Message{ - ProviderName: "marathon", - Configuration: conf, - } - } - } - } - }) - } - - configuration := p.getConfigurations(ctx) - configurationChan <- dynamic.Message{ - ProviderName: "marathon", - Configuration: configuration, - } - return nil - } - - notify := func(err error, time time.Duration) { - logger.Error().Err(err).Msgf("Provider error, retrying in %s", time) - } - err := backoff.RetryNotify(safe.OperationWithRecover(operation), backoff.WithContext(job.NewBackOff(backoff.NewExponentialBackOff()), ctx), notify) - if err != nil { - logger.Error().Err(err).Msg("Cannot retrieve data") - } - return nil -} - -func (p *Provider) getConfigurations(ctx context.Context) *dynamic.Configuration { - applications, err := p.getApplications() - if err != nil { - log.Ctx(ctx).Error().Err(err).Msg("Failed to retrieve Marathon applications") - return nil - } - - return p.buildConfiguration(ctx, applications) -} - -func (p *Provider) getApplications() (*marathon.Applications, error) { - v := url.Values{} - v.Add("embed", "apps.tasks") - v.Add("embed", "apps.deployments") - v.Add("embed", "apps.readiness") - - return p.marathonClient.Applications(v) -} diff --git a/pkg/provider/marathon/mocks/Marathon.go b/pkg/provider/marathon/mocks/Marathon.go deleted file mode 100644 index d2506bc79cf37a9f8743ede0b688a482dda3ca3b..0000000000000000000000000000000000000000 --- a/pkg/provider/marathon/mocks/Marathon.go +++ /dev/null @@ -1,1286 +0,0 @@ -// Package mocks Code generated by mockery v1.0.0. DO NOT EDIT. -// mockery -recursive -dir=vendor/github.com/gambol99/ -name=Marathon -output=provider/marathon/mocks -package mocks - -import ( - "net/url" - "time" - - "github.com/gambol99/go-marathon" - "github.com/stretchr/testify/mock" -) - -// Marathon is an autogenerated mock type for the Marathon type -type Marathon struct { - mock.Mock -} - -// AbdicateLeader provides a mock function with given fields: -func (_m *Marathon) AbdicateLeader() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// AddEventsListener provides a mock function with given fields: filter -func (_m *Marathon) AddEventsListener(filter int) (marathon.EventsChannel, error) { - ret := _m.Called(filter) - - var r0 marathon.EventsChannel - if rf, ok := ret.Get(0).(func(int) marathon.EventsChannel); ok { - r0 = rf(filter) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(marathon.EventsChannel) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(int) error); ok { - r1 = rf(filter) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// AllTasks provides a mock function with given fields: opts -func (_m *Marathon) AllTasks(opts *marathon.AllTasksOpts) (*marathon.Tasks, error) { - ret := _m.Called(opts) - - var r0 *marathon.Tasks - if rf, ok := ret.Get(0).(func(*marathon.AllTasksOpts) *marathon.Tasks); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Tasks) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.AllTasksOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Application provides a mock function with given fields: name -func (_m *Marathon) Application(name string) (*marathon.Application, error) { - ret := _m.Called(name) - - var r0 *marathon.Application - if rf, ok := ret.Get(0).(func(string) *marathon.Application); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Application) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ApplicationBy provides a mock function with given fields: name, opts -func (_m *Marathon) ApplicationBy(name string, opts *marathon.GetAppOpts) (*marathon.Application, error) { - ret := _m.Called(name, opts) - - var r0 *marathon.Application - if rf, ok := ret.Get(0).(func(string, *marathon.GetAppOpts) *marathon.Application); ok { - r0 = rf(name, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Application) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.GetAppOpts) error); ok { - r1 = rf(name, opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ApplicationByVersion provides a mock function with given fields: name, version -func (_m *Marathon) ApplicationByVersion(name, version string) (*marathon.Application, error) { - ret := _m.Called(name, version) - - var r0 *marathon.Application - if rf, ok := ret.Get(0).(func(string, string) *marathon.Application); ok { - r0 = rf(name, version) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Application) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(name, version) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ApplicationDeployments provides a mock function with given fields: name -func (_m *Marathon) ApplicationDeployments(name string) ([]*marathon.DeploymentID, error) { - ret := _m.Called(name) - - var r0 []*marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string) []*marathon.DeploymentID); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ApplicationOK provides a mock function with given fields: name -func (_m *Marathon) ApplicationOK(name string) (bool, error) { - ret := _m.Called(name) - - var r0 bool - if rf, ok := ret.Get(0).(func(string) bool); ok { - r0 = rf(name) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ApplicationVersions provides a mock function with given fields: name -func (_m *Marathon) ApplicationVersions(name string) (*marathon.ApplicationVersions, error) { - ret := _m.Called(name) - - var r0 *marathon.ApplicationVersions - if rf, ok := ret.Get(0).(func(string) *marathon.ApplicationVersions); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.ApplicationVersions) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Applications provides a mock function with given fields: _a0 -func (_m *Marathon) Applications(_a0 url.Values) (*marathon.Applications, error) { - ret := _m.Called(_a0) - - var r0 *marathon.Applications - if rf, ok := ret.Get(0).(func(url.Values) *marathon.Applications); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Applications) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(url.Values) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CreateApplication provides a mock function with given fields: application -func (_m *Marathon) CreateApplication(application *marathon.Application) (*marathon.Application, error) { - ret := _m.Called(application) - - var r0 *marathon.Application - if rf, ok := ret.Get(0).(func(*marathon.Application) *marathon.Application); ok { - r0 = rf(application) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Application) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.Application) error); ok { - r1 = rf(application) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// CreateGroup provides a mock function with given fields: group -func (_m *Marathon) CreateGroup(group *marathon.Group) error { - ret := _m.Called(group) - - var r0 error - if rf, ok := ret.Get(0).(func(*marathon.Group) error); ok { - r0 = rf(group) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// CreatePod provides a mock function with given fields: pod -func (_m *Marathon) CreatePod(pod *marathon.Pod) (*marathon.Pod, error) { - ret := _m.Called(pod) - - var r0 *marathon.Pod - if rf, ok := ret.Get(0).(func(*marathon.Pod) *marathon.Pod); ok { - r0 = rf(pod) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Pod) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.Pod) error); ok { - r1 = rf(pod) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteApplication provides a mock function with given fields: name, force -func (_m *Marathon) DeleteApplication(name string, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(name, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok { - r0 = rf(name, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(name, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteDeployment provides a mock function with given fields: id, force -func (_m *Marathon) DeleteDeployment(id string, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(id, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok { - r0 = rf(id, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(id, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteGroup provides a mock function with given fields: name, force -func (_m *Marathon) DeleteGroup(name string, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(name, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok { - r0 = rf(name, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(name, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeletePod provides a mock function with given fields: name, force -func (_m *Marathon) DeletePod(name string, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(name, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok { - r0 = rf(name, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(name, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeletePodInstance provides a mock function with given fields: name, instance -func (_m *Marathon) DeletePodInstance(name, instance string) (*marathon.PodInstance, error) { - ret := _m.Called(name, instance) - - var r0 *marathon.PodInstance - if rf, ok := ret.Get(0).(func(string, string) *marathon.PodInstance); ok { - r0 = rf(name, instance) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.PodInstance) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(name, instance) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeletePodInstances provides a mock function with given fields: name, instances -func (_m *Marathon) DeletePodInstances(name string, instances []string) ([]*marathon.PodInstance, error) { - ret := _m.Called(name, instances) - - var r0 []*marathon.PodInstance - if rf, ok := ret.Get(0).(func(string, []string) []*marathon.PodInstance); ok { - r0 = rf(name, instances) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*marathon.PodInstance) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, []string) error); ok { - r1 = rf(name, instances) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// DeleteQueueDelay provides a mock function with given fields: appID -func (_m *Marathon) DeleteQueueDelay(appID string) error { - ret := _m.Called(appID) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(appID) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Deployments provides a mock function with given fields: -func (_m *Marathon) Deployments() ([]*marathon.Deployment, error) { - ret := _m.Called() - - var r0 []*marathon.Deployment - if rf, ok := ret.Get(0).(func() []*marathon.Deployment); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*marathon.Deployment) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GetMarathonURL provides a mock function with given fields: -func (_m *Marathon) GetMarathonURL() string { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - return r0 -} - -// Group provides a mock function with given fields: name -func (_m *Marathon) Group(name string) (*marathon.Group, error) { - ret := _m.Called(name) - - var r0 *marathon.Group - if rf, ok := ret.Get(0).(func(string) *marathon.Group); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Group) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GroupBy provides a mock function with given fields: name, opts -func (_m *Marathon) GroupBy(name string, opts *marathon.GetGroupOpts) (*marathon.Group, error) { - ret := _m.Called(name, opts) - - var r0 *marathon.Group - if rf, ok := ret.Get(0).(func(string, *marathon.GetGroupOpts) *marathon.Group); ok { - r0 = rf(name, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Group) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.GetGroupOpts) error); ok { - r1 = rf(name, opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Groups provides a mock function with given fields: -func (_m *Marathon) Groups() (*marathon.Groups, error) { - ret := _m.Called() - - var r0 *marathon.Groups - if rf, ok := ret.Get(0).(func() *marathon.Groups); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Groups) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// GroupsBy provides a mock function with given fields: opts -func (_m *Marathon) GroupsBy(opts *marathon.GetGroupOpts) (*marathon.Groups, error) { - ret := _m.Called(opts) - - var r0 *marathon.Groups - if rf, ok := ret.Get(0).(func(*marathon.GetGroupOpts) *marathon.Groups); ok { - r0 = rf(opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Groups) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.GetGroupOpts) error); ok { - r1 = rf(opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// HasApplicationVersion provides a mock function with given fields: name, version -func (_m *Marathon) HasApplicationVersion(name, version string) (bool, error) { - ret := _m.Called(name, version) - - var r0 bool - if rf, ok := ret.Get(0).(func(string, string) bool); ok { - r0 = rf(name, version) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(name, version) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// HasDeployment provides a mock function with given fields: id -func (_m *Marathon) HasDeployment(id string) (bool, error) { - ret := _m.Called(id) - - var r0 bool - if rf, ok := ret.Get(0).(func(string) bool); ok { - r0 = rf(id) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(id) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// HasGroup provides a mock function with given fields: name -func (_m *Marathon) HasGroup(name string) (bool, error) { - ret := _m.Called(name) - - var r0 bool - if rf, ok := ret.Get(0).(func(string) bool); ok { - r0 = rf(name) - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Info provides a mock function with given fields: -func (_m *Marathon) Info() (*marathon.Info, error) { - ret := _m.Called() - - var r0 *marathon.Info - if rf, ok := ret.Get(0).(func() *marathon.Info); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Info) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// KillApplicationTasks provides a mock function with given fields: applicationID, opts -func (_m *Marathon) KillApplicationTasks(applicationID string, opts *marathon.KillApplicationTasksOpts) (*marathon.Tasks, error) { - ret := _m.Called(applicationID, opts) - - var r0 *marathon.Tasks - if rf, ok := ret.Get(0).(func(string, *marathon.KillApplicationTasksOpts) *marathon.Tasks); ok { - r0 = rf(applicationID, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Tasks) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.KillApplicationTasksOpts) error); ok { - r1 = rf(applicationID, opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// KillTask provides a mock function with given fields: taskID, opts -func (_m *Marathon) KillTask(taskID string, opts *marathon.KillTaskOpts) (*marathon.Task, error) { - ret := _m.Called(taskID, opts) - - var r0 *marathon.Task - if rf, ok := ret.Get(0).(func(string, *marathon.KillTaskOpts) *marathon.Task); ok { - r0 = rf(taskID, opts) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Task) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.KillTaskOpts) error); ok { - r1 = rf(taskID, opts) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// KillTasks provides a mock function with given fields: taskIDs, opts -func (_m *Marathon) KillTasks(taskIDs []string, opts *marathon.KillTaskOpts) error { - ret := _m.Called(taskIDs, opts) - - var r0 error - if rf, ok := ret.Get(0).(func([]string, *marathon.KillTaskOpts) error); ok { - r0 = rf(taskIDs, opts) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Leader provides a mock function with given fields: -func (_m *Marathon) Leader() (string, error) { - ret := _m.Called() - - var r0 string - if rf, ok := ret.Get(0).(func() string); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(string) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ListApplications provides a mock function with given fields: _a0 -func (_m *Marathon) ListApplications(_a0 url.Values) ([]string, error) { - ret := _m.Called(_a0) - - var r0 []string - if rf, ok := ret.Get(0).(func(url.Values) []string); ok { - r0 = rf(_a0) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(url.Values) error); ok { - r1 = rf(_a0) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Ping provides a mock function with given fields: -func (_m *Marathon) Ping() (bool, error) { - ret := _m.Called() - - var r0 bool - if rf, ok := ret.Get(0).(func() bool); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Pod provides a mock function with given fields: name -func (_m *Marathon) Pod(name string) (*marathon.Pod, error) { - ret := _m.Called(name) - - var r0 *marathon.Pod - if rf, ok := ret.Get(0).(func(string) *marathon.Pod); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Pod) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PodByVersion provides a mock function with given fields: name, version -func (_m *Marathon) PodByVersion(name, version string) (*marathon.Pod, error) { - ret := _m.Called(name, version) - - var r0 *marathon.Pod - if rf, ok := ret.Get(0).(func(string, string) *marathon.Pod); ok { - r0 = rf(name, version) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Pod) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, string) error); ok { - r1 = rf(name, version) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PodIsRunning provides a mock function with given fields: name -func (_m *Marathon) PodIsRunning(name string) bool { - ret := _m.Called(name) - - var r0 bool - if rf, ok := ret.Get(0).(func(string) bool); ok { - r0 = rf(name) - } else { - r0 = ret.Get(0).(bool) - } - - return r0 -} - -// PodStatus provides a mock function with given fields: name -func (_m *Marathon) PodStatus(name string) (*marathon.PodStatus, error) { - ret := _m.Called(name) - - var r0 *marathon.PodStatus - if rf, ok := ret.Get(0).(func(string) *marathon.PodStatus); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.PodStatus) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PodStatuses provides a mock function with given fields: -func (_m *Marathon) PodStatuses() ([]*marathon.PodStatus, error) { - ret := _m.Called() - - var r0 []*marathon.PodStatus - if rf, ok := ret.Get(0).(func() []*marathon.PodStatus); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]*marathon.PodStatus) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// PodVersions provides a mock function with given fields: name -func (_m *Marathon) PodVersions(name string) ([]string, error) { - ret := _m.Called(name) - - var r0 []string - if rf, ok := ret.Get(0).(func(string) []string); ok { - r0 = rf(name) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(name) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Pods provides a mock function with given fields: -func (_m *Marathon) Pods() ([]marathon.Pod, error) { - ret := _m.Called() - - var r0 []marathon.Pod - if rf, ok := ret.Get(0).(func() []marathon.Pod); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]marathon.Pod) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Queue provides a mock function with given fields: -func (_m *Marathon) Queue() (*marathon.Queue, error) { - ret := _m.Called() - - var r0 *marathon.Queue - if rf, ok := ret.Get(0).(func() *marathon.Queue); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Queue) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// RemoveEventsListener provides a mock function with given fields: channel -func (_m *Marathon) RemoveEventsListener(channel marathon.EventsChannel) { - _m.Called(channel) -} - -// RestartApplication provides a mock function with given fields: name, force -func (_m *Marathon) RestartApplication(name string, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(name, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, bool) *marathon.DeploymentID); ok { - r0 = rf(name, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, bool) error); ok { - r1 = rf(name, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// ScaleApplicationInstances provides a mock function with given fields: name, instances, force -func (_m *Marathon) ScaleApplicationInstances(name string, instances int, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(name, instances, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, int, bool) *marathon.DeploymentID); ok { - r0 = rf(name, instances, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, int, bool) error); ok { - r1 = rf(name, instances, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// SetApplicationVersion provides a mock function with given fields: name, version -func (_m *Marathon) SetApplicationVersion(name string, version *marathon.ApplicationVersion) (*marathon.DeploymentID, error) { - ret := _m.Called(name, version) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, *marathon.ApplicationVersion) *marathon.DeploymentID); ok { - r0 = rf(name, version) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.ApplicationVersion) error); ok { - r1 = rf(name, version) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Subscribe provides a mock function with given fields: _a0 -func (_m *Marathon) Subscribe(_a0 string) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// Subscriptions provides a mock function with given fields: -func (_m *Marathon) Subscriptions() (*marathon.Subscriptions, error) { - ret := _m.Called() - - var r0 *marathon.Subscriptions - if rf, ok := ret.Get(0).(func() *marathon.Subscriptions); ok { - r0 = rf() - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Subscriptions) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// SupportsPods provides a mock function with given fields: -func (_m *Marathon) SupportsPods() (bool, error) { - ret := _m.Called() - - var r0 bool - if rf, ok := ret.Get(0).(func() bool); ok { - r0 = rf() - } else { - r0 = ret.Get(0).(bool) - } - - var r1 error - if rf, ok := ret.Get(1).(func() error); ok { - r1 = rf() - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// TaskEndpoints provides a mock function with given fields: name, port, healthCheck -func (_m *Marathon) TaskEndpoints(name string, port int, healthCheck bool) ([]string, error) { - ret := _m.Called(name, port, healthCheck) - - var r0 []string - if rf, ok := ret.Get(0).(func(string, int, bool) []string); ok { - r0 = rf(name, port, healthCheck) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]string) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, int, bool) error); ok { - r1 = rf(name, port, healthCheck) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Tasks provides a mock function with given fields: application -func (_m *Marathon) Tasks(application string) (*marathon.Tasks, error) { - ret := _m.Called(application) - - var r0 *marathon.Tasks - if rf, ok := ret.Get(0).(func(string) *marathon.Tasks); ok { - r0 = rf(application) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Tasks) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string) error); ok { - r1 = rf(application) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// Unsubscribe provides a mock function with given fields: _a0 -func (_m *Marathon) Unsubscribe(_a0 string) error { - ret := _m.Called(_a0) - - var r0 error - if rf, ok := ret.Get(0).(func(string) error); ok { - r0 = rf(_a0) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// UpdateApplication provides a mock function with given fields: application, force -func (_m *Marathon) UpdateApplication(application *marathon.Application, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(application, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(*marathon.Application, bool) *marathon.DeploymentID); ok { - r0 = rf(application, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.Application, bool) error); ok { - r1 = rf(application, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// UpdateGroup provides a mock function with given fields: id, group, force -func (_m *Marathon) UpdateGroup(id string, group *marathon.Group, force bool) (*marathon.DeploymentID, error) { - ret := _m.Called(id, group, force) - - var r0 *marathon.DeploymentID - if rf, ok := ret.Get(0).(func(string, *marathon.Group, bool) *marathon.DeploymentID); ok { - r0 = rf(id, group, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.DeploymentID) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(string, *marathon.Group, bool) error); ok { - r1 = rf(id, group, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// UpdatePod provides a mock function with given fields: pod, force -func (_m *Marathon) UpdatePod(pod *marathon.Pod, force bool) (*marathon.Pod, error) { - ret := _m.Called(pod, force) - - var r0 *marathon.Pod - if rf, ok := ret.Get(0).(func(*marathon.Pod, bool) *marathon.Pod); ok { - r0 = rf(pod, force) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*marathon.Pod) - } - } - - var r1 error - if rf, ok := ret.Get(1).(func(*marathon.Pod, bool) error); ok { - r1 = rf(pod, force) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// WaitOnApplication provides a mock function with given fields: name, timeout -func (_m *Marathon) WaitOnApplication(name string, timeout time.Duration) error { - ret := _m.Called(name, timeout) - - var r0 error - if rf, ok := ret.Get(0).(func(string, time.Duration) error); ok { - r0 = rf(name, timeout) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// WaitOnDeployment provides a mock function with given fields: id, timeout -func (_m *Marathon) WaitOnDeployment(id string, timeout time.Duration) error { - ret := _m.Called(id, timeout) - - var r0 error - if rf, ok := ret.Get(0).(func(string, time.Duration) error); ok { - r0 = rf(id, timeout) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// WaitOnGroup provides a mock function with given fields: name, timeout -func (_m *Marathon) WaitOnGroup(name string, timeout time.Duration) error { - ret := _m.Called(name, timeout) - - var r0 error - if rf, ok := ret.Get(0).(func(string, time.Duration) error); ok { - r0 = rf(name, timeout) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// WaitOnPod provides a mock function with given fields: name, timeout -func (_m *Marathon) WaitOnPod(name string, timeout time.Duration) error { - ret := _m.Called(name, timeout) - - var r0 error - if rf, ok := ret.Get(0).(func(string, time.Duration) error); ok { - r0 = rf(name, timeout) - } else { - r0 = ret.Error(0) - } - - return r0 -} diff --git a/pkg/provider/marathon/readiness.go b/pkg/provider/marathon/readiness.go deleted file mode 100644 index 76785df13dbfde9f84085b670ca80c2e465ed830..0000000000000000000000000000000000000000 --- a/pkg/provider/marathon/readiness.go +++ /dev/null @@ -1,122 +0,0 @@ -package marathon - -import ( - "time" - - "github.com/gambol99/go-marathon" - "github.com/rs/zerolog/log" -) - -const ( - // readinessCheckDefaultTimeout is the default timeout for a readiness - // check if no check timeout is specified on the application spec. This - // should really never be the case, but better be safe than sorry. - readinessCheckDefaultTimeout = 10 * time.Second - // readinessCheckSafetyMargin is some buffer duration to account for - // small offsets in readiness check execution. - readinessCheckSafetyMargin = 5 * time.Second - readinessLogHeader = "Marathon readiness check: " -) - -type readinessChecker struct { - checkDefaultTimeout time.Duration - checkSafetyMargin time.Duration - traceLogging bool -} - -func defaultReadinessChecker(isTraceLogging bool) *readinessChecker { - return &readinessChecker{ - checkDefaultTimeout: readinessCheckDefaultTimeout, - checkSafetyMargin: readinessCheckSafetyMargin, - traceLogging: isTraceLogging, - } -} - -func (rc *readinessChecker) Do(task marathon.Task, app marathon.Application) bool { - if rc == nil { - // Readiness checker disabled. - return true - } - - switch { - case len(app.Deployments) == 0: - // We only care about readiness during deployments; post-deployment readiness - // can be covered by a periodic post-deployment probe (i.e., Traefik health checks). - rc.tracef("task %s app %s: ready = true [no deployment ongoing]", task.ID, app.ID) - return true - - case app.ReadinessChecks == nil || len(*app.ReadinessChecks) == 0: - // Applications without configured readiness checks are always considered - // ready. - rc.tracef("task %s app %s: ready = true [no readiness checks on app]", task.ID, app.ID) - return true - } - - // Loop through all readiness check results and return the results for - // matching task IDs. - if app.ReadinessCheckResults != nil { - for _, readinessCheckResult := range *app.ReadinessCheckResults { - if readinessCheckResult.TaskID == task.ID { - rc.tracef("task %s app %s: ready = %t [evaluating readiness check ready state]", task.ID, app.ID, readinessCheckResult.Ready) - return readinessCheckResult.Ready - } - } - } - - // There's a corner case sometimes hit where the first new task of a - // deployment goes from TASK_STAGING to TASK_RUNNING without a corresponding - // readiness check result being included in the API response. This only happens - // in a very short (yet unlucky) time frame and does not repeat for subsequent - // tasks of the same deployment. - // Complicating matters, the situation may occur for both initially deploying - // applications as well as rolling-upgraded ones where one or more tasks from - // a previous deployment exist already and are joined by new tasks from a - // subsequent deployment. We must always make sure that pre-existing tasks - // maintain their ready state while newly launched tasks must be considered - // unready until a check result appears. - // We distinguish the two cases by comparing the current time with the start - // time of the task: It should take Marathon at most one readiness check timeout - // interval (plus some safety margin to account for the delayed nature of - // distributed systems) for readiness check results to be returned along the API - // response. Once the task turns old enough, we assume it to be part of a - // pre-existing deployment and mark it as ready. Note that it is okay to err - // on the side of caution and consider a task unready until the safety time - // window has elapsed because a newly created task should be readiness-checked - // and be given a result fairly shortly after its creation (i.e., on the scale - // of seconds). - readinessCheckTimeoutSecs := (*app.ReadinessChecks)[0].TimeoutSeconds - readinessCheckTimeout := time.Duration(readinessCheckTimeoutSecs) * time.Second - if readinessCheckTimeout == 0 { - rc.tracef("task %s app %s: readiness check timeout not set, using default value %s", task.ID, app.ID, rc.checkDefaultTimeout) - readinessCheckTimeout = rc.checkDefaultTimeout - } else { - readinessCheckTimeout += rc.checkSafetyMargin - } - - startTime, err := time.Parse(time.RFC3339, task.StartedAt) - if err != nil { - // An unparseable start time should never occur; if it does, we assume the - // problem should be surfaced as quickly as possible, which is easiest if - // we shun the task from rotation. - log.Warn().Err(err).Msgf("Failed to parse start-time %s of task %s from application %s (assuming unready)", task.StartedAt, task.ID, app.ID) - return false - } - - since := time.Since(startTime) - if since < readinessCheckTimeout { - rc.tracef("task %s app %s: ready = false [task with start-time %s not within assumed check timeout window of %s (elapsed time since task start: %s)]", task.ID, app.ID, startTime.Format(time.RFC3339), readinessCheckTimeout, since) - return false - } - - // Finally, we can be certain this task is not part of the deployment (i.e., - // it's an old task that's going to transition into the TASK_KILLING and/or - // TASK_KILLED state as new tasks' readiness checks gradually turn green.) - rc.tracef("task %s app %s: ready = true [task with start-time %s not involved in deployment (elapsed time since task start: %s)]", task.ID, app.ID, startTime.Format(time.RFC3339), since) - return true -} - -func (rc *readinessChecker) tracef(format string, args ...interface{}) { - if rc.traceLogging { - log.Debug().Msgf(readinessLogHeader+format, args...) - } -} diff --git a/pkg/provider/marathon/readiness_test.go b/pkg/provider/marathon/readiness_test.go deleted file mode 100644 index 8d61c01c4134adfe9769bc0f96be3b3037d250a1..0000000000000000000000000000000000000000 --- a/pkg/provider/marathon/readiness_test.go +++ /dev/null @@ -1,134 +0,0 @@ -package marathon - -import ( - "testing" - "time" - - "github.com/gambol99/go-marathon" -) - -func testReadinessChecker() *readinessChecker { - return defaultReadinessChecker(false) -} - -func TestDisabledReadinessChecker(t *testing.T) { - var rc *readinessChecker - tsk := task() - app := application( - deployments("deploymentId"), - readinessCheck(0), - readinessCheckResult(testTaskName, false), - ) - - if ready := rc.Do(tsk, app); !ready { - t.Error("expected ready = true") - } -} - -func TestEnabledReadinessChecker(t *testing.T) { - tests := []struct { - desc string - task marathon.Task - app marathon.Application - rc readinessChecker - expectedReady bool - }{ - { - desc: "no deployment running", - task: task(), - app: application(), - expectedReady: true, - }, - { - desc: "no readiness checks defined", - task: task(), - app: application(deployments("deploymentId")), - expectedReady: true, - }, - { - desc: "readiness check result negative", - task: task(), - app: application( - deployments("deploymentId"), - readinessCheck(0), - readinessCheckResult("otherTaskID", true), - readinessCheckResult(testTaskName, false), - ), - expectedReady: false, - }, - { - desc: "readiness check result positive", - task: task(), - app: application( - deployments("deploymentId"), - readinessCheck(0), - readinessCheckResult("otherTaskID", false), - readinessCheckResult(testTaskName, true), - ), - expectedReady: true, - }, - { - desc: "no readiness check result with default timeout", - task: task(startedAtFromNow(3 * time.Minute)), - app: application( - deployments("deploymentId"), - readinessCheck(0), - ), - rc: readinessChecker{ - checkDefaultTimeout: 5 * time.Minute, - }, - expectedReady: false, - }, - { - desc: "no readiness check result with readiness check timeout", - task: task(startedAtFromNow(4 * time.Minute)), - app: application( - deployments("deploymentId"), - readinessCheck(3*time.Minute), - ), - rc: readinessChecker{ - checkSafetyMargin: 3 * time.Minute, - }, - expectedReady: false, - }, - { - desc: "invalid task start time", - task: task(startedAt("invalid")), - app: application( - deployments("deploymentId"), - readinessCheck(0), - ), - expectedReady: false, - }, - { - desc: "task not involved in deployment", - task: task(startedAtFromNow(1 * time.Hour)), - app: application( - deployments("deploymentId"), - readinessCheck(0), - ), - rc: readinessChecker{ - checkDefaultTimeout: 10 * time.Second, - }, - expectedReady: true, - }, - } - - for _, test := range tests { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - rc := testReadinessChecker() - if test.rc.checkDefaultTimeout > 0 { - rc.checkDefaultTimeout = test.rc.checkDefaultTimeout - } - if test.rc.checkSafetyMargin > 0 { - rc.checkSafetyMargin = test.rc.checkSafetyMargin - } - actualReady := test.rc.Do(test.task, test.app) - if actualReady != test.expectedReady { - t.Errorf("actual ready = %t, expected ready = %t", actualReady, test.expectedReady) - } - }) - } -} diff --git a/pkg/provider/nomad/config.go b/pkg/provider/nomad/config.go index a31b8ee21cd95940d87aca059bd812448fe110b6..b6caa8cf1032e09b1ddc82f38b0526284ff4e8a1 100644 --- a/pkg/provider/nomad/config.go +++ b/pkg/provider/nomad/config.go @@ -11,11 +11,11 @@ import ( "strings" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/label" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/constraints" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/label" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/constraints" ) func (p *Provider) buildConfig(ctx context.Context, items []item) *dynamic.Configuration { @@ -89,13 +89,10 @@ func (p *Provider) buildConfig(ctx context.Context, items []item) *dynamic.Confi func (p *Provider) buildTCPConfig(i item, configuration *dynamic.TCPConfiguration) error { if len(configuration.Services) == 0 { - configuration.Services = make(map[string]*dynamic.TCPService) - - lb := new(dynamic.TCPServersLoadBalancer) - lb.SetDefaults() - - configuration.Services[getName(i)] = &dynamic.TCPService{ - LoadBalancer: lb, + configuration.Services = map[string]*dynamic.TCPService{ + getName(i): { + LoadBalancer: new(dynamic.TCPServersLoadBalancer), + }, } } diff --git a/pkg/provider/nomad/config_test.go b/pkg/provider/nomad/config_test.go index 4924849aba1352999512896bec1bdeeafe047650..db7bb3855b8f71327a17ebbe0bb594c28282ace9 100644 --- a/pkg/provider/nomad/config_test.go +++ b/pkg/provider/nomad/config_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func Test_defaultRule(t *testing.T) { @@ -33,9 +33,10 @@ func Test_defaultRule(t *testing.T) { rule: "Host(`example.com`)", expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -86,9 +87,10 @@ func Test_defaultRule(t *testing.T) { rule: `Host("{{ .Name }}.{{ index .Labels "traefik.domain" }}")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -136,9 +138,10 @@ func Test_defaultRule(t *testing.T) { rule: `Host"{{ .Invalid }}")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -181,9 +184,10 @@ func Test_defaultRule(t *testing.T) { rule: defaultTemplateRule, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -254,9 +258,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -311,9 +316,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -387,9 +393,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -449,9 +456,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -508,9 +516,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -562,9 +571,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -615,9 +625,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -666,9 +677,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -718,9 +730,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -771,9 +784,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -840,9 +854,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -897,9 +912,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -944,9 +960,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -998,9 +1015,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1065,9 +1083,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1135,9 +1154,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1199,9 +1219,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1258,9 +1279,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1312,9 +1334,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1364,9 +1387,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1416,9 +1440,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1473,9 +1498,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1504,9 +1530,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1536,9 +1563,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1569,9 +1597,10 @@ func Test_buildConfig(t *testing.T) { constraints: `Tag("traefik.tags=bar")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1602,9 +1631,10 @@ func Test_buildConfig(t *testing.T) { constraints: `Tag("traefik.tags=foo")`, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1654,9 +1684,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1739,10 +1770,10 @@ func Test_buildConfig(t *testing.T) { Address: "127.0.0.1:9999", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1789,10 +1820,10 @@ func Test_buildConfig(t *testing.T) { Address: "127.0.0.1:9999", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1841,9 +1872,10 @@ func Test_buildConfig(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -1879,10 +1911,10 @@ func Test_buildConfig(t *testing.T) { Address: "127.0.0.1:9999", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1932,10 +1964,10 @@ func Test_buildConfig(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -1985,9 +2017,10 @@ func Test_buildConfig(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2048,10 +2081,10 @@ func Test_buildConfig(t *testing.T) { Address: "127.0.0.2:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2139,9 +2172,10 @@ func Test_buildConfig(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{ @@ -2199,10 +2233,10 @@ func Test_buildConfig(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2246,9 +2280,10 @@ func Test_buildConfig(t *testing.T) { }, }, TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, HTTP: &dynamic.HTTPConfiguration{ Routers: map[string]*dynamic.Router{}, @@ -2259,6 +2294,7 @@ func Test_buildConfig(t *testing.T) { }, }, { + // TODO: replace or delete? desc: "tcp with label for tcp service, with termination delay", items: []item{ { @@ -2266,7 +2302,6 @@ func Test_buildConfig(t *testing.T) { Name: "Test", Tags: []string{ "traefik.tcp.services.foo.loadbalancer.server.port = 80", - "traefik.tcp.services.foo.loadbalancer.terminationdelay = 200", }, Address: "127.0.0.1", Port: 80, @@ -2285,10 +2320,10 @@ func Test_buildConfig(t *testing.T) { Address: "127.0.0.1:80", }, }, - TerminationDelay: Int(200), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2335,9 +2370,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2440,7 +2476,6 @@ func Test_buildConfig(t *testing.T) { Servers: []dynamic.TCPServer{ {Address: "127.0.0.1:80"}, }, - TerminationDelay: Int(100), }, }, "Test-8769860286750522282": { @@ -2448,10 +2483,10 @@ func Test_buildConfig(t *testing.T) { Servers: []dynamic.TCPServer{ {Address: "127.0.0.2:80"}, }, - TerminationDelay: Int(100), }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -2501,9 +2536,10 @@ func Test_buildConfig(t *testing.T) { }, expected: &dynamic.Configuration{ TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{ diff --git a/pkg/provider/nomad/nomad.go b/pkg/provider/nomad/nomad.go index 8f12086f6165193227f39e4b8fbae8fe3d7db142..b836707ebb31bac611f7896cda3271596c16a893 100644 --- a/pkg/provider/nomad/nomad.go +++ b/pkg/provider/nomad/nomad.go @@ -12,13 +12,13 @@ import ( "github.com/hashicorp/nomad/api" "github.com/rs/zerolog/log" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/constraints" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/job" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/provider/constraints" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/types" ) const ( @@ -48,6 +48,13 @@ type item struct { ExtraConf configuration // global options } +// configuration contains information from the service's tags that are globals +// (not specific to the dynamic configuration). +type configuration struct { + Enable bool // <prefix>.enable is the corresponding label. + Canary bool // <prefix>.nomad.canary is the corresponding label. +} + // ProviderBuilder is responsible for constructing namespaced instances of the Nomad provider. type ProviderBuilder struct { Configuration `yaml:",inline" export:"true"` @@ -89,13 +96,39 @@ type Configuration struct { // SetDefaults sets the default values for the Nomad Traefik Provider Configuration. func (c *Configuration) SetDefaults() { - c.Endpoint = &EndpointConfig{} + defConfig := api.DefaultConfig() + c.Endpoint = &EndpointConfig{ + Address: defConfig.Address, + Region: defConfig.Region, + Token: defConfig.SecretID, + } + + if defConfig.TLSConfig != nil && (defConfig.TLSConfig.Insecure || defConfig.TLSConfig.CACert != "" || defConfig.TLSConfig.ClientCert != "" || defConfig.TLSConfig.ClientKey != "") { + c.Endpoint.TLS = &types.ClientTLS{ + CA: defConfig.TLSConfig.CACert, + Cert: defConfig.TLSConfig.ClientCert, + Key: defConfig.TLSConfig.ClientKey, + InsecureSkipVerify: defConfig.TLSConfig.Insecure, + } + } + c.Prefix = defaultPrefix c.ExposedByDefault = true c.RefreshInterval = ptypes.Duration(15 * time.Second) c.DefaultRule = defaultTemplateRule } +type EndpointConfig struct { + // Address is the Nomad endpoint address, if empty it defaults to NOMAD_ADDR or "http://127.0.0.1:4646". + Address string `description:"The address of the Nomad server, including scheme and port." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` + // Region is the Nomad region, if empty it defaults to NOMAD_REGION. + Region string `description:"Nomad region to use. If not provided, the local agent region is used." json:"region,omitempty" toml:"region,omitempty" yaml:"region,omitempty"` + // Token is the ACL token to connect with Nomad, if empty it defaults to NOMAD_TOKEN. + Token string `description:"Token is used to provide a per-request ACL token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"` + TLS *types.ClientTLS `description:"Configure TLS." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"` + EndpointWaitTime ptypes.Duration `description:"WaitTime limits how long a Watch will block. If not provided, the agent default values will be used" json:"endpointWaitTime,omitempty" toml:"endpointWaitTime,omitempty" yaml:"endpointWaitTime,omitempty" export:"true"` +} + // Provider holds configuration along with the namespace it will discover services in. type Provider struct { Configuration @@ -106,15 +139,9 @@ type Provider struct { defaultRuleTpl *template.Template // default routing rule } -type EndpointConfig struct { - // Address is the Nomad endpoint address, if empty it defaults to NOMAD_ADDR or "http://localhost:4646". - Address string `description:"The address of the Nomad server, including scheme and port." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` - // Region is the Nomad region, if empty it defaults to NOMAD_REGION or "global". - Region string `description:"Nomad region to use. If not provided, the local agent region is used." json:"region,omitempty" toml:"region,omitempty" yaml:"region,omitempty"` - // Token is the ACL token to connect with Nomad, if empty it defaults to NOMAD_TOKEN. - Token string `description:"Token is used to provide a per-request ACL token." json:"token,omitempty" toml:"token,omitempty" yaml:"token,omitempty" loggable:"false"` - TLS *types.ClientTLS `description:"Configure TLS." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" export:"true"` - EndpointWaitTime ptypes.Duration `description:"WaitTime limits how long a Watch will block. If not provided, the agent default values will be used" json:"endpointWaitTime,omitempty" toml:"endpointWaitTime,omitempty" yaml:"endpointWaitTime,omitempty" export:"true"` +// SetDefaults sets the default values for the Nomad Traefik Provider. +func (p *Provider) SetDefaults() { + p.Configuration.SetDefaults() } // Init the Nomad Traefik Provider. @@ -207,51 +234,6 @@ func (p *Provider) loadConfiguration(ctx context.Context, configurationC chan<- return nil } -func createClient(namespace string, endpoint *EndpointConfig) (*api.Client, error) { - config := api.Config{ - Address: endpoint.Address, - Namespace: namespace, - Region: endpoint.Region, - SecretID: endpoint.Token, - WaitTime: time.Duration(endpoint.EndpointWaitTime), - } - - if endpoint.TLS != nil { - config.TLSConfig = &api.TLSConfig{ - CACert: endpoint.TLS.CA, - ClientCert: endpoint.TLS.Cert, - ClientKey: endpoint.TLS.Key, - Insecure: endpoint.TLS.InsecureSkipVerify, - } - } - - return api.NewClient(&config) -} - -// configuration contains information from the service's tags that are globals -// (not specific to the dynamic configuration). -type configuration struct { - Enable bool // <prefix>.enable is the corresponding label. - Canary bool // <prefix>.nomad.canary is the corresponding label. -} - -// getExtraConf returns a configuration with settings which are not part of the dynamic configuration (e.g. "<prefix>.enable"). -func (p *Provider) getExtraConf(tags []string) configuration { - labels := tagsToLabels(tags, p.Prefix) - - enabled := p.ExposedByDefault - if v, exists := labels["traefik.enable"]; exists { - enabled = strings.EqualFold(v, "true") - } - - var canary bool - if v, exists := labels["traefik.nomad.canary"]; exists { - canary = strings.EqualFold(v, "true") - } - - return configuration{Enable: enabled, Canary: canary} -} - func (p *Provider) getNomadServiceData(ctx context.Context) ([]item, error) { // first, get list of service stubs opts := &api.QueryOptions{AllowStale: p.Stale} @@ -309,6 +291,23 @@ func (p *Provider) getNomadServiceData(ctx context.Context) ([]item, error) { return items, nil } +// getExtraConf returns a configuration with settings which are not part of the dynamic configuration (e.g. "<prefix>.enable"). +func (p *Provider) getExtraConf(tags []string) configuration { + labels := tagsToLabels(tags, p.Prefix) + + enabled := p.ExposedByDefault + if v, exists := labels["traefik.enable"]; exists { + enabled = strings.EqualFold(v, "true") + } + + var canary bool + if v, exists := labels["traefik.nomad.canary"]; exists { + canary = strings.EqualFold(v, "true") + } + + return configuration{Enable: enabled, Canary: canary} +} + // fetchService queries Nomad API for services matching name, // that also have the <prefix>.enable=true set in its tags. func (p *Provider) fetchService(ctx context.Context, name string) ([]*api.ServiceRegistration, error) { @@ -329,3 +328,24 @@ func (p *Provider) fetchService(ctx context.Context, name string) ([]*api.Servic } return services, nil } + +func createClient(namespace string, endpoint *EndpointConfig) (*api.Client, error) { + config := api.Config{ + Address: endpoint.Address, + Namespace: namespace, + Region: endpoint.Region, + SecretID: endpoint.Token, + WaitTime: time.Duration(endpoint.EndpointWaitTime), + } + + if endpoint.TLS != nil { + config.TLSConfig = &api.TLSConfig{ + CACert: endpoint.TLS.CA, + ClientCert: endpoint.TLS.Cert, + ClientKey: endpoint.TLS.Key, + Insecure: endpoint.TLS.InsecureSkipVerify, + } + } + + return api.NewClient(&config) +} diff --git a/pkg/provider/nomad/nomad_test.go b/pkg/provider/nomad/nomad_test.go index b9d2bfa39c98e7a609d4be9ad680f6cde5f5b9b3..b83c7727cdbed939fd8da24df323d15e9d74e74d 100644 --- a/pkg/provider/nomad/nomad_test.go +++ b/pkg/provider/nomad/nomad_test.go @@ -7,7 +7,9 @@ import ( "strings" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/traefik/traefik/v3/pkg/types" ) func Test_globalConfig(t *testing.T) { @@ -76,6 +78,60 @@ func Test_globalConfig(t *testing.T) { } } +func TestProvider_SetDefaults_Endpoint(t *testing.T) { + testCases := []struct { + desc string + envs map[string]string + expected *EndpointConfig + }{ + { + desc: "without env vars", + envs: map[string]string{}, + expected: &EndpointConfig{ + Address: "http://127.0.0.1:4646", + }, + }, + { + desc: "with env vars", + envs: map[string]string{ + "NOMAD_ADDR": "https://nomad.example.com", + "NOMAD_REGION": "us-west", + "NOMAD_TOKEN": "almighty_token", + "NOMAD_CACERT": "/etc/ssl/private/nomad-agent-ca.pem", + "NOMAD_CLIENT_CERT": "/etc/ssl/private/global-client-nomad.pem", + "NOMAD_CLIENT_KEY": "/etc/ssl/private/global-client-nomad-key.pem", + "NOMAD_SKIP_VERIFY": "true", + }, + expected: &EndpointConfig{ + Address: "https://nomad.example.com", + Region: "us-west", + Token: "almighty_token", + TLS: &types.ClientTLS{ + CA: "/etc/ssl/private/nomad-agent-ca.pem", + Cert: "/etc/ssl/private/global-client-nomad.pem", + Key: "/etc/ssl/private/global-client-nomad-key.pem", + InsecureSkipVerify: true, + }, + EndpointWaitTime: 0, + }, + }, + } + + for _, test := range testCases { + test := test + t.Run(test.desc, func(t *testing.T) { + for k, v := range test.envs { + t.Setenv(k, v) + } + + p := &Provider{} + p.SetDefaults() + + assert.Equal(t, test.expected, p.Endpoint) + }) + } +} + func Test_getNomadServiceData(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch { diff --git a/pkg/provider/provider.go b/pkg/provider/provider.go index 70b053055c432c4f4225ec09e18c964cb0854811..2597a05e6991893fe8449c1a1707cb9e4a2c5387 100644 --- a/pkg/provider/provider.go +++ b/pkg/provider/provider.go @@ -1,8 +1,8 @@ package provider import ( - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/safe" ) // Provider defines methods of a provider. diff --git a/pkg/provider/rancher/config.go b/pkg/provider/rancher/config.go deleted file mode 100644 index 1b0d5339d82b2f841c0e150c4757b92c508283ea..0000000000000000000000000000000000000000 --- a/pkg/provider/rancher/config.go +++ /dev/null @@ -1,300 +0,0 @@ -package rancher - -import ( - "context" - "errors" - "fmt" - "net" - "strings" - - "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/label" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/provider/constraints" -) - -func (p *Provider) buildConfiguration(ctx context.Context, services []rancherData) *dynamic.Configuration { - configurations := make(map[string]*dynamic.Configuration) - - for _, service := range services { - logger := log.Ctx(ctx).With().Str("service", service.Name).Logger() - ctxService := logger.WithContext(ctx) - - if !p.keepService(ctx, service) { - continue - } - - confFromLabel, err := label.DecodeConfiguration(service.Labels) - if err != nil { - logger.Error().Err(err).Send() - continue - } - - var tcpOrUDP bool - if len(confFromLabel.TCP.Routers) > 0 || len(confFromLabel.TCP.Services) > 0 { - tcpOrUDP = true - - err := p.buildTCPServiceConfiguration(ctxService, service, confFromLabel.TCP) - if err != nil { - logger.Error().Err(err).Send() - continue - } - provider.BuildTCPRouterConfiguration(ctxService, confFromLabel.TCP) - } - - if len(confFromLabel.UDP.Routers) > 0 || len(confFromLabel.UDP.Services) > 0 { - tcpOrUDP = true - - err := p.buildUDPServiceConfiguration(ctxService, service, confFromLabel.UDP) - if err != nil { - logger.Error().Err(err).Send() - continue - } - provider.BuildUDPRouterConfiguration(ctxService, confFromLabel.UDP) - } - - if tcpOrUDP && len(confFromLabel.HTTP.Routers) == 0 && - len(confFromLabel.HTTP.Middlewares) == 0 && - len(confFromLabel.HTTP.Services) == 0 { - configurations[service.Name] = confFromLabel - continue - } - - err = p.buildServiceConfiguration(ctx, service, confFromLabel.HTTP) - if err != nil { - logger.Error().Err(err).Send() - continue - } - - model := struct { - Name string - Labels map[string]string - }{ - Name: service.Name, - Labels: service.Labels, - } - - provider.BuildRouterConfiguration(ctx, confFromLabel.HTTP, service.Name, p.defaultRuleTpl, model) - - configurations[service.Name] = confFromLabel - } - - return provider.Merge(ctx, configurations) -} - -func (p *Provider) buildTCPServiceConfiguration(ctx context.Context, service rancherData, configuration *dynamic.TCPConfiguration) error { - serviceName := service.Name - - if len(configuration.Services) == 0 { - configuration.Services = make(map[string]*dynamic.TCPService) - lb := &dynamic.TCPServersLoadBalancer{} - lb.SetDefaults() - configuration.Services[serviceName] = &dynamic.TCPService{ - LoadBalancer: lb, - } - } - - for _, confService := range configuration.Services { - err := p.addServerTCP(ctx, service, confService.LoadBalancer) - if err != nil { - return err - } - } - - return nil -} - -func (p *Provider) buildUDPServiceConfiguration(ctx context.Context, service rancherData, configuration *dynamic.UDPConfiguration) error { - serviceName := service.Name - - if len(configuration.Services) == 0 { - configuration.Services = make(map[string]*dynamic.UDPService) - lb := &dynamic.UDPServersLoadBalancer{} - - configuration.Services[serviceName] = &dynamic.UDPService{ - LoadBalancer: lb, - } - } - - for _, confService := range configuration.Services { - err := p.addServerUDP(ctx, service, confService.LoadBalancer) - if err != nil { - return err - } - } - - return nil -} - -func (p *Provider) buildServiceConfiguration(ctx context.Context, service rancherData, configuration *dynamic.HTTPConfiguration) error { - serviceName := service.Name - - if len(configuration.Services) == 0 { - configuration.Services = make(map[string]*dynamic.Service) - lb := &dynamic.ServersLoadBalancer{} - lb.SetDefaults() - configuration.Services[serviceName] = &dynamic.Service{ - LoadBalancer: lb, - } - } - - for _, confService := range configuration.Services { - err := p.addServers(ctx, service, confService.LoadBalancer) - if err != nil { - return err - } - } - - return nil -} - -func (p *Provider) keepService(ctx context.Context, service rancherData) bool { - logger := log.Ctx(ctx) - - if !service.ExtraConf.Enable { - logger.Debug().Msg("Filtering disabled service") - return false - } - - matches, err := constraints.MatchLabels(service.Labels, p.Constraints) - if err != nil { - logger.Error().Err(err).Msg("Error matching constraint expression") - return false - } - if !matches { - logger.Debug().Msgf("Service pruned by constraint expression: %q", p.Constraints) - return false - } - - if p.EnableServiceHealthFilter { - if service.Health != "" && service.Health != healthy && service.Health != updatingHealthy { - logger.Debug().Msgf("Filtering service %s with healthState of %s", service.Name, service.Health) - return false - } - if service.State != "" && service.State != active && service.State != updatingActive && service.State != upgraded && service.State != upgrading { - logger.Debug().Msgf("Filtering service %s with state of %s", service.Name, service.State) - return false - } - } - - return true -} - -func (p *Provider) addServerTCP(ctx context.Context, service rancherData, loadBalancer *dynamic.TCPServersLoadBalancer) error { - log.Ctx(ctx).Debug().Msgf("Trying to add servers for service %s", service.Name) - - if loadBalancer == nil { - return errors.New("load-balancer is not defined") - } - - if len(loadBalancer.Servers) == 0 { - loadBalancer.Servers = []dynamic.TCPServer{{}} - } - - port := loadBalancer.Servers[0].Port - loadBalancer.Servers[0].Port = "" - - if port == "" { - port = getServicePort(service) - } - - if port == "" { - return errors.New("port is missing") - } - - var servers []dynamic.TCPServer - for _, containerIP := range service.Containers { - servers = append(servers, dynamic.TCPServer{ - Address: net.JoinHostPort(containerIP, port), - }) - } - - loadBalancer.Servers = servers - - return nil -} - -func (p *Provider) addServerUDP(ctx context.Context, service rancherData, loadBalancer *dynamic.UDPServersLoadBalancer) error { - log.Ctx(ctx).Debug().Msgf("Trying to add servers for service %s", service.Name) - - if loadBalancer == nil { - return errors.New("load-balancer is not defined") - } - - if len(loadBalancer.Servers) == 0 { - loadBalancer.Servers = []dynamic.UDPServer{{}} - } - - port := loadBalancer.Servers[0].Port - loadBalancer.Servers[0].Port = "" - - if port == "" { - port = getServicePort(service) - } - - if port == "" { - return errors.New("port is missing") - } - - var servers []dynamic.UDPServer - for _, containerIP := range service.Containers { - servers = append(servers, dynamic.UDPServer{ - Address: net.JoinHostPort(containerIP, port), - }) - } - - loadBalancer.Servers = servers - - return nil -} - -func (p *Provider) addServers(ctx context.Context, service rancherData, loadBalancer *dynamic.ServersLoadBalancer) error { - log.Ctx(ctx).Debug().Msgf("Trying to add servers for service %s", service.Name) - - if loadBalancer == nil { - return errors.New("load-balancer is not defined") - } - - if len(loadBalancer.Servers) == 0 { - server := dynamic.Server{} - server.SetDefaults() - - loadBalancer.Servers = []dynamic.Server{server} - } - - port := loadBalancer.Servers[0].Port - loadBalancer.Servers[0].Port = "" - - if port == "" { - port = getServicePort(service) - } - - if port == "" { - return errors.New("port is missing") - } - - var servers []dynamic.Server - for _, containerIP := range service.Containers { - servers = append(servers, dynamic.Server{ - URL: fmt.Sprintf("%s://%s", loadBalancer.Servers[0].Scheme, net.JoinHostPort(containerIP, port)), - }) - } - - loadBalancer.Servers = servers - - return nil -} - -func getServicePort(data rancherData) string { - rawPort := strings.Split(data.Port, "/")[0] - hostPort := strings.Split(rawPort, ":") - - if len(hostPort) >= 2 { - return hostPort[1] - } - if len(hostPort) > 0 && hostPort[0] != "" { - return hostPort[0] - } - return rawPort -} diff --git a/pkg/provider/rancher/config_test.go b/pkg/provider/rancher/config_test.go deleted file mode 100644 index f1b080ecbdda0febd58afa2fd532161277ed074d..0000000000000000000000000000000000000000 --- a/pkg/provider/rancher/config_test.go +++ /dev/null @@ -1,1188 +0,0 @@ -package rancher - -import ( - "context" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" -) - -func Int(v int) *int { return &v } -func Bool(v bool) *bool { return &v } - -func Test_buildConfiguration(t *testing.T) { - testCases := []struct { - desc string - containers []rancherData - constraints string - expected *dynamic.Configuration - }{ - { - desc: "one service no label", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{}, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two services no label", - containers: []rancherData{ - { - Name: "Test1", - Labels: map[string]string{}, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - { - Name: "Test2", - Labels: map[string]string{}, - Port: "80/tcp", - Containers: []string{"127.0.0.2"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test1": { - Service: "Test1", - Rule: "Host(`Test1.traefik.wtf`)", - }, - "Test2": { - Service: "Test2", - Rule: "Host(`Test2.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "Test2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.2:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "two services no label multiple containers", - containers: []rancherData{ - { - Name: "Test1", - Labels: map[string]string{}, - Port: "80/tcp", - Containers: []string{"127.0.0.1", "127.0.0.2"}, - Health: "", - State: "", - }, - { - Name: "Test2", - Labels: map[string]string{}, - Port: "80/tcp", - Containers: []string{"128.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test1": { - Service: "Test1", - Rule: "Host(`Test1.traefik.wtf`)", - }, - "Test2": { - Service: "Test2", - Rule: "Host(`Test2.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - { - URL: "http://127.0.0.2:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - "Test2": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://128.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service some labels", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.http.services.Service1.loadbalancer.passhostheader": "true", - "traefik.http.routers.Router1.rule": "Host(`foo.com`)", - "traefik.http.routers.Router1.service": "Service1", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Service1", - Rule: "Host(`foo.com`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service which is unhealthy", - containers: []rancherData{ - { - Name: "Test", - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "broken", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service which is upgrading", - containers: []rancherData{ - { - Name: "Test", - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "upgradefailed", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service with rule label and has a host exposed port", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.http.routers.Router1.rule": "Host(`foo.com`)", - }, - Port: "12345:80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Router1": { - Service: "Test", - Rule: "Host(`foo.com`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service with non matching constraints", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.http.routers.Router1.rule": "Host(`foo.com`)", - }, - Port: "12345:80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - constraints: `Label("traefik.tags", "bar")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "one service with matching constraints", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tags": "foo", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - constraints: `Label("traefik.tags", "foo")`, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "Middlewares used in router", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.http.middlewares.Middleware1.basicauth.users": "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/,test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - "traefik.http.routers.Test.middlewares": "Middleware1", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - Middlewares: []string{"Middleware1"}, - }, - }, - Middlewares: map[string]*dynamic.Middleware{ - "Middleware1": { - BasicAuth: &dynamic.BasicAuth{ - Users: []string{ - "test:$apr1$H6uskkkW$IgXLP6ewTrSuBkTrqE8wj/", - "test2:$apr1$d9hr9HBB$4HxwgUir3HP4EsggP/QNo0", - }, - }, - }, - }, - Services: map[string]*dynamic.Service{ - "Test": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "Middlewares used in TCP router", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.routers.Test.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.middlewares.Middleware1.ipallowlist.sourcerange": "foobar, fiibar", - "traefik.tcp.routers.Test.middlewares": "Middleware1", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "Test": { - Service: "Test", - Rule: "HostSNI(`foo.bar`)", - Middlewares: []string{"Middleware1"}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{ - "Middleware1": { - IPAllowList: &dynamic.TCPIPAllowList{ - SourceRange: []string{"foobar", "fiibar"}, - }, - }, - }, - Services: map[string]*dynamic.TCPService{ - "Test": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:80", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "Port in labels", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.http.services.Test.loadbalancer.server.port": "80", - }, - Port: "", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Test", - Rule: "Host(`Test.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Test": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.routers.foo.tls": "true", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "Test", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "Test": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:80", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "udp with label", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.udp.routers.foo.entrypoints": "mydns", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "Test", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "Test": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "127.0.0.1:80", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label without rule", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.routers.foo.tls": "true", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "Test": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:80", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label and port", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "foo", - Rule: "HostSNI(`foo.bar`)", - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:8080", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "udp with label and port", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.udp.routers.foo.entrypoints": "mydns", - "traefik.udp.services.foo.loadbalancer.server.port": "8080", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "foo", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "foo": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "127.0.0.1:8080", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label and port and http service", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.routers.foo.rule": "HostSNI(`foo.bar`)", - "traefik.tcp.routers.foo.tls": "true", - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - "traefik.http.services.Service1.loadbalancer.passhostheader": "true", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1", "127.0.0.2"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{ - "foo": { - Service: "foo", - Rule: "HostSNI(`foo.bar`)", - TLS: &dynamic.RouterTCPTLSConfig{}, - }, - }, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:8080", - }, - { - Address: "127.0.0.2:8080", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Service1", - Rule: "Host(`Test.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - { - URL: "http://127.0.0.2:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "udp with label and port and http service", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.udp.routers.foo.entrypoints": "mydns", - "traefik.udp.services.foo.loadbalancer.server.port": "8080", - "traefik.http.services.Service1.loadbalancer.passhostheader": "true", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1", "127.0.0.2"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{ - "foo": { - Service: "foo", - EntryPoints: []string{"mydns"}, - }, - }, - Services: map[string]*dynamic.UDPService{ - "foo": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "127.0.0.1:8080", - }, - { - Address: "127.0.0.2:8080", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{ - "Test": { - Service: "Service1", - Rule: "Host(`Test.traefik.wtf`)", - }, - }, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{ - "Service1": { - LoadBalancer: &dynamic.ServersLoadBalancer{ - Servers: []dynamic.Server{ - { - URL: "http://127.0.0.1:80", - }, - { - URL: "http://127.0.0.2:80", - }, - }, - PassHostHeader: Bool(true), - ResponseForwarding: &dynamic.ResponseForwarding{ - FlushInterval: ptypes.Duration(100 * time.Millisecond), - }, - }, - }, - }, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label for tcp service", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:8080", - }, - }, - TerminationDelay: Int(100), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "udp with label for tcp service", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.udp.services.foo.loadbalancer.server.port": "8080", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{ - "foo": { - LoadBalancer: &dynamic.UDPServersLoadBalancer{ - Servers: []dynamic.UDPServer{ - { - Address: "127.0.0.1:8080", - }, - }, - }, - }, - }, - }, - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - { - desc: "tcp with label for tcp service, with termination delay", - containers: []rancherData{ - { - Name: "Test", - Labels: map[string]string{ - "traefik.tcp.services.foo.loadbalancer.server.port": "8080", - "traefik.tcp.services.foo.loadbalancer.terminationdelay": "200", - }, - Port: "80/tcp", - Containers: []string{"127.0.0.1"}, - Health: "", - State: "", - }, - }, - expected: &dynamic.Configuration{ - TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{ - "foo": { - LoadBalancer: &dynamic.TCPServersLoadBalancer{ - Servers: []dynamic.TCPServer{ - { - Address: "127.0.0.1:8080", - }, - }, - TerminationDelay: Int(200), - }, - }, - }, - }, - UDP: &dynamic.UDPConfiguration{ - Routers: map[string]*dynamic.UDPRouter{}, - Services: map[string]*dynamic.UDPService{}, - }, - HTTP: &dynamic.HTTPConfiguration{ - Routers: map[string]*dynamic.Router{}, - Middlewares: map[string]*dynamic.Middleware{}, - Services: map[string]*dynamic.Service{}, - ServersTransports: map[string]*dynamic.ServersTransport{}, - }, - }, - }, - } - - for _, test := range testCases { - test := test - - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - p := Provider{ - ExposedByDefault: true, - DefaultRule: "Host(`{{ normalize .Name }}.traefik.wtf`)", - EnableServiceHealthFilter: true, - } - - p.Constraints = test.constraints - - err := p.Init() - require.NoError(t, err) - - for i := 0; i < len(test.containers); i++ { - var err error - test.containers[i].ExtraConf, err = p.getConfiguration(test.containers[i]) - require.NoError(t, err) - } - - configuration := p.buildConfiguration(context.Background(), test.containers) - - assert.Equal(t, test.expected, configuration) - }) - } -} diff --git a/pkg/provider/rancher/label.go b/pkg/provider/rancher/label.go deleted file mode 100644 index 6e90a609809b17d62874b587cde3b813e2e670ed..0000000000000000000000000000000000000000 --- a/pkg/provider/rancher/label.go +++ /dev/null @@ -1,22 +0,0 @@ -package rancher - -import ( - "github.com/traefik/traefik/v2/pkg/config/label" -) - -type configuration struct { - Enable bool -} - -func (p *Provider) getConfiguration(service rancherData) (configuration, error) { - conf := configuration{ - Enable: p.ExposedByDefault, - } - - err := label.Decode(service.Labels, &conf, "traefik.rancher.", "traefik.enable") - if err != nil { - return configuration{}, err - } - - return conf, nil -} diff --git a/pkg/provider/rancher/rancher.go b/pkg/provider/rancher/rancher.go deleted file mode 100644 index 212c6607c648973e2e6554e5c9011f14fdf39311..0000000000000000000000000000000000000000 --- a/pkg/provider/rancher/rancher.go +++ /dev/null @@ -1,232 +0,0 @@ -package rancher - -import ( - "context" - "fmt" - "text/template" - "time" - - "github.com/cenkalti/backoff/v4" - rancher "github.com/rancher/go-rancher-metadata/metadata" - "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/job" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" -) - -const ( - // DefaultTemplateRule The default template for the default rule. - DefaultTemplateRule = "Host(`{{ normalize .Name }}`)" -) - -// Health. -const ( - healthy = "healthy" - updatingHealthy = "updating-healthy" -) - -// States. -const ( - active = "active" - running = "running" - upgraded = "upgraded" - upgrading = "upgrading" - updatingActive = "updating-active" - updatingRunning = "updating-running" -) - -var _ provider.Provider = (*Provider)(nil) - -// Provider holds configurations of the provider. -type Provider struct { - Constraints string `description:"Constraints is an expression that Traefik matches against the container's labels to determine whether to create any route for that container." json:"constraints,omitempty" toml:"constraints,omitempty" yaml:"constraints,omitempty" export:"true"` - Watch bool `description:"Watch provider." json:"watch,omitempty" toml:"watch,omitempty" yaml:"watch,omitempty" export:"true"` - DefaultRule string `description:"Default rule." json:"defaultRule,omitempty" toml:"defaultRule,omitempty" yaml:"defaultRule,omitempty"` - ExposedByDefault bool `description:"Expose containers by default." json:"exposedByDefault,omitempty" toml:"exposedByDefault,omitempty" yaml:"exposedByDefault,omitempty" export:"true"` - EnableServiceHealthFilter bool `description:"Filter services with unhealthy states and inactive states." json:"enableServiceHealthFilter,omitempty" toml:"enableServiceHealthFilter,omitempty" yaml:"enableServiceHealthFilter,omitempty" export:"true"` - RefreshSeconds int `description:"Defines the polling interval in seconds." json:"refreshSeconds,omitempty" toml:"refreshSeconds,omitempty" yaml:"refreshSeconds,omitempty" export:"true"` - IntervalPoll bool `description:"Poll the Rancher metadata service every 'rancher.refreshseconds' (less accurate)." json:"intervalPoll,omitempty" toml:"intervalPoll,omitempty" yaml:"intervalPoll,omitempty" export:"true"` - Prefix string `description:"Prefix used for accessing the Rancher metadata service." json:"prefix,omitempty" toml:"prefix,omitempty" yaml:"prefix,omitempty"` - defaultRuleTpl *template.Template -} - -// SetDefaults sets the default values. -func (p *Provider) SetDefaults() { - p.Watch = true - p.ExposedByDefault = true - p.EnableServiceHealthFilter = true - p.RefreshSeconds = 15 - p.DefaultRule = DefaultTemplateRule - p.Prefix = "latest" -} - -type rancherData struct { - Name string - Labels map[string]string - Containers []string - Health string - State string - Port string - ExtraConf configuration -} - -// Init the provider. -func (p *Provider) Init() error { - defaultRuleTpl, err := provider.MakeDefaultRuleTemplate(p.DefaultRule, nil) - if err != nil { - return fmt.Errorf("error while parsing default rule: %w", err) - } - - p.defaultRuleTpl = defaultRuleTpl - return nil -} - -func (p *Provider) createClient(ctx context.Context) (rancher.Client, error) { - metadataServiceURL := fmt.Sprintf("http://rancher-metadata.rancher.internal/%s", p.Prefix) - client, err := rancher.NewClientAndWait(metadataServiceURL) - if err != nil { - log.Ctx(ctx).Error().Err(err).Msg("Failed to create Rancher metadata service client") - return nil, err - } - - return client, nil -} - -// Provide allows the rancher provider to provide configurations to traefik using the given configuration channel. -func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.Pool) error { - pool.GoCtx(func(routineCtx context.Context) { - logger := log.Ctx(routineCtx).With().Str(logs.ProviderName, "rancher").Logger() - ctxLog := logger.WithContext(routineCtx) - - operation := func() error { - client, err := p.createClient(ctxLog) - if err != nil { - logger.Error().Err(err).Msg("Failed to create the metadata client metadata service") - return err - } - - updateConfiguration := func(_ string) { - stacks, err := client.GetStacks() - if err != nil { - logger.Error().Err(err).Msg("Failed to query Rancher metadata service") - return - } - - rancherData := p.parseMetadataSourcedRancherData(ctxLog, stacks) - - logger.Printf("Received Rancher data %+v", rancherData) - - configuration := p.buildConfiguration(ctxLog, rancherData) - configurationChan <- dynamic.Message{ - ProviderName: "rancher", - Configuration: configuration, - } - } - updateConfiguration("init") - - if p.Watch { - if p.IntervalPoll { - p.intervalPoll(ctxLog, client, updateConfiguration) - } else { - // Long polling should be favored for the most accurate configuration updates. - // Holds the connection until there is either a change in the metadata repository or `p.RefreshSeconds` has elapsed. - client.OnChangeCtx(ctxLog, p.RefreshSeconds, updateConfiguration) - } - } - - return nil - } - - notify := func(err error, time time.Duration) { - logger.Error().Err(err).Msgf("Provider error, retrying in %s", time) - } - err := backoff.RetryNotify(safe.OperationWithRecover(operation), backoff.WithContext(job.NewBackOff(backoff.NewExponentialBackOff()), ctxLog), notify) - if err != nil { - logger.Error().Err(err).Msg("Cannot retrieve data") - } - }) - - return nil -} - -func (p *Provider) intervalPoll(ctx context.Context, client rancher.Client, updateConfiguration func(string)) { - ticker := time.NewTicker(time.Duration(p.RefreshSeconds) * time.Second) - defer ticker.Stop() - - var version string - for { - select { - case <-ticker.C: - newVersion, err := client.GetVersion() - if err != nil { - log.Ctx(ctx).Error().Err(err).Msg("Failed to create Rancher metadata service client") - } else if version != newVersion { - version = newVersion - updateConfiguration(version) - } - case <-ctx.Done(): - return - } - } -} - -func (p *Provider) parseMetadataSourcedRancherData(ctx context.Context, stacks []rancher.Stack) (rancherDataList []rancherData) { - for _, stack := range stacks { - for _, service := range stack.Services { - logger := log.Ctx(ctx).With().Str("stack", stack.Name).Str("service", service.Name).Logger() - ctxSvc := logger.WithContext(ctx) - - servicePort := "" - if len(service.Ports) > 0 { - servicePort = service.Ports[0] - } - for _, port := range service.Ports { - logger.Debug().Msgf("Set Port %s", port) - } - - var containerIPAddresses []string - for _, container := range service.Containers { - if containerFilter(ctxSvc, container.Name, container.HealthState, container.State) { - containerIPAddresses = append(containerIPAddresses, container.PrimaryIp) - } - } - - service := rancherData{ - Name: service.Name + "_" + stack.Name, - State: service.State, - Labels: service.Labels, - Port: servicePort, - Containers: containerIPAddresses, - } - - extraConf, err := p.getConfiguration(service) - if err != nil { - logger.Error().Err(err).Msgf("Skip container %s", service.Name) - continue - } - - service.ExtraConf = extraConf - - rancherDataList = append(rancherDataList, service) - } - } - return rancherDataList -} - -func containerFilter(ctx context.Context, name, healthState, state string) bool { - logger := log.Ctx(ctx) - - if healthState != "" && healthState != healthy && healthState != updatingHealthy { - logger.Debug().Msgf("Filtering container %s with healthState of %s", name, healthState) - return false - } - - if state != "" && state != running && state != updatingRunning && state != upgraded { - logger.Debug().Msgf("Filtering container %s with state of %s", name, state) - return false - } - - return true -} diff --git a/pkg/provider/rest/rest.go b/pkg/provider/rest/rest.go index f375bd1dbc71e0b11e48cc6e5b5f035d1c2a59ea..e0a03bb4be1a8a4d757176cbe4853f17b3bfb6b7 100644 --- a/pkg/provider/rest/rest.go +++ b/pkg/provider/rest/rest.go @@ -7,9 +7,9 @@ import ( "github.com/gorilla/mux" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" "github.com/unrolled/render" ) diff --git a/pkg/provider/tailscale/provider.go b/pkg/provider/tailscale/provider.go index a807dfdcfaf5e361a0b04b27db3173f54a21e722..b0b439b862198a7dd8681d6a1e000a3753e85c1f 100644 --- a/pkg/provider/tailscale/provider.go +++ b/pkg/provider/tailscale/provider.go @@ -11,12 +11,12 @@ import ( "github.com/rs/zerolog/log" "github.com/tailscale/tscert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/muxer/http" - "github.com/traefik/traefik/v2/pkg/muxer/tcp" - "github.com/traefik/traefik/v2/pkg/safe" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/muxer/http" + "github.com/traefik/traefik/v3/pkg/muxer/tcp" + "github.com/traefik/traefik/v3/pkg/safe" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" ) // Provider is the Tailscale certificates provider implementation. It receives diff --git a/pkg/provider/tailscale/provider_test.go b/pkg/provider/tailscale/provider_test.go index 6a7ae0d6f282ed682c6ab8e976353ba3d78d6865..614b42ed306db98be4d7785fb7b4750d5f8003ab 100644 --- a/pkg/provider/tailscale/provider_test.go +++ b/pkg/provider/tailscale/provider_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" ) func TestProvider_findDomains(t *testing.T) { diff --git a/pkg/provider/traefik/internal.go b/pkg/provider/traefik/internal.go index 1e1c23becc4795704c04065f4d4316c47a6efbb1..71a6c321aa0b28e5df856854fd270c489daafd8a 100644 --- a/pkg/provider/traefik/internal.go +++ b/pkg/provider/traefik/internal.go @@ -9,12 +9,12 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/tls" ) const defaultInternalEntryPointName = "traefik" @@ -63,8 +63,9 @@ func (i *Provider) createConfiguration(ctx context.Context) *dynamic.Configurati ServersTransports: make(map[string]*dynamic.ServersTransport), }, TCP: &dynamic.TCPConfiguration{ - Routers: make(map[string]*dynamic.TCPRouter), - Services: make(map[string]*dynamic.TCPService), + Routers: make(map[string]*dynamic.TCPRouter), + Services: make(map[string]*dynamic.TCPService), + ServersTransports: make(map[string]*dynamic.TCPServersTransport), }, TLS: &dynamic.TLSConfiguration{ Stores: make(map[string]tls.Store), @@ -79,6 +80,7 @@ func (i *Provider) createConfiguration(ctx context.Context) *dynamic.Configurati i.entryPointModels(cfg) i.redirection(ctx, cfg) i.serverTransport(cfg) + i.serverTransportTCP(cfg) i.acme(cfg) @@ -340,3 +342,30 @@ func (i *Provider) serverTransport(cfg *dynamic.Configuration) { cfg.HTTP.ServersTransports["default"] = st } + +func (i *Provider) serverTransportTCP(cfg *dynamic.Configuration) { + if i.staticCfg.TCPServersTransport == nil { + return + } + + st := &dynamic.TCPServersTransport{ + DialTimeout: i.staticCfg.TCPServersTransport.DialTimeout, + DialKeepAlive: i.staticCfg.TCPServersTransport.DialKeepAlive, + } + + if i.staticCfg.TCPServersTransport.TLS != nil { + st.TLS = &dynamic.TLSClientConfig{ + InsecureSkipVerify: i.staticCfg.TCPServersTransport.TLS.InsecureSkipVerify, + RootCAs: i.staticCfg.TCPServersTransport.TLS.RootCAs, + } + + if i.staticCfg.TCPServersTransport.TLS.Spiffe != nil { + st.TLS.Spiffe = &dynamic.Spiffe{ + IDs: i.staticCfg.ServersTransport.Spiffe.IDs, + TrustDomain: i.staticCfg.ServersTransport.Spiffe.TrustDomain, + } + } + } + + cfg.TCP.ServersTransports["default"] = st +} diff --git a/pkg/provider/traefik/internal_test.go b/pkg/provider/traefik/internal_test.go index 1e7d5b282bb600bfa5661e9859934a64510c0eac..915bbf6b684406645429e6429823b0f7ae9aaa16 100644 --- a/pkg/provider/traefik/internal_test.go +++ b/pkg/provider/traefik/internal_test.go @@ -10,10 +10,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/ping" - "github.com/traefik/traefik/v2/pkg/provider/rest" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/ping" + "github.com/traefik/traefik/v3/pkg/provider/rest" + "github.com/traefik/traefik/v3/pkg/types" ) var updateExpected = flag.Bool("update_expected", false, "Update expected files in fixtures") diff --git a/pkg/redactor/redactor.go b/pkg/redactor/redactor.go index c122e307cfb1ccede2398f258ce1483445cb93a6..fc8a9dd14aa5bfd86e120435738c674350d3e287 100644 --- a/pkg/redactor/redactor.go +++ b/pkg/redactor/redactor.go @@ -7,8 +7,8 @@ import ( "regexp" "github.com/mitchellh/copystructure" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/tls" "mvdan.cc/xurls/v2" ) diff --git a/pkg/redactor/redactor_config_test.go b/pkg/redactor/redactor_config_test.go index beb7ed5b15cb376ce8cf1eb23e54107303be28de..c8836d2d0a278ba3536ee404509259e3d0e04542 100644 --- a/pkg/redactor/redactor_config_test.go +++ b/pkg/redactor/redactor_config_test.go @@ -10,38 +10,36 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/ping" - "github.com/traefik/traefik/v2/pkg/plugins" - "github.com/traefik/traefik/v2/pkg/provider/acme" - "github.com/traefik/traefik/v2/pkg/provider/consulcatalog" - "github.com/traefik/traefik/v2/pkg/provider/docker" - "github.com/traefik/traefik/v2/pkg/provider/ecs" - "github.com/traefik/traefik/v2/pkg/provider/file" - "github.com/traefik/traefik/v2/pkg/provider/http" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/gateway" - "github.com/traefik/traefik/v2/pkg/provider/kubernetes/ingress" - "github.com/traefik/traefik/v2/pkg/provider/kv" - "github.com/traefik/traefik/v2/pkg/provider/kv/consul" - "github.com/traefik/traefik/v2/pkg/provider/kv/etcd" - "github.com/traefik/traefik/v2/pkg/provider/kv/redis" - "github.com/traefik/traefik/v2/pkg/provider/kv/zk" - "github.com/traefik/traefik/v2/pkg/provider/marathon" - "github.com/traefik/traefik/v2/pkg/provider/rancher" - "github.com/traefik/traefik/v2/pkg/provider/rest" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/tracing/datadog" - "github.com/traefik/traefik/v2/pkg/tracing/elastic" - "github.com/traefik/traefik/v2/pkg/tracing/haystack" - "github.com/traefik/traefik/v2/pkg/tracing/instana" - "github.com/traefik/traefik/v2/pkg/tracing/jaeger" - "github.com/traefik/traefik/v2/pkg/tracing/zipkin" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/ping" + "github.com/traefik/traefik/v3/pkg/plugins" + "github.com/traefik/traefik/v3/pkg/provider/acme" + "github.com/traefik/traefik/v3/pkg/provider/consulcatalog" + "github.com/traefik/traefik/v3/pkg/provider/docker" + "github.com/traefik/traefik/v3/pkg/provider/ecs" + "github.com/traefik/traefik/v3/pkg/provider/file" + "github.com/traefik/traefik/v3/pkg/provider/http" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/crd" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/gateway" + "github.com/traefik/traefik/v3/pkg/provider/kubernetes/ingress" + "github.com/traefik/traefik/v3/pkg/provider/kv" + "github.com/traefik/traefik/v3/pkg/provider/kv/consul" + "github.com/traefik/traefik/v3/pkg/provider/kv/etcd" + "github.com/traefik/traefik/v3/pkg/provider/kv/redis" + "github.com/traefik/traefik/v3/pkg/provider/kv/zk" + "github.com/traefik/traefik/v3/pkg/provider/rest" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/tracing/datadog" + "github.com/traefik/traefik/v3/pkg/tracing/elastic" + "github.com/traefik/traefik/v3/pkg/tracing/haystack" + "github.com/traefik/traefik/v3/pkg/tracing/instana" + "github.com/traefik/traefik/v3/pkg/tracing/jaeger" + "github.com/traefik/traefik/v3/pkg/tracing/zipkin" + "github.com/traefik/traefik/v3/pkg/types" ) -var updateExpected = flag.Bool("update_expected", false, "Update expected files in fixtures") +var updateExpected = flag.Bool("update_expected", true, "Update expected files in fixtures") var fullDynConf *dynamic.Configuration @@ -370,7 +368,6 @@ func init() { Services: map[string]*dynamic.TCPService{ "foo": { LoadBalancer: &dynamic.TCPServersLoadBalancer{ - TerminationDelay: intPtr(42), ProxyProtocol: &dynamic.ProxyProtocol{ Version: 42, }, @@ -379,6 +376,7 @@ func init() { Address: "127.0.0.1:8080", }, }, + ServersTransport: "foo", }, }, "bar": { @@ -392,6 +390,24 @@ func init() { }, }, }, + ServersTransports: map[string]*dynamic.TCPServersTransport{ + "foo": { + TLS: &dynamic.TLSClientConfig{ + ServerName: "foo", + InsecureSkipVerify: true, + RootCAs: []traefiktls.FileOrContent{"rootca.pem"}, + Certificates: []traefiktls.Certificate{ + { + CertFile: "cert.pem", + KeyFile: "key.pem", + }, + }, + }, + DialTimeout: 42, + DialKeepAlive: 42, + TerminationDelay: 42, + }, + }, } config.UDP = &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{ @@ -500,17 +516,6 @@ func TestDo_staticConfiguration(t *testing.T) { SendAnonymousUsage: true, } - config.ServersTransport = &static.ServersTransport{ - InsecureSkipVerify: true, - RootCAs: []traefiktls.FileOrContent{"root.ca"}, - MaxIdleConnsPerHost: 42, - ForwardingTimeouts: &static.ForwardingTimeouts{ - DialTimeout: 42, - ResponseHeaderTimeout: 42, - IdleConnTimeout: 42, - }, - } - config.EntryPoints = static.EntryPoints{ "foobar": { Address: "foo Address", @@ -569,6 +574,15 @@ func TestDo_staticConfiguration(t *testing.T) { }, } + config.TCPServersTransport = &static.TCPServersTransport{ + DialTimeout: ptypes.Duration(111 * time.Second), + DialKeepAlive: ptypes.Duration(111 * time.Second), + TLS: &static.TLSClientConfig{ + InsecureSkipVerify: true, + RootCAs: []traefiktls.FileOrContent{"RootCAs 1", "RootCAs 2", "RootCAs 3"}, + }, + } + config.Providers.File = &file.Provider{ Directory: "file Directory", Watch: true, @@ -595,32 +609,6 @@ func TestDo_staticConfiguration(t *testing.T) { HTTPClientTimeout: 42, } - config.Providers.Marathon = &marathon.Provider{ - Constraints: `Label("foo", "bar")`, - Trace: true, - Watch: true, - Endpoint: "foobar", - DefaultRule: "PathPrefix(`/`)", - ExposedByDefault: true, - DCOSToken: "foobar", - TLS: &types.ClientTLS{ - CA: "myCa", - Cert: "mycert.pem", - Key: "mycert.key", - InsecureSkipVerify: true, - }, - DialerTimeout: 42, - ResponseHeaderTimeout: 42, - TLSHandshakeTimeout: 42, - KeepAlive: 42, - ForceTaskHostname: true, - Basic: &marathon.Basic{ - HTTPBasicAuthUser: "user", - HTTPBasicPassword: "password", - }, - RespectReadinessChecks: true, - } - config.Providers.KubernetesIngress = &ingress.Provider{ Endpoint: "MyEndpoint", Token: "MyToken", @@ -659,17 +647,6 @@ func TestDo_staticConfiguration(t *testing.T) { Insecure: true, } - config.Providers.Rancher = &rancher.Provider{ - Constraints: `Label("foo", "bar")`, - Watch: true, - DefaultRule: "PathPrefix(`/`)", - ExposedByDefault: true, - EnableServiceHealthFilter: true, - RefreshSeconds: 42, - IntervalPoll: true, - Prefix: "MyPrefix", - } - config.Providers.ConsulCatalog = &consulcatalog.ProviderBuilder{ Configuration: consulcatalog.Configuration{ Constraints: `Label("foo", "bar")`, @@ -807,17 +784,6 @@ func TestDo_staticConfiguration(t *testing.T) { AddServicesLabels: true, Prefix: "MyPrefix", }, - InfluxDB: &types.InfluxDB{ - Address: "localhost:8183", - Protocol: "http", - PushInterval: 42, - Database: "myDB", - RetentionPolicy: "12", - Username: "a", - Password: "aaaa", - AddEntryPointsLabels: true, - AddServicesLabels: true, - }, } config.Ping = &ping.Handler{ @@ -885,6 +851,7 @@ func TestDo_staticConfiguration(t *testing.T) { }, Datadog: &datadog.Config{ LocalAgentHostPort: "foobar", + LocalAgentSocket: "foobar", GlobalTags: map[string]string{"foobar": "foobar"}, Debug: true, PrioritySampling: true, diff --git a/pkg/redactor/testdata/anonymized-dynamic-config.json b/pkg/redactor/testdata/anonymized-dynamic-config.json index f5ce9308f0a892bb7bdbee11d60358063907186c..b4afd7aa1bac0a5ea71ab7a322d48deab6d51c92 100644 --- a/pkg/redactor/testdata/anonymized-dynamic-config.json +++ b/pkg/redactor/testdata/anonymized-dynamic-config.json @@ -389,7 +389,6 @@ }, "foo": { "loadBalancer": { - "terminationDelay": 42, "proxyProtocol": { "version": 42 }, @@ -397,6 +396,27 @@ { "address": "xxxx" } + ], + "serversTransport": "foo" + } + } + }, + "serversTransports": { + "foo": { + "dialKeepAlive": "42ns", + "dialTimeout": "42ns", + "terminationDelay": "42ns", + "tls": { + "serverName": "xxxx", + "insecureSkipVerify": true, + "rootCAs": [ + "xxxx" + ], + "certificates": [ + { + "certFile": "xxxx", + "keyFile": "xxxx" + } ] } } @@ -466,4 +486,4 @@ } } } -} +} \ No newline at end of file diff --git a/pkg/redactor/testdata/anonymized-static-config.json b/pkg/redactor/testdata/anonymized-static-config.json index a2e3ba0be20a84af5626c32a7ae6a09a450453e3..0097aa2c29fea3ac785f6c8e983154db98404fac 100644 --- a/pkg/redactor/testdata/anonymized-static-config.json +++ b/pkg/redactor/testdata/anonymized-static-config.json @@ -17,6 +17,18 @@ "idleConnTimeout": "1m51s" } }, + "tcpServersTransport": { + "dialKeepAlive": "1m51s", + "dialTimeout": "1m51s", + "tls": { + "insecureSkipVerify": true, + "rootCAs": [ + "xxxx", + "xxxx", + "xxxx" + ] + } + }, "entryPoints": { "foobar": { "address": "xxxx", @@ -100,31 +112,6 @@ "filename": "file Filename", "debugLogGeneratedTemplate": true }, - "marathon": { - "constraints": "Label(\"foo\", \"bar\")", - "trace": true, - "watch": true, - "endpoint": "xxxx", - "defaultRule": "xxxx", - "exposedByDefault": true, - "dcosToken": "xxxx", - "tls": { - "ca": "xxxx", - "cert": "xxxx", - "key": "xxxx", - "insecureSkipVerify": true - }, - "dialerTimeout": "42ns", - "responseHeaderTimeout": "42ns", - "tlsHandshakeTimeout": "42ns", - "keepAlive": "42ns", - "forceTaskHostname": true, - "basic": { - "httpBasicAuthUser": "xxxx", - "httpBasicPassword": "xxxx" - }, - "respectReadinessChecks": true - }, "kubernetesIngress": { "endpoint": "xxxx", "token": "xxxx", @@ -168,16 +155,6 @@ "rest": { "insecure": true }, - "rancher": { - "constraints": "Label(\"foo\", \"bar\")", - "watch": true, - "defaultRule": "xxxx", - "exposedByDefault": true, - "enableServiceHealthFilter": true, - "refreshSeconds": 42, - "intervalPoll": true, - "prefix": "xxxx" - }, "consulCatalog": { "constraints": "Label(\"foo\", \"bar\")", "endpoint": { @@ -307,17 +284,6 @@ "addEntryPointsLabels": true, "addServicesLabels": true, "prefix": "MyPrefix" - }, - "influxDB": { - "address": "xxxx", - "protocol": "xxxx", - "pushInterval": "42ns", - "database": "myDB", - "retentionPolicy": "12", - "username": "xxxx", - "password": "xxxx", - "addEntryPointsLabels": true, - "addServicesLabels": true } }, "ping": { @@ -385,6 +351,7 @@ }, "datadog": { "localAgentHostPort": "xxxx", + "localAgentSocket": "xxxx", "globalTags": { "foobar": "foobar" }, diff --git a/pkg/redactor/testdata/example.json b/pkg/redactor/testdata/example.json index 0d12d63d9c7597c8e422b86a53da45244b24edf7..3dd94d238f7aed4f5317a19ea0630653211fb46c 100644 --- a/pkg/redactor/testdata/example.json +++ b/pkg/redactor/testdata/example.json @@ -65,7 +65,6 @@ "Docker": null, "File": null, "Web": null, - "Marathon": null, "Consul": null, "ConsulCatalog": null, "Etcd": null, @@ -73,10 +72,8 @@ "Boltdb": null, "KubernetesIngress": null, "KubernetesCRD": null, - "Mesos": null, "Eureka": null, "ECS": null, - "Rancher": null, "DynamoDB": null, "ConfigFile": "/etc/traefik/traefik.toml" } diff --git a/pkg/redactor/testdata/expected.json b/pkg/redactor/testdata/expected.json index 7319a7f1a2e6e0f3243177c81df25489bcac2c5c..5849375f8fea4aee421a6d3add90639c733be4e7 100644 --- a/pkg/redactor/testdata/expected.json +++ b/pkg/redactor/testdata/expected.json @@ -65,7 +65,6 @@ "Docker": null, "File": null, "Web": null, - "Marathon": null, "Consul": null, "ConsulCatalog": null, "Etcd": null, @@ -73,10 +72,8 @@ "Boltdb": null, "KubernetesIngress": null, "KubernetesCRD": null, - "Mesos": null, "Eureka": null, "ECS": null, - "Rancher": null, "DynamoDB": null, "ConfigFile": "/etc/traefik/traefik.toml" } diff --git a/pkg/redactor/testdata/secured-dynamic-config.json b/pkg/redactor/testdata/secured-dynamic-config.json index 05efe14205debfe34fba3ee3200b1b7b12f3c3b6..8ff3d078958b211c6bfd68dfbebbf1399c4ac94f 100644 --- a/pkg/redactor/testdata/secured-dynamic-config.json +++ b/pkg/redactor/testdata/secured-dynamic-config.json @@ -392,7 +392,6 @@ }, "foo": { "loadBalancer": { - "terminationDelay": 42, "proxyProtocol": { "version": 42 }, @@ -400,6 +399,27 @@ { "address": "127.0.0.1:8080" } + ], + "serversTransport": "foo" + } + } + }, + "serversTransports": { + "foo": { + "dialKeepAlive": "42ns", + "dialTimeout": "42ns", + "terminationDelay": "42ns", + "tls": { + "serverName": "foo", + "insecureSkipVerify": true, + "rootCAs": [ + "rootca.pem" + ], + "certificates": [ + { + "certFile": "cert.pem", + "keyFile": "xxxx" + } ] } } @@ -474,4 +494,4 @@ } } } -} +} \ No newline at end of file diff --git a/pkg/server/aggregator.go b/pkg/server/aggregator.go index ecf332b1f93d74b03cfb4301d9cbc2c7853a8259..bd4fda0f59f61cc3cbcf1ed6c6dad1abdce27127 100644 --- a/pkg/server/aggregator.go +++ b/pkg/server/aggregator.go @@ -3,10 +3,10 @@ package server import ( "github.com/go-acme/lego/v4/challenge/tlsalpn01" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/server/provider" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/tls" ) func mergeConfiguration(configurations dynamic.Configurations, defaultEntryPoints []string) dynamic.Configuration { @@ -21,9 +21,10 @@ func mergeConfiguration(configurations dynamic.Configurations, defaultEntryPoint ServersTransports: make(map[string]*dynamic.ServersTransport), }, TCP: &dynamic.TCPConfiguration{ - Routers: make(map[string]*dynamic.TCPRouter), - Services: make(map[string]*dynamic.TCPService), - Middlewares: make(map[string]*dynamic.TCPMiddleware), + Routers: make(map[string]*dynamic.TCPRouter), + Services: make(map[string]*dynamic.TCPService), + Middlewares: make(map[string]*dynamic.TCPMiddleware), + ServersTransports: make(map[string]*dynamic.TCPServersTransport), }, UDP: &dynamic.UDPConfiguration{ Routers: make(map[string]*dynamic.UDPRouter), @@ -80,6 +81,9 @@ func mergeConfiguration(configurations dynamic.Configurations, defaultEntryPoint for serviceName, service := range configuration.TCP.Services { conf.TCP.Services[provider.MakeQualifiedName(pvd, serviceName)] = service } + for serversTransportName, serversTransport := range configuration.TCP.ServersTransports { + conf.TCP.ServersTransports[provider.MakeQualifiedName(pvd, serversTransportName)] = serversTransport + } } if configuration.UDP != nil { diff --git a/pkg/server/aggregator_test.go b/pkg/server/aggregator_test.go index cc45578961e0dda2fcd617b8d45b9340e0bbafe8..ea1fb639f498b14cbededccef677cfe4170efda0 100644 --- a/pkg/server/aggregator_test.go +++ b/pkg/server/aggregator_test.go @@ -5,8 +5,8 @@ import ( "github.com/go-acme/lego/v4/challenge/tlsalpn01" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/tls" ) func Test_mergeConfiguration(t *testing.T) { @@ -473,6 +473,7 @@ func Test_mergeConfiguration_defaultTCPEntryPoint(t *testing.T) { Services: map[string]*dynamic.TCPService{ "service-1@provider-1": {}, }, + ServersTransports: make(map[string]*dynamic.TCPServersTransport), } actual := mergeConfiguration(given, []string{"defaultEP"}) diff --git a/pkg/server/configurationwatcher.go b/pkg/server/configurationwatcher.go index 64446ef95e12e7506a628775c366334a70262b59..da2d66f170f9b89b81b276e7aa3564a2ffdb231d 100644 --- a/pkg/server/configurationwatcher.go +++ b/pkg/server/configurationwatcher.go @@ -7,11 +7,11 @@ import ( "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/provider" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/provider" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/tls" ) // ConfigurationWatcher watches configuration changes. @@ -209,6 +209,15 @@ func logConfiguration(logger zerolog.Logger, configMsg dynamic.Message) { } } + if copyConf.TCP != nil { + for _, transport := range copyConf.TCP.ServersTransports { + if transport.TLS != nil { + transport.TLS.Certificates = tls.Certificates{} + transport.TLS.RootCAs = []tls.FileOrContent{} + } + } + } + jsonConf, err := json.Marshal(copyConf) if err != nil { logger.Error().Err(err).Msg("Could not marshal dynamic configuration") diff --git a/pkg/server/configurationwatcher_test.go b/pkg/server/configurationwatcher_test.go index da8d39c4d486441c30b840e031c42e1fb18c856e..d22cb9538f2733ead65a4e2da4aa585726971de7 100644 --- a/pkg/server/configurationwatcher_test.go +++ b/pkg/server/configurationwatcher_test.go @@ -9,11 +9,11 @@ import ( "time" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/provider/aggregator" - "github.com/traefik/traefik/v2/pkg/safe" - th "github.com/traefik/traefik/v2/pkg/testhelpers" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/provider/aggregator" + "github.com/traefik/traefik/v3/pkg/safe" + th "github.com/traefik/traefik/v3/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/tls" ) type mockProvider struct { @@ -89,9 +89,10 @@ func TestNewConfigurationWatcher(t *testing.T) { th.WithLoadBalancerServices(), ), TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{ Options: map[string]tls.Options{ @@ -224,9 +225,10 @@ func TestIgnoreTransientConfiguration(t *testing.T) { th.WithMiddlewares(), ), TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -392,9 +394,10 @@ func TestListenProvidersDoesNotSkipFlappingConfiguration(t *testing.T) { th.WithMiddlewares(), ), TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -481,9 +484,10 @@ func TestListenProvidersIgnoreSameConfig(t *testing.T) { th.WithMiddlewares(), ), TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -615,9 +619,10 @@ func TestListenProvidersIgnoreIntermediateConfigs(t *testing.T) { th.WithMiddlewares(), ), TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, UDP: &dynamic.UDPConfiguration{ Routers: map[string]*dynamic.UDPRouter{}, @@ -682,9 +687,10 @@ func TestListenProvidersPublishesConfigForEachProvider(t *testing.T) { th.WithMiddlewares(), ), TCP: &dynamic.TCPConfiguration{ - Routers: map[string]*dynamic.TCPRouter{}, - Middlewares: map[string]*dynamic.TCPMiddleware{}, - Services: map[string]*dynamic.TCPService{}, + Routers: map[string]*dynamic.TCPRouter{}, + Middlewares: map[string]*dynamic.TCPMiddleware{}, + Services: map[string]*dynamic.TCPService{}, + ServersTransports: map[string]*dynamic.TCPServersTransport{}, }, TLS: &dynamic.TLSConfiguration{ Options: map[string]tls.Options{ diff --git a/pkg/server/middleware/chainbuilder.go b/pkg/server/middleware/chainbuilder.go index 57d8385c5aa1e32919749164b828d14a6d878733..864e7e68b4e1df2c447a4252f72bebe3daedc1b1 100644 --- a/pkg/server/middleware/chainbuilder.go +++ b/pkg/server/middleware/chainbuilder.go @@ -5,12 +5,12 @@ import ( "github.com/containous/alice" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/metrics" - "github.com/traefik/traefik/v2/pkg/middlewares/accesslog" - "github.com/traefik/traefik/v2/pkg/middlewares/capture" - metricsmiddleware "github.com/traefik/traefik/v2/pkg/middlewares/metrics" - mTracing "github.com/traefik/traefik/v2/pkg/middlewares/tracing" - "github.com/traefik/traefik/v2/pkg/tracing" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/middlewares/accesslog" + "github.com/traefik/traefik/v3/pkg/middlewares/capture" + metricsmiddleware "github.com/traefik/traefik/v3/pkg/middlewares/metrics" + mTracing "github.com/traefik/traefik/v3/pkg/middlewares/tracing" + "github.com/traefik/traefik/v3/pkg/tracing" ) // ChainBuilder Creates a middleware chain by entry point. It is used for middlewares that are created almost systematically and that need to be created before all others. diff --git a/pkg/server/middleware/middlewares.go b/pkg/server/middleware/middlewares.go index 6d1790838e97bb07a30d9844dc0971284b05c3ea..0d1bfcfa8d01c9a9ef60576783c001c88ee97580 100644 --- a/pkg/server/middleware/middlewares.go +++ b/pkg/server/middleware/middlewares.go @@ -9,29 +9,29 @@ import ( "strings" "github.com/containous/alice" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/middlewares/addprefix" - "github.com/traefik/traefik/v2/pkg/middlewares/auth" - "github.com/traefik/traefik/v2/pkg/middlewares/buffering" - "github.com/traefik/traefik/v2/pkg/middlewares/chain" - "github.com/traefik/traefik/v2/pkg/middlewares/circuitbreaker" - "github.com/traefik/traefik/v2/pkg/middlewares/compress" - "github.com/traefik/traefik/v2/pkg/middlewares/contenttype" - "github.com/traefik/traefik/v2/pkg/middlewares/customerrors" - "github.com/traefik/traefik/v2/pkg/middlewares/grpcweb" - "github.com/traefik/traefik/v2/pkg/middlewares/headers" - "github.com/traefik/traefik/v2/pkg/middlewares/inflightreq" - "github.com/traefik/traefik/v2/pkg/middlewares/ipallowlist" - "github.com/traefik/traefik/v2/pkg/middlewares/passtlsclientcert" - "github.com/traefik/traefik/v2/pkg/middlewares/ratelimiter" - "github.com/traefik/traefik/v2/pkg/middlewares/redirect" - "github.com/traefik/traefik/v2/pkg/middlewares/replacepath" - "github.com/traefik/traefik/v2/pkg/middlewares/replacepathregex" - "github.com/traefik/traefik/v2/pkg/middlewares/retry" - "github.com/traefik/traefik/v2/pkg/middlewares/stripprefix" - "github.com/traefik/traefik/v2/pkg/middlewares/stripprefixregex" - "github.com/traefik/traefik/v2/pkg/middlewares/tracing" - "github.com/traefik/traefik/v2/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/middlewares/addprefix" + "github.com/traefik/traefik/v3/pkg/middlewares/auth" + "github.com/traefik/traefik/v3/pkg/middlewares/buffering" + "github.com/traefik/traefik/v3/pkg/middlewares/chain" + "github.com/traefik/traefik/v3/pkg/middlewares/circuitbreaker" + "github.com/traefik/traefik/v3/pkg/middlewares/compress" + "github.com/traefik/traefik/v3/pkg/middlewares/contenttype" + "github.com/traefik/traefik/v3/pkg/middlewares/customerrors" + "github.com/traefik/traefik/v3/pkg/middlewares/grpcweb" + "github.com/traefik/traefik/v3/pkg/middlewares/headers" + "github.com/traefik/traefik/v3/pkg/middlewares/inflightreq" + "github.com/traefik/traefik/v3/pkg/middlewares/ipallowlist" + "github.com/traefik/traefik/v3/pkg/middlewares/passtlsclientcert" + "github.com/traefik/traefik/v3/pkg/middlewares/ratelimiter" + "github.com/traefik/traefik/v3/pkg/middlewares/redirect" + "github.com/traefik/traefik/v3/pkg/middlewares/replacepath" + "github.com/traefik/traefik/v3/pkg/middlewares/replacepathregex" + "github.com/traefik/traefik/v3/pkg/middlewares/retry" + "github.com/traefik/traefik/v3/pkg/middlewares/stripprefix" + "github.com/traefik/traefik/v3/pkg/middlewares/stripprefixregex" + "github.com/traefik/traefik/v3/pkg/middlewares/tracing" + "github.com/traefik/traefik/v3/pkg/server/provider" ) type middlewareStackType int diff --git a/pkg/server/middleware/middlewares_test.go b/pkg/server/middleware/middlewares_test.go index 5d8db1aa8d796c1d54cfb704063eac19580dd44d..a0b97d1b9070755d1a1923613d1b69a29a6ee75b 100644 --- a/pkg/server/middleware/middlewares_test.go +++ b/pkg/server/middleware/middlewares_test.go @@ -9,9 +9,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/server/provider" ) func TestBuilder_BuildChainNilConfig(t *testing.T) { diff --git a/pkg/server/middleware/plugins.go b/pkg/server/middleware/plugins.go index 3a092f140884191aa4bca81f14bed5110cd7d27a..13b8b195968ecccad0b7efda39b84aa2b61b053d 100644 --- a/pkg/server/middleware/plugins.go +++ b/pkg/server/middleware/plugins.go @@ -3,8 +3,8 @@ package middleware import ( "errors" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/plugins" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/plugins" ) // PluginsBuilder the plugin's builder interface. diff --git a/pkg/server/middleware/tcp/middlewares.go b/pkg/server/middleware/tcp/middlewares.go index ad6320a4679ca016df7d0b61fbdfcd3808b7f796..e03a4fb84f81e4edae44c17372f6f6678d6977d4 100644 --- a/pkg/server/middleware/tcp/middlewares.go +++ b/pkg/server/middleware/tcp/middlewares.go @@ -5,11 +5,11 @@ import ( "fmt" "strings" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/middlewares/tcp/inflightconn" - "github.com/traefik/traefik/v2/pkg/middlewares/tcp/ipallowlist" - "github.com/traefik/traefik/v2/pkg/server/provider" - "github.com/traefik/traefik/v2/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/middlewares/tcp/inflightconn" + "github.com/traefik/traefik/v3/pkg/middlewares/tcp/ipallowlist" + "github.com/traefik/traefik/v3/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/tcp" ) type middlewareStackType int diff --git a/pkg/server/router/router.go b/pkg/server/router/router.go index 388e792d30b50ee136d5e9adf7269b498bad875f..97f7f98b6a8622b082521f0871c07c5c59db2511 100644 --- a/pkg/server/router/router.go +++ b/pkg/server/router/router.go @@ -8,17 +8,17 @@ import ( "github.com/containous/alice" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/metrics" - "github.com/traefik/traefik/v2/pkg/middlewares/accesslog" - metricsMiddle "github.com/traefik/traefik/v2/pkg/middlewares/metrics" - "github.com/traefik/traefik/v2/pkg/middlewares/recovery" - "github.com/traefik/traefik/v2/pkg/middlewares/tracing" - httpmuxer "github.com/traefik/traefik/v2/pkg/muxer/http" - "github.com/traefik/traefik/v2/pkg/server/middleware" - "github.com/traefik/traefik/v2/pkg/server/provider" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/middlewares/accesslog" + metricsMiddle "github.com/traefik/traefik/v3/pkg/middlewares/metrics" + "github.com/traefik/traefik/v3/pkg/middlewares/recovery" + "github.com/traefik/traefik/v3/pkg/middlewares/tracing" + httpmuxer "github.com/traefik/traefik/v3/pkg/muxer/http" + "github.com/traefik/traefik/v3/pkg/server/middleware" + "github.com/traefik/traefik/v3/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/tls" ) type middlewareBuilder interface { @@ -119,6 +119,10 @@ func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string logger := log.Ctx(ctx).With().Str(logs.RouterName, routerName).Logger() ctxRouter := logger.WithContext(provider.AddInContext(ctx, routerName)) + if routerConfig.Priority == 0 { + routerConfig.Priority = httpmuxer.GetRulePriority(routerConfig.Rule) + } + handler, err := m.buildRouterHandler(ctxRouter, routerName, routerConfig) if err != nil { routerConfig.AddError(err, true) @@ -126,16 +130,13 @@ func (m *Manager) buildEntryPointHandler(ctx context.Context, configs map[string continue } - err = muxer.AddRoute(routerConfig.Rule, routerConfig.Priority, handler) - if err != nil { + if err = muxer.AddRoute(routerConfig.Rule, routerConfig.Priority, handler); err != nil { routerConfig.AddError(err, true) logger.Error().Err(err).Send() continue } } - muxer.SortRoutes() - chain := alice.New() chain = chain.Append(func(next http.Handler) (http.Handler, error) { return recovery.New(ctx, next) diff --git a/pkg/server/router/router_test.go b/pkg/server/router/router_test.go index 7f867633e6a87db7f92ebb3c2db32c184818e612..21e0de141edf08106eaa9da9d5bb798530ae6eb5 100644 --- a/pkg/server/router/router_test.go +++ b/pkg/server/router/router_test.go @@ -13,17 +13,17 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/metrics" - "github.com/traefik/traefik/v2/pkg/middlewares/accesslog" - "github.com/traefik/traefik/v2/pkg/middlewares/capture" - "github.com/traefik/traefik/v2/pkg/middlewares/requestdecorator" - "github.com/traefik/traefik/v2/pkg/server/middleware" - "github.com/traefik/traefik/v2/pkg/server/service" - "github.com/traefik/traefik/v2/pkg/testhelpers" - "github.com/traefik/traefik/v2/pkg/tls" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/middlewares/accesslog" + "github.com/traefik/traefik/v3/pkg/middlewares/capture" + "github.com/traefik/traefik/v3/pkg/middlewares/requestdecorator" + "github.com/traefik/traefik/v3/pkg/server/middleware" + "github.com/traefik/traefik/v3/pkg/server/service" + "github.com/traefik/traefik/v3/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/types" ) func TestRouterManager_Get(t *testing.T) { diff --git a/pkg/server/router/tcp/manager.go b/pkg/server/router/tcp/manager.go index 9bbadbc20980fb74af16ac01b84e057a7a6672d0..df24ed704e7ccb6c04aded74515d4007676e06b0 100644 --- a/pkg/server/router/tcp/manager.go +++ b/pkg/server/router/tcp/manager.go @@ -8,15 +8,15 @@ import ( "net/http" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/middlewares/snicheck" - httpmuxer "github.com/traefik/traefik/v2/pkg/muxer/http" - tcpmuxer "github.com/traefik/traefik/v2/pkg/muxer/tcp" - "github.com/traefik/traefik/v2/pkg/server/provider" - tcpservice "github.com/traefik/traefik/v2/pkg/server/service/tcp" - "github.com/traefik/traefik/v2/pkg/tcp" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/middlewares/snicheck" + httpmuxer "github.com/traefik/traefik/v3/pkg/muxer/http" + tcpmuxer "github.com/traefik/traefik/v3/pkg/muxer/tcp" + "github.com/traefik/traefik/v3/pkg/server/provider" + tcpservice "github.com/traefik/traefik/v3/pkg/server/service/tcp" + "github.com/traefik/traefik/v3/pkg/tcp" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" ) type middlewareBuilder interface { @@ -264,6 +264,10 @@ func (m *Manager) addTCPHandlers(ctx context.Context, configs map[string]*runtim logger := log.Ctx(ctx).With().Str(logs.RouterName, routerName).Logger() ctxRouter := logger.WithContext(provider.AddInContext(ctx, routerName)) + if routerConfig.Priority == 0 { + routerConfig.Priority = tcpmuxer.GetRulePriority(routerConfig.Rule) + } + if routerConfig.Service == "" { err := errors.New("the service is missing on the router") routerConfig.AddError(err, true) @@ -306,6 +310,7 @@ func (m *Manager) addTCPHandlers(ctx context.Context, configs map[string]*runtim if routerConfig.TLS == nil { logger.Debug().Msgf("Adding route for %q", routerConfig.Rule) + if err := router.AddRoute(routerConfig.Rule, routerConfig.Priority, handler); err != nil { routerConfig.AddError(err, true) logger.Error().Err(err).Send() @@ -315,6 +320,7 @@ func (m *Manager) addTCPHandlers(ctx context.Context, configs map[string]*runtim if routerConfig.TLS.Passthrough { logger.Debug().Msgf("Adding Passthrough route for %q", routerConfig.Rule) + if err := router.muxerTCPTLS.AddRoute(routerConfig.Rule, routerConfig.Priority, handler); err != nil { routerConfig.AddError(err, true) logger.Error().Err(err).Send() @@ -349,11 +355,11 @@ func (m *Manager) addTCPHandlers(ctx context.Context, configs map[string]*runtim logger.Debug().Msgf("Adding special TLS closing route for %q because broken TLS options %s", routerConfig.Rule, tlsOptionsName) - err = router.muxerTCPTLS.AddRoute(routerConfig.Rule, routerConfig.Priority, &brokenTLSRouter{}) - if err != nil { + if err := router.muxerTCPTLS.AddRoute(routerConfig.Rule, routerConfig.Priority, &brokenTLSRouter{}); err != nil { routerConfig.AddError(err, true) logger.Error().Err(err).Send() } + continue } @@ -383,10 +389,10 @@ func (m *Manager) addTCPHandlers(ctx context.Context, configs map[string]*runtim logger.Debug().Msgf("Adding TLS route for %q", routerConfig.Rule) - err = router.muxerTCPTLS.AddRoute(routerConfig.Rule, routerConfig.Priority, handler) - if err != nil { + if err := router.muxerTCPTLS.AddRoute(routerConfig.Rule, routerConfig.Priority, handler); err != nil { routerConfig.AddError(err, true) logger.Error().Err(err).Send() + continue } } } diff --git a/pkg/server/router/tcp/manager_test.go b/pkg/server/router/tcp/manager_test.go index dd31ce3b3b0074111c1b543e867a1265c7deeabb..29af7783ce049fb807c9badf8a3f5525ffd32e7f 100644 --- a/pkg/server/router/tcp/manager_test.go +++ b/pkg/server/router/tcp/manager_test.go @@ -9,11 +9,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - tcpmiddleware "github.com/traefik/traefik/v2/pkg/server/middleware/tcp" - "github.com/traefik/traefik/v2/pkg/server/service/tcp" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + tcpmiddleware "github.com/traefik/traefik/v3/pkg/server/middleware/tcp" + "github.com/traefik/traefik/v3/pkg/server/service/tcp" + tcp2 "github.com/traefik/traefik/v3/pkg/tcp" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" ) func TestRuntimeConfiguration(t *testing.T) { @@ -311,7 +312,9 @@ func TestRuntimeConfiguration(t *testing.T) { TCPServices: test.tcpServiceConfig, TCPRouters: test.tcpRouterConfig, } - serviceManager := tcp.NewManager(conf) + dialerManager := tcp2.NewDialerManager(nil) + dialerManager.Update(map[string]*dynamic.TCPServersTransport{"default@internal": {}}) + serviceManager := tcp.NewManager(conf, dialerManager) tlsManager := traefiktls.NewManager() tlsManager.UpdateConfigs( context.Background(), @@ -622,7 +625,7 @@ func TestDomainFronting(t *testing.T) { Routers: test.routers, } - serviceManager := tcp.NewManager(conf) + serviceManager := tcp.NewManager(conf, tcp2.NewDialerManager(nil)) tlsManager := traefiktls.NewManager() tlsManager.UpdateConfigs(context.Background(), map[string]traefiktls.Store{}, test.tlsOptions, []*traefiktls.CertAndStores{}) diff --git a/pkg/server/router/tcp/postgres.go b/pkg/server/router/tcp/postgres.go index b79c3762f19e6f0bd0ef6640be4419b6c72a8030..e82ba7eb3b5aa699ab602d17660eb9106726cedd 100644 --- a/pkg/server/router/tcp/postgres.go +++ b/pkg/server/router/tcp/postgres.go @@ -4,11 +4,13 @@ import ( "bufio" "bytes" "errors" + "io" + "net" "sync" "github.com/rs/zerolog/log" - tcpmuxer "github.com/traefik/traefik/v2/pkg/muxer/tcp" - "github.com/traefik/traefik/v2/pkg/tcp" + tcpmuxer "github.com/traefik/traefik/v3/pkg/muxer/tcp" + "github.com/traefik/traefik/v3/pkg/tcp" ) var ( @@ -25,7 +27,10 @@ func isPostgres(br *bufio.Reader) (bool, error) { for i := 1; i < len(PostgresStartTLSMsg)+1; i++ { peeked, err := br.Peek(i) if err != nil { - log.Error().Err(err).Msg("Error while Peeking first bytes") + var opErr *net.OpError + if !errors.Is(err, io.EOF) && (!errors.As(err, &opErr) || opErr.Timeout()) { + log.Error().Err(err).Msg("Error while Peeking first byte") + } return false, err } diff --git a/pkg/server/router/tcp/router.go b/pkg/server/router/tcp/router.go index b3f34ee0d6815ba139abde1af5a08fa0e2d1122c..8c2e8939bdb0de25fa49b73a8e23d4f5e27c1ff1 100644 --- a/pkg/server/router/tcp/router.go +++ b/pkg/server/router/tcp/router.go @@ -11,8 +11,8 @@ import ( "time" "github.com/rs/zerolog/log" - tcpmuxer "github.com/traefik/traefik/v2/pkg/muxer/tcp" - "github.com/traefik/traefik/v2/pkg/tcp" + tcpmuxer "github.com/traefik/traefik/v3/pkg/muxer/tcp" + "github.com/traefik/traefik/v3/pkg/tcp" ) const defaultBufSize = 4096 @@ -268,8 +268,7 @@ func (r *Router) SetHTTPSForwarder(handler tcp.Handler) { // muxerHTTPS only contains single HostSNI rules (and no other kind of rules), // so there's no need for specifying a priority for them. - err := r.muxerHTTPS.AddRoute("HostSNI(`"+sniHost+"`)", 0, tcpHandler) - if err != nil { + if err := r.muxerHTTPS.AddRoute("HostSNI(`"+sniHost+"`)", 0, tcpHandler); err != nil { log.Error().Err(err).Msg("Error while adding route for host") } } diff --git a/pkg/server/router/tcp/router_test.go b/pkg/server/router/tcp/router_test.go index f6fc4f4ab0184344b5e9b000b2f3a407b2d975c0..3701ca67e59a46aa9531300a4261cc739fb866f7 100644 --- a/pkg/server/router/tcp/router_test.go +++ b/pkg/server/router/tcp/router_test.go @@ -16,12 +16,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - tcpmiddleware "github.com/traefik/traefik/v2/pkg/server/middleware/tcp" - "github.com/traefik/traefik/v2/pkg/server/service/tcp" - tcp2 "github.com/traefik/traefik/v2/pkg/tcp" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + tcpmiddleware "github.com/traefik/traefik/v3/pkg/server/middleware/tcp" + "github.com/traefik/traefik/v3/pkg/server/service/tcp" + tcp2 "github.com/traefik/traefik/v3/pkg/tcp" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" ) type applyRouter func(conf *runtime.Configuration) @@ -162,7 +162,9 @@ func Test_Routing(t *testing.T) { }, } - serviceManager := tcp.NewManager(conf) + dialerManager := tcp2.NewDialerManager(nil) + dialerManager.Update(map[string]*dynamic.TCPServersTransport{"default@internal": {}}) + serviceManager := tcp.NewManager(conf, dialerManager) // Creates the tlsManager and defines the TLS 1.0 and 1.2 TLSOptions. tlsManager := traefiktls.NewManager() diff --git a/pkg/server/router/udp/router.go b/pkg/server/router/udp/router.go index 0a5303effee2e096cd785d6516b3beb1cc7a25ca..091d77ed510da947474cfe771d504d5d3d993a1f 100644 --- a/pkg/server/router/udp/router.go +++ b/pkg/server/router/udp/router.go @@ -6,11 +6,11 @@ import ( "sort" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/server/provider" - udpservice "github.com/traefik/traefik/v2/pkg/server/service/udp" - "github.com/traefik/traefik/v2/pkg/udp" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/server/provider" + udpservice "github.com/traefik/traefik/v3/pkg/server/service/udp" + "github.com/traefik/traefik/v3/pkg/udp" ) // NewManager Creates a new Manager. diff --git a/pkg/server/router/udp/router_test.go b/pkg/server/router/udp/router_test.go index d29d7d2d6bba7765da4fadd7ce40f65a69fd5133..d6be074915da232ca63a1e89f07a53ee3eedb041 100644 --- a/pkg/server/router/udp/router_test.go +++ b/pkg/server/router/udp/router_test.go @@ -5,9 +5,9 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/server/service/udp" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/server/service/udp" ) func TestRuntimeConfiguration(t *testing.T) { diff --git a/pkg/server/routerfactory.go b/pkg/server/routerfactory.go index 1b28a0dfd2cde1c1db9b9010bf8837e36f591180..d7a1bf68ce934d5e609b931b9225c24f40df3593 100644 --- a/pkg/server/routerfactory.go +++ b/pkg/server/routerfactory.go @@ -4,19 +4,20 @@ import ( "context" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/metrics" - "github.com/traefik/traefik/v2/pkg/server/middleware" - tcpmiddleware "github.com/traefik/traefik/v2/pkg/server/middleware/tcp" - "github.com/traefik/traefik/v2/pkg/server/router" - tcprouter "github.com/traefik/traefik/v2/pkg/server/router/tcp" - udprouter "github.com/traefik/traefik/v2/pkg/server/router/udp" - "github.com/traefik/traefik/v2/pkg/server/service" - "github.com/traefik/traefik/v2/pkg/server/service/tcp" - "github.com/traefik/traefik/v2/pkg/server/service/udp" - "github.com/traefik/traefik/v2/pkg/tls" - udptypes "github.com/traefik/traefik/v2/pkg/udp" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/server/middleware" + tcpmiddleware "github.com/traefik/traefik/v3/pkg/server/middleware/tcp" + "github.com/traefik/traefik/v3/pkg/server/router" + tcprouter "github.com/traefik/traefik/v3/pkg/server/router/tcp" + udprouter "github.com/traefik/traefik/v3/pkg/server/router/udp" + "github.com/traefik/traefik/v3/pkg/server/service" + tcpsvc "github.com/traefik/traefik/v3/pkg/server/service/tcp" + udpsvc "github.com/traefik/traefik/v3/pkg/server/service/udp" + "github.com/traefik/traefik/v3/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/tls" + "github.com/traefik/traefik/v3/pkg/udp" ) // RouterFactory the factory of TCP/UDP routers. @@ -32,12 +33,14 @@ type RouterFactory struct { chainBuilder *middleware.ChainBuilder tlsManager *tls.Manager + dialerManager *tcp.DialerManager + cancelPrevState func() } // NewRouterFactory creates a new RouterFactory. func NewRouterFactory(staticConfiguration static.Configuration, managerFactory *service.ManagerFactory, tlsManager *tls.Manager, - chainBuilder *middleware.ChainBuilder, pluginBuilder middleware.PluginsBuilder, metricsRegistry metrics.Registry, + chainBuilder *middleware.ChainBuilder, pluginBuilder middleware.PluginsBuilder, metricsRegistry metrics.Registry, dialerManager *tcp.DialerManager, ) *RouterFactory { var entryPointsTCP, entryPointsUDP []string for name, cfg := range staticConfiguration.EntryPoints { @@ -62,11 +65,12 @@ func NewRouterFactory(staticConfiguration static.Configuration, managerFactory * tlsManager: tlsManager, chainBuilder: chainBuilder, pluginBuilder: pluginBuilder, + dialerManager: dialerManager, } } // CreateRouters creates new TCPRouters and UDPRouters. -func (f *RouterFactory) CreateRouters(rtConf *runtime.Configuration) (map[string]*tcprouter.Router, map[string]udptypes.Handler) { +func (f *RouterFactory) CreateRouters(rtConf *runtime.Configuration) (map[string]*tcprouter.Router, map[string]udp.Handler) { if f.cancelPrevState != nil { f.cancelPrevState() } @@ -87,7 +91,7 @@ func (f *RouterFactory) CreateRouters(rtConf *runtime.Configuration) (map[string serviceManager.LaunchHealthCheck(ctx) // TCP - svcTCPManager := tcp.NewManager(rtConf) + svcTCPManager := tcpsvc.NewManager(rtConf, f.dialerManager) middlewaresTCPBuilder := tcpmiddleware.NewBuilder(rtConf.TCPMiddlewares) @@ -95,7 +99,7 @@ func (f *RouterFactory) CreateRouters(rtConf *runtime.Configuration) (map[string routersTCP := rtTCPManager.BuildHandlers(ctx, f.entryPointsTCP) // UDP - svcUDPManager := udp.NewManager(rtConf) + svcUDPManager := udpsvc.NewManager(rtConf) rtUDPManager := udprouter.NewManager(rtConf, svcUDPManager) routersUDP := rtUDPManager.BuildHandlers(ctx, f.entryPointsUDP) diff --git a/pkg/server/routerfactory_test.go b/pkg/server/routerfactory_test.go index 6358d4cbf8000792da9db7f3948074db6a3c4459..b935df89efafd6ca4c46c849436b856517140cd0 100644 --- a/pkg/server/routerfactory_test.go +++ b/pkg/server/routerfactory_test.go @@ -6,14 +6,15 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/metrics" - "github.com/traefik/traefik/v2/pkg/server/middleware" - "github.com/traefik/traefik/v2/pkg/server/service" - th "github.com/traefik/traefik/v2/pkg/testhelpers" - "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/server/middleware" + "github.com/traefik/traefik/v3/pkg/server/service" + "github.com/traefik/traefik/v3/pkg/tcp" + th "github.com/traefik/traefik/v3/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/tls" ) func TestReuseService(t *testing.T) { @@ -53,7 +54,9 @@ func TestReuseService(t *testing.T) { managerFactory := service.NewManagerFactory(staticConfig, nil, metrics.NewVoidRegistry(), roundTripperManager, nil) tlsManager := tls.NewManager() - factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(nil, nil, nil), nil, metrics.NewVoidRegistry()) + dialerManager := tcp.NewDialerManager(nil) + dialerManager.Update(map[string]*dynamic.TCPServersTransport{"default@internal": {}}) + factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(nil, nil, nil), nil, metrics.NewVoidRegistry(), dialerManager) entryPointsHandlers, _ := factory.CreateRouters(runtime.NewConfig(dynamic.Configuration{HTTP: dynamicConfigs})) @@ -189,7 +192,9 @@ func TestServerResponseEmptyBackend(t *testing.T) { managerFactory := service.NewManagerFactory(staticConfig, nil, metrics.NewVoidRegistry(), roundTripperManager, nil) tlsManager := tls.NewManager() - factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(nil, nil, nil), nil, metrics.NewVoidRegistry()) + dialerManager := tcp.NewDialerManager(nil) + dialerManager.Update(map[string]*dynamic.TCPServersTransport{"default@internal": {}}) + factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(nil, nil, nil), nil, metrics.NewVoidRegistry(), dialerManager) entryPointsHandlers, _ := factory.CreateRouters(runtime.NewConfig(dynamic.Configuration{HTTP: test.config(testServer.URL)})) @@ -232,7 +237,9 @@ func TestInternalServices(t *testing.T) { voidRegistry := metrics.NewVoidRegistry() - factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(voidRegistry, nil, nil), nil, voidRegistry) + dialerManager := tcp.NewDialerManager(nil) + dialerManager.Update(map[string]*dynamic.TCPServersTransport{"default@internal": {}}) + factory := NewRouterFactory(staticConfig, managerFactory, tlsManager, middleware.NewChainBuilder(voidRegistry, nil, nil), nil, voidRegistry, dialerManager) entryPointsHandlers, _ := factory.CreateRouters(runtime.NewConfig(dynamic.Configuration{HTTP: dynamicConfigs})) diff --git a/pkg/server/server.go b/pkg/server/server.go index 421437a383658b4e80560dd4211e17f2e39f65b7..c17464621e43d5b645ea6dfbb8381fb2fbc19763 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -8,10 +8,10 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/metrics" - "github.com/traefik/traefik/v2/pkg/middlewares/accesslog" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/server/middleware" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/middlewares/accesslog" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/server/middleware" ) // Server is the reverse-proxy/load-balancer engine. @@ -111,7 +111,6 @@ func (s *Server) Close() { func stopMetricsClients() { metrics.StopDatadog() metrics.StopStatsd() - metrics.StopInfluxDB() metrics.StopInfluxDB2() metrics.StopOpenTelemetry() } diff --git a/pkg/server/server_entrypoint_tcp.go b/pkg/server/server_entrypoint_tcp.go index 87c0a77efda147c711af6508ea910458b01825ed..6f8bfba02477c358a1205e0a8fa2666c652470a6 100644 --- a/pkg/server/server_entrypoint_tcp.go +++ b/pkg/server/server_entrypoint_tcp.go @@ -15,21 +15,23 @@ import ( "time" "github.com/containous/alice" + gokitmetrics "github.com/go-kit/kit/metrics" "github.com/pires/go-proxyproto" "github.com/rs/zerolog" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/ip" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/middlewares" - "github.com/traefik/traefik/v2/pkg/middlewares/contenttype" - "github.com/traefik/traefik/v2/pkg/middlewares/forwardedheaders" - "github.com/traefik/traefik/v2/pkg/middlewares/requestdecorator" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/server/router" - tcprouter "github.com/traefik/traefik/v2/pkg/server/router/tcp" - "github.com/traefik/traefik/v2/pkg/tcp" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/ip" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/middlewares" + "github.com/traefik/traefik/v3/pkg/middlewares/contenttype" + "github.com/traefik/traefik/v3/pkg/middlewares/forwardedheaders" + "github.com/traefik/traefik/v3/pkg/middlewares/requestdecorator" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/server/router" + tcprouter "github.com/traefik/traefik/v3/pkg/server/router/tcp" + "github.com/traefik/traefik/v3/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/types" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" ) @@ -67,7 +69,7 @@ func (h *httpForwarder) Accept() (net.Conn, error) { type TCPEntryPoints map[string]*TCPEntryPoint // NewTCPEntryPoints creates a new TCPEntryPoints. -func NewTCPEntryPoints(entryPointsConfig static.EntryPoints, hostResolverConfig *types.HostResolverConfig) (TCPEntryPoints, error) { +func NewTCPEntryPoints(entryPointsConfig static.EntryPoints, hostResolverConfig *types.HostResolverConfig, metricsRegistry metrics.Registry) (TCPEntryPoints, error) { serverEntryPointsTCP := make(TCPEntryPoints) for entryPointName, config := range entryPointsConfig { protocol, err := config.GetProtocol() @@ -81,7 +83,11 @@ func NewTCPEntryPoints(entryPointsConfig static.EntryPoints, hostResolverConfig ctx := log.With().Str(logs.EntryPointName, entryPointName).Logger().WithContext(context.Background()) - serverEntryPointsTCP[entryPointName], err = NewTCPEntryPoint(ctx, config, hostResolverConfig) + openConnectionsGauge := metricsRegistry. + OpenConnectionsGauge(). + With("entrypoint", entryPointName, "protocol", "TCP") + + serverEntryPointsTCP[entryPointName], err = NewTCPEntryPoint(ctx, config, hostResolverConfig, openConnectionsGauge) if err != nil { return nil, fmt.Errorf("error while building entryPoint %s: %w", entryPointName, err) } @@ -137,8 +143,8 @@ type TCPEntryPoint struct { } // NewTCPEntryPoint creates a new TCPEntryPoint. -func NewTCPEntryPoint(ctx context.Context, configuration *static.EntryPoint, hostResolverConfig *types.HostResolverConfig) (*TCPEntryPoint, error) { - tracker := newConnectionTracker() +func NewTCPEntryPoint(ctx context.Context, configuration *static.EntryPoint, hostResolverConfig *types.HostResolverConfig, openConnectionsGauge gokitmetrics.Gauge) (*TCPEntryPoint, error) { + tracker := newConnectionTracker(openConnectionsGauge) listener, err := buildListener(ctx, configuration) if err != nil { @@ -440,34 +446,45 @@ func buildListener(ctx context.Context, entryPoint *static.EntryPoint) (net.List return listener, nil } -func newConnectionTracker() *connectionTracker { +func newConnectionTracker(openConnectionsGauge gokitmetrics.Gauge) *connectionTracker { return &connectionTracker{ - conns: make(map[net.Conn]struct{}), + conns: make(map[net.Conn]struct{}), + openConnectionsGauge: openConnectionsGauge, } } type connectionTracker struct { - conns map[net.Conn]struct{} - lock sync.RWMutex + connsMu sync.RWMutex + conns map[net.Conn]struct{} + + openConnectionsGauge gokitmetrics.Gauge } // AddConnection add a connection in the tracked connections list. func (c *connectionTracker) AddConnection(conn net.Conn) { - c.lock.Lock() - defer c.lock.Unlock() + c.connsMu.Lock() c.conns[conn] = struct{}{} + c.connsMu.Unlock() + + if c.openConnectionsGauge != nil { + c.openConnectionsGauge.Add(1) + } } // RemoveConnection remove a connection from the tracked connections list. func (c *connectionTracker) RemoveConnection(conn net.Conn) { - c.lock.Lock() - defer c.lock.Unlock() + c.connsMu.Lock() delete(c.conns, conn) + c.connsMu.Unlock() + + if c.openConnectionsGauge != nil { + c.openConnectionsGauge.Add(-1) + } } func (c *connectionTracker) isEmpty() bool { - c.lock.RLock() - defer c.lock.RUnlock() + c.connsMu.RLock() + defer c.connsMu.RUnlock() return len(c.conns) == 0 } @@ -489,8 +506,8 @@ func (c *connectionTracker) Shutdown(ctx context.Context) error { // Close close all the connections in the tracked connections list. func (c *connectionTracker) Close() { - c.lock.Lock() - defer c.lock.Unlock() + c.connsMu.Lock() + defer c.connsMu.Unlock() for conn := range c.conns { if err := conn.Close(); err != nil { log.Error().Err(err).Msg("Error while closing connection") diff --git a/pkg/server/server_entrypoint_tcp_http3.go b/pkg/server/server_entrypoint_tcp_http3.go index 99755d6d779936d113cf8e428d255f3ed083a3e4..188be8026384b4a0dc883afb3e6870c5a4ccc494 100644 --- a/pkg/server/server_entrypoint_tcp_http3.go +++ b/pkg/server/server_entrypoint_tcp_http3.go @@ -9,10 +9,10 @@ import ( "net/http" "sync" - "github.com/lucas-clemente/quic-go/http3" + "github.com/quic-go/quic-go/http3" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/static" - tcprouter "github.com/traefik/traefik/v2/pkg/server/router/tcp" + "github.com/traefik/traefik/v3/pkg/config/static" + tcprouter "github.com/traefik/traefik/v3/pkg/server/router/tcp" ) type http3server struct { diff --git a/pkg/server/server_entrypoint_tcp_http3_test.go b/pkg/server/server_entrypoint_tcp_http3_test.go index 6544dd2e04572361fd1c1b91de584ca843d7ebf5..9b440be4b4ea4e082d94cbddb9a55f0858a15c8f 100644 --- a/pkg/server/server_entrypoint_tcp_http3_test.go +++ b/pkg/server/server_entrypoint_tcp_http3_test.go @@ -6,12 +6,13 @@ import ( "crypto/tls" "net/http" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/static" - tcprouter "github.com/traefik/traefik/v2/pkg/server/router/tcp" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/static" + tcprouter "github.com/traefik/traefik/v3/pkg/server/router/tcp" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" ) // LocalhostCert is a PEM-encoded TLS cert with SAN IPs @@ -92,7 +93,7 @@ func TestHTTP3AdvertisedPort(t *testing.T) { HTTP3: &static.HTTP3Config{ AdvertisedPort: 8080, }, - }, nil) + }, nil, nil) require.NoError(t, err) router, err := tcprouter.NewRouter() @@ -113,6 +114,9 @@ func TestHTTP3AdvertisedPort(t *testing.T) { }) require.NoError(t, err) + // We are racing with the http3Server readiness happening in the goroutine starting the entrypoint + time.Sleep(time.Second) + request, err := http.NewRequest(http.MethodGet, "https://127.0.0.1:8090", nil) require.NoError(t, err) diff --git a/pkg/server/server_entrypoint_tcp_test.go b/pkg/server/server_entrypoint_tcp_test.go index 342d7d9faf7a65f19ef7532b8aa55cf06166260d..3567ca47fcdd2ba2c1be1268a1196e98a1f6ad7d 100644 --- a/pkg/server/server_entrypoint_tcp_test.go +++ b/pkg/server/server_entrypoint_tcp_test.go @@ -14,9 +14,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/static" - tcprouter "github.com/traefik/traefik/v2/pkg/server/router/tcp" - "github.com/traefik/traefik/v2/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/config/static" + tcprouter "github.com/traefik/traefik/v3/pkg/server/router/tcp" + "github.com/traefik/traefik/v3/pkg/tcp" ) func TestShutdownHijacked(t *testing.T) { @@ -79,7 +79,7 @@ func testShutdown(t *testing.T, router *tcprouter.Router) { Transport: epConfig, ForwardedHeaders: &static.ForwardedHeaders{}, HTTP2: &static.HTTP2Config{}, - }, nil) + }, nil, nil) require.NoError(t, err) conn, err := startEntrypoint(entryPoint, router) @@ -164,7 +164,7 @@ func TestReadTimeoutWithoutFirstByte(t *testing.T) { Transport: epConfig, ForwardedHeaders: &static.ForwardedHeaders{}, HTTP2: &static.HTTP2Config{}, - }, nil) + }, nil, nil) require.NoError(t, err) router := &tcprouter.Router{} @@ -201,7 +201,7 @@ func TestReadTimeoutWithFirstByte(t *testing.T) { Transport: epConfig, ForwardedHeaders: &static.ForwardedHeaders{}, HTTP2: &static.HTTP2Config{}, - }, nil) + }, nil, nil) require.NoError(t, err) router := &tcprouter.Router{} diff --git a/pkg/server/server_entrypoint_udp.go b/pkg/server/server_entrypoint_udp.go index 1aa4c38c31d12088be4b94f402115fbf78d1ca75..347b169db20748e67b10c42c1458bd3eaea4ea0e 100644 --- a/pkg/server/server_entrypoint_udp.go +++ b/pkg/server/server_entrypoint_udp.go @@ -8,9 +8,9 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/udp" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/udp" ) // UDPEntryPoints maps UDP entry points by their names. diff --git a/pkg/server/server_entrypoint_udp_test.go b/pkg/server/server_entrypoint_udp_test.go index 0396f434fab5db24dfd52956ba61be7a588820ee..e5ac550862767a43c96a7858cdbdc313068ba844 100644 --- a/pkg/server/server_entrypoint_udp_test.go +++ b/pkg/server/server_entrypoint_udp_test.go @@ -9,8 +9,8 @@ import ( "github.com/stretchr/testify/require" ptypes "github.com/traefik/paerser/types" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/udp" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/udp" ) func TestShutdownUDPConn(t *testing.T) { diff --git a/pkg/server/service/loadbalancer/failover/failover.go b/pkg/server/service/loadbalancer/failover/failover.go index 972d38672774557a4cec5f6eaeeb61b9c9ca5021..07cf519684f02e9470c0d67b15149bc3488e26ac 100644 --- a/pkg/server/service/loadbalancer/failover/failover.go +++ b/pkg/server/service/loadbalancer/failover/failover.go @@ -7,7 +7,7 @@ import ( "sync" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) // Failover is an http.Handler that can forward requests to the fallback handler diff --git a/pkg/server/service/loadbalancer/failover/failover_test.go b/pkg/server/service/loadbalancer/failover/failover_test.go index 9f8d3821528b71980cfecbe4bfba7188d656be76..a2f7f89f04e5cd3d414bb6e4d25063855d1cbec3 100644 --- a/pkg/server/service/loadbalancer/failover/failover_test.go +++ b/pkg/server/service/loadbalancer/failover/failover_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) type responseRecorder struct { diff --git a/pkg/server/service/loadbalancer/mirror/mirror.go b/pkg/server/service/loadbalancer/mirror/mirror.go index cb77b72808feeee77fd52c30e76514ff74c7cae4..201dade9a74b8090e2e2f17d2b8996e7e3c5534c 100644 --- a/pkg/server/service/loadbalancer/mirror/mirror.go +++ b/pkg/server/service/loadbalancer/mirror/mirror.go @@ -12,10 +12,10 @@ import ( "sync" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/healthcheck" - "github.com/traefik/traefik/v2/pkg/middlewares/accesslog" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/healthcheck" + "github.com/traefik/traefik/v3/pkg/middlewares/accesslog" + "github.com/traefik/traefik/v3/pkg/safe" ) // Mirroring is an http.Handler that can mirror requests. diff --git a/pkg/server/service/loadbalancer/mirror/mirror_test.go b/pkg/server/service/loadbalancer/mirror/mirror_test.go index eda49a9600740d0c0f6a7dbd25d049c31b11c050..57d815f0f3fd833042fbb8521315a63711c9bac2 100644 --- a/pkg/server/service/loadbalancer/mirror/mirror_test.go +++ b/pkg/server/service/loadbalancer/mirror/mirror_test.go @@ -10,7 +10,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/safe" ) const defaultMaxBodySize int64 = -1 diff --git a/pkg/server/service/loadbalancer/wrr/wrr.go b/pkg/server/service/loadbalancer/wrr/wrr.go index ed89dfb314b6022e357fcce8163c50c646a4d1c9..7442fa3a19ee6926cbd9348040ecf248203ea5f1 100644 --- a/pkg/server/service/loadbalancer/wrr/wrr.go +++ b/pkg/server/service/loadbalancer/wrr/wrr.go @@ -8,7 +8,7 @@ import ( "sync" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) type namedHandler struct { diff --git a/pkg/server/service/loadbalancer/wrr/wrr_test.go b/pkg/server/service/loadbalancer/wrr/wrr_test.go index 7d6d6acad0381efb27174a3c6a6f94ba790a5d5d..e0ca68c0490312319f8a61f9ba891c9b76b8c94c 100644 --- a/pkg/server/service/loadbalancer/wrr/wrr_test.go +++ b/pkg/server/service/loadbalancer/wrr/wrr_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func TestBalancer(t *testing.T) { diff --git a/pkg/server/service/managerfactory.go b/pkg/server/service/managerfactory.go index 5db06ef40a9cc2d5a687105a5c074feeed362fca..524ae01d9ec75ac98d0ed8c6e9eec0c113ee78da 100644 --- a/pkg/server/service/managerfactory.go +++ b/pkg/server/service/managerfactory.go @@ -4,12 +4,12 @@ import ( "net/http" "github.com/gorilla/mux" - "github.com/traefik/traefik/v2/pkg/api" - "github.com/traefik/traefik/v2/pkg/api/dashboard" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/config/static" - "github.com/traefik/traefik/v2/pkg/metrics" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/api" + "github.com/traefik/traefik/v3/pkg/api/dashboard" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/config/static" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/safe" ) // ManagerFactory a factory of service manager. diff --git a/pkg/server/service/proxy.go b/pkg/server/service/proxy.go index 58f5e70813e7929282ec39d033793cfa5cc456f0..b34cc050062e3d655de7d0f2f8c3daaa11a21d2c 100644 --- a/pkg/server/service/proxy.go +++ b/pkg/server/service/proxy.go @@ -53,11 +53,7 @@ func directorBuilder(target *url.URL, passHostHeader bool) func(req *http.Reques outReq.ProtoMajor = 1 outReq.ProtoMinor = 1 - if _, ok := outReq.Header["User-Agent"]; !ok { - outReq.Header.Set("User-Agent", "") - } - - // Do not pass client Host header unless PassHostHeader is set. + // Do not pass client Host header unless optsetter PassHostHeader is set. if !passHostHeader { outReq.Host = outReq.URL.Host } diff --git a/pkg/server/service/proxy_test.go b/pkg/server/service/proxy_test.go index 8abc51cd2c2f320cf76492e57c21f4275727bf3f..8bea51829bbd8f807f28644cbc31d8c2795fcaad 100644 --- a/pkg/server/service/proxy_test.go +++ b/pkg/server/service/proxy_test.go @@ -7,7 +7,7 @@ import ( "strings" "testing" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) type staticTransport struct { diff --git a/pkg/server/service/roundtripper.go b/pkg/server/service/roundtripper.go index a4c01ef060152726d882ea5ac5592f9bd62b34fa..d7ab54c7a0ea60858661a06a5f50cad894ea7484 100644 --- a/pkg/server/service/roundtripper.go +++ b/pkg/server/service/roundtripper.go @@ -16,8 +16,8 @@ import ( "github.com/spiffe/go-spiffe/v2/spiffeid" "github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig" "github.com/spiffe/go-spiffe/v2/svid/x509svid" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" "golang.org/x/net/http2" ) diff --git a/pkg/server/service/roundtripper_test.go b/pkg/server/service/roundtripper_test.go index d11e2f6936ab6562b8812cfec2faacb1f9154386..971604d927dc565635f7e6906b6f62c3734d5ac5 100644 --- a/pkg/server/service/roundtripper_test.go +++ b/pkg/server/service/roundtripper_test.go @@ -21,8 +21,8 @@ import ( "github.com/spiffe/go-spiffe/v2/svid/x509svid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - traefiktls "github.com/traefik/traefik/v2/pkg/tls" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" ) func Int32(i int32) *int32 { diff --git a/pkg/server/service/service.go b/pkg/server/service/service.go index d4295b9c6abe128cd1bad0f9e876c65a8698ebb0..9883d79a2904675627cb1721d0d8f2261327fa80 100644 --- a/pkg/server/service/service.go +++ b/pkg/server/service/service.go @@ -14,19 +14,19 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/healthcheck" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/metrics" - "github.com/traefik/traefik/v2/pkg/middlewares/accesslog" - metricsMiddle "github.com/traefik/traefik/v2/pkg/middlewares/metrics" - "github.com/traefik/traefik/v2/pkg/safe" - "github.com/traefik/traefik/v2/pkg/server/cookie" - "github.com/traefik/traefik/v2/pkg/server/provider" - "github.com/traefik/traefik/v2/pkg/server/service/loadbalancer/failover" - "github.com/traefik/traefik/v2/pkg/server/service/loadbalancer/mirror" - "github.com/traefik/traefik/v2/pkg/server/service/loadbalancer/wrr" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/healthcheck" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/metrics" + "github.com/traefik/traefik/v3/pkg/middlewares/accesslog" + metricsMiddle "github.com/traefik/traefik/v3/pkg/middlewares/metrics" + "github.com/traefik/traefik/v3/pkg/safe" + "github.com/traefik/traefik/v3/pkg/server/cookie" + "github.com/traefik/traefik/v3/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/failover" + "github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/mirror" + "github.com/traefik/traefik/v3/pkg/server/service/loadbalancer/wrr" ) const defaultMaxBodySize int64 = -1 diff --git a/pkg/server/service/service_test.go b/pkg/server/service/service_test.go index 36501caceb228c61fbd0c3e557e6d0854add4037..8b5ff946b681d5cc066e7b42f15762547433b2df 100644 --- a/pkg/server/service/service_test.go +++ b/pkg/server/service/service_test.go @@ -2,17 +2,20 @@ package service import ( "context" + "io" "net/http" "net/http/httptest" + "net/http/httptrace" + "net/textproto" "strings" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/server/provider" - "github.com/traefik/traefik/v2/pkg/testhelpers" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/testhelpers" ) func TestGetLoadBalancer(t *testing.T) { @@ -86,24 +89,34 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { server1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-From", "first") })) - defer server1.Close() + t.Cleanup(server1.Close) server2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-From", "second") })) - defer server2.Close() + t.Cleanup(server2.Close) serverPassHost := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-From", "passhost") assert.Equal(t, "callme", r.Host) })) - defer serverPassHost.Close() + t.Cleanup(serverPassHost.Close) serverPassHostFalse := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("X-From", "passhostfalse") assert.NotEqual(t, "callme", r.Host) })) - defer serverPassHostFalse.Close() + t.Cleanup(serverPassHostFalse.Close) + + hasNoUserAgent := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Empty(t, r.Header.Get("User-Agent")) + })) + t.Cleanup(hasNoUserAgent.Close) + + hasUserAgent := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Equal(t, "foobar", r.Header.Get("User-Agent")) + })) + t.Cleanup(hasUserAgent.Close) type ExpectedResult struct { StatusCode int @@ -119,6 +132,7 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { service *dynamic.ServersLoadBalancer responseModifier func(*http.Response) error cookieRawValue string + userAgent string expected []ExpectedResult }{ @@ -256,6 +270,39 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { }, }, }, + { + desc: "No user-agent", + serviceName: "test", + service: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: hasNoUserAgent.URL, + }, + }, + }, + expected: []ExpectedResult{ + { + StatusCode: http.StatusOK, + }, + }, + }, + { + desc: "Custom user-agent", + serviceName: "test", + userAgent: "foobar", + service: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: hasUserAgent.URL, + }, + }, + }, + expected: []ExpectedResult{ + { + StatusCode: http.StatusOK, + }, + }, + }, } for _, test := range testCases { @@ -268,6 +315,12 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { assert.NotNil(t, handler) req := testhelpers.MustNewRequest(http.MethodGet, "http://callme", nil) + assert.Equal(t, "", req.Header.Get("User-Agent")) + + if test.userAgent != "" { + req.Header.Set("User-Agent", test.userAgent) + } + if test.cookieRawValue != "" { req.Header.Set("Cookie", test.cookieRawValue) } @@ -306,6 +359,101 @@ func TestGetLoadBalancerServiceHandler(t *testing.T) { } } +// This test is an adapted version of net/http/httputil.Test1xxResponses test. +func Test1xxResponses(t *testing.T) { + sm := NewManager(nil, nil, nil, &RoundTripperManager{ + roundTrippers: map[string]http.RoundTripper{ + "default@internal": http.DefaultTransport, + }, + }) + + backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + h := w.Header() + h.Add("Link", "</style.css>; rel=preload; as=style") + h.Add("Link", "</script.js>; rel=preload; as=script") + w.WriteHeader(http.StatusEarlyHints) + + h.Add("Link", "</foo.js>; rel=preload; as=script") + w.WriteHeader(http.StatusProcessing) + + _, _ = w.Write([]byte("Hello")) + })) + t.Cleanup(backend.Close) + + info := &runtime.ServiceInfo{ + Service: &dynamic.Service{ + LoadBalancer: &dynamic.ServersLoadBalancer{ + Servers: []dynamic.Server{ + { + URL: backend.URL, + }, + }, + }, + }, + } + + handler, err := sm.getLoadBalancerServiceHandler(context.Background(), "foobar", info) + assert.Nil(t, err) + + frontend := httptest.NewServer(handler) + t.Cleanup(frontend.Close) + frontendClient := frontend.Client() + + checkLinkHeaders := func(t *testing.T, expected, got []string) { + t.Helper() + + if len(expected) != len(got) { + t.Errorf("Expected %d link headers; got %d", len(expected), len(got)) + } + + for i := range expected { + if i >= len(got) { + t.Errorf("Expected %q link header; got nothing", expected[i]) + + continue + } + + if expected[i] != got[i] { + t.Errorf("Expected %q link header; got %q", expected[i], got[i]) + } + } + } + + var respCounter uint8 + trace := &httptrace.ClientTrace{ + Got1xxResponse: func(code int, header textproto.MIMEHeader) error { + switch code { + case http.StatusEarlyHints: + checkLinkHeaders(t, []string{"</style.css>; rel=preload; as=style", "</script.js>; rel=preload; as=script"}, header["Link"]) + case http.StatusProcessing: + checkLinkHeaders(t, []string{"</style.css>; rel=preload; as=style", "</script.js>; rel=preload; as=script", "</foo.js>; rel=preload; as=script"}, header["Link"]) + default: + t.Error("Unexpected 1xx response") + } + + respCounter++ + + return nil + }, + } + req, _ := http.NewRequestWithContext(httptrace.WithClientTrace(context.Background(), trace), http.MethodGet, frontend.URL, nil) + + res, err := frontendClient.Do(req) + assert.Nil(t, err) + + defer res.Body.Close() + + if respCounter != 2 { + t.Errorf("Expected 2 1xx responses; got %d", respCounter) + } + checkLinkHeaders(t, []string{"</style.css>; rel=preload; as=style", "</script.js>; rel=preload; as=script", "</foo.js>; rel=preload; as=script"}, res.Header["Link"]) + + body, _ := io.ReadAll(res.Body) + if string(body) != "Hello" { + t.Errorf("Read body %q; want Hello", body) + } +} + func TestManager_Build(t *testing.T) { testCases := []struct { desc string diff --git a/pkg/server/service/smart_roundtripper.go b/pkg/server/service/smart_roundtripper.go index 5643e60edf04d222afa144964915b74cbbddd985..3b88b499a19d024a10d4e1463bc9ca3538010b0e 100644 --- a/pkg/server/service/smart_roundtripper.go +++ b/pkg/server/service/smart_roundtripper.go @@ -6,7 +6,7 @@ import ( "net/http" "time" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" "golang.org/x/net/http/httpguts" "golang.org/x/net/http2" ) diff --git a/pkg/server/service/tcp/service.go b/pkg/server/service/tcp/service.go index d099af5010844f1b016acbce72d42d3d23b723b5..bbc19b8cdc22a672e09dae4de5d4a951c2df3a48 100644 --- a/pkg/server/service/tcp/service.go +++ b/pkg/server/service/tcp/service.go @@ -9,23 +9,25 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/server/provider" - "github.com/traefik/traefik/v2/pkg/tcp" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/tcp" ) // Manager is the TCPHandlers factory. type Manager struct { - configs map[string]*runtime.TCPServiceInfo - rand *rand.Rand // For the initial shuffling of load-balancers. + dialerManager *tcp.DialerManager + configs map[string]*runtime.TCPServiceInfo + rand *rand.Rand // For the initial shuffling of load-balancers. } // NewManager creates a new manager. -func NewManager(conf *runtime.Configuration) *Manager { +func NewManager(conf *runtime.Configuration, dialerManager *tcp.DialerManager) *Manager { return &Manager{ - configs: conf.TCPServices, - rand: rand.New(rand.NewSource(time.Now().UnixNano())), + dialerManager: dialerManager, + configs: conf.TCPServices, + rand: rand.New(rand.NewSource(time.Now().UnixNano())), } } @@ -51,11 +53,9 @@ func (m *Manager) BuildTCP(rootCtx context.Context, serviceName string) (tcp.Han case conf.LoadBalancer != nil: loadBalancer := tcp.NewWRRLoadBalancer() - if conf.LoadBalancer.TerminationDelay == nil { - defaultTerminationDelay := 100 - conf.LoadBalancer.TerminationDelay = &defaultTerminationDelay + if len(conf.LoadBalancer.ServersTransport) > 0 { + conf.LoadBalancer.ServersTransport = provider.GetQualifiedName(ctx, conf.LoadBalancer.ServersTransport) } - duration := time.Duration(*conf.LoadBalancer.TerminationDelay) * time.Millisecond for index, server := range shuffle(conf.LoadBalancer.Servers, m.rand) { srvLogger := logger.With(). @@ -67,7 +67,12 @@ func (m *Manager) BuildTCP(rootCtx context.Context, serviceName string) (tcp.Han continue } - handler, err := tcp.NewProxy(server.Address, duration, conf.LoadBalancer.ProxyProtocol) + dialer, err := m.dialerManager.Get(conf.LoadBalancer.ServersTransport, server.TLS) + if err != nil { + return nil, err + } + + handler, err := tcp.NewProxy(server.Address, conf.LoadBalancer.ProxyProtocol, dialer) if err != nil { srvLogger.Error().Err(err).Msg("Failed to create server") continue diff --git a/pkg/server/service/tcp/service_test.go b/pkg/server/service/tcp/service_test.go index fc6c4702c2cae5a33aefcdd893d645a0b5fc6f18..cb94becb4baac7c7cfb494227a369a22e3a34ef8 100644 --- a/pkg/server/service/tcp/service_test.go +++ b/pkg/server/service/tcp/service_test.go @@ -6,9 +6,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/tcp" ) func TestManager_BuildTCP(t *testing.T) { @@ -16,6 +17,7 @@ func TestManager_BuildTCP(t *testing.T) { desc string serviceName string configs map[string]*runtime.TCPServiceInfo + stConfigs map[string]*dynamic.TCPServersTransport providerName string expectedError string }{ @@ -38,6 +40,7 @@ func TestManager_BuildTCP(t *testing.T) { { desc: "no such host, server is skipped, error is logged", serviceName: "test", + stConfigs: map[string]*dynamic.TCPServersTransport{"default@internal": {}}, configs: map[string]*runtime.TCPServiceInfo{ "test": { TCPService: &dynamic.TCPService{ @@ -102,6 +105,7 @@ func TestManager_BuildTCP(t *testing.T) { { desc: "Server with correct host:port as address", serviceName: "serviceName", + stConfigs: map[string]*dynamic.TCPServersTransport{"default@internal": {}}, configs: map[string]*runtime.TCPServiceInfo{ "serviceName@provider-1": { TCPService: &dynamic.TCPService{ @@ -120,6 +124,7 @@ func TestManager_BuildTCP(t *testing.T) { { desc: "Server with correct ip:port as address", serviceName: "serviceName", + stConfigs: map[string]*dynamic.TCPServersTransport{"default@internal": {}}, configs: map[string]*runtime.TCPServiceInfo{ "serviceName@provider-1": { TCPService: &dynamic.TCPService{ @@ -135,6 +140,24 @@ func TestManager_BuildTCP(t *testing.T) { }, providerName: "provider-1", }, + { + desc: "empty server address, server is skipped, error is logged", + serviceName: "serviceName", + configs: map[string]*runtime.TCPServiceInfo{ + "serviceName@provider-1": { + TCPService: &dynamic.TCPService{ + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{ + { + Address: "", + }, + }, + }, + }, + }, + }, + providerName: "provider-1", + }, { desc: "missing port in address with hostname, server is skipped, error is logged", serviceName: "serviceName", @@ -171,6 +194,46 @@ func TestManager_BuildTCP(t *testing.T) { }, providerName: "provider-1", }, + { + desc: "user defined serversTransport reference", + serviceName: "serviceName", + stConfigs: map[string]*dynamic.TCPServersTransport{"myServersTransport@provider-1": {}}, + configs: map[string]*runtime.TCPServiceInfo{ + "serviceName@provider-1": { + TCPService: &dynamic.TCPService{ + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{ + { + Address: "192.168.0.12:80", + }, + }, + ServersTransport: "myServersTransport@provider-1", + }, + }, + }, + }, + providerName: "provider-1", + }, + { + desc: "user defined serversTransport reference not found", + serviceName: "serviceName", + configs: map[string]*runtime.TCPServiceInfo{ + "serviceName@provider-1": { + TCPService: &dynamic.TCPService{ + LoadBalancer: &dynamic.TCPServersLoadBalancer{ + Servers: []dynamic.TCPServer{ + { + Address: "192.168.0.12:80", + }, + }, + ServersTransport: "myServersTransport@provider-1", + }, + }, + }, + }, + providerName: "provider-1", + expectedError: "TCP dialer not found myServersTransport@provider-1", + }, } for _, test := range testCases { @@ -178,9 +241,14 @@ func TestManager_BuildTCP(t *testing.T) { t.Run(test.desc, func(t *testing.T) { t.Parallel() + dialerManager := tcp.NewDialerManager(nil) + if test.stConfigs != nil { + dialerManager.Update(test.stConfigs) + } + manager := NewManager(&runtime.Configuration{ TCPServices: test.configs, - }) + }, dialerManager) ctx := context.Background() if len(test.providerName) > 0 { diff --git a/pkg/server/service/udp/service.go b/pkg/server/service/udp/service.go index 7d15c19ff6b41db2d982d047fff84ef2b9f2fadc..1772c195431f5d30f93fd4aa13eb6eca29bebe65 100644 --- a/pkg/server/service/udp/service.go +++ b/pkg/server/service/udp/service.go @@ -9,10 +9,10 @@ import ( "time" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/server/provider" - "github.com/traefik/traefik/v2/pkg/udp" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/udp" ) // Manager handles UDP services creation. diff --git a/pkg/server/service/udp/service_test.go b/pkg/server/service/udp/service_test.go index 335a13a24ae79078192459e03f7ef28d2b2d949a..6517c66a142fb76ea9c6c65eb71a123b8378adc3 100644 --- a/pkg/server/service/udp/service_test.go +++ b/pkg/server/service/udp/service_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" - "github.com/traefik/traefik/v2/pkg/config/runtime" - "github.com/traefik/traefik/v2/pkg/server/provider" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/runtime" + "github.com/traefik/traefik/v3/pkg/server/provider" ) func TestManager_BuildUDP(t *testing.T) { diff --git a/pkg/tcp/dialer.go b/pkg/tcp/dialer.go new file mode 100644 index 0000000000000000000000000000000000000000..267d1b05bae4394e4b53e8b344e3dd87143e46dc --- /dev/null +++ b/pkg/tcp/dialer.go @@ -0,0 +1,205 @@ +package tcp + +import ( + "crypto/tls" + "crypto/x509" + "errors" + "fmt" + "net" + "sync" + "time" + + "github.com/rs/zerolog/log" + "github.com/spiffe/go-spiffe/v2/bundle/x509bundle" + "github.com/spiffe/go-spiffe/v2/spiffeid" + "github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig" + "github.com/spiffe/go-spiffe/v2/svid/x509svid" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" + "golang.org/x/net/proxy" +) + +type Dialer interface { + proxy.Dialer + + TerminationDelay() time.Duration +} + +type tcpDialer struct { + proxy.Dialer + terminationDelay time.Duration +} + +func (d tcpDialer) TerminationDelay() time.Duration { + return d.terminationDelay +} + +// SpiffeX509Source allows to retrieve a x509 SVID and bundle. +type SpiffeX509Source interface { + x509svid.Source + x509bundle.Source +} + +// DialerManager handles dialer for the reverse proxy. +type DialerManager struct { + rtLock sync.RWMutex + dialers map[string]Dialer + dialersTLS map[string]Dialer + spiffeX509Source SpiffeX509Source +} + +// NewDialerManager creates a new DialerManager. +func NewDialerManager(spiffeX509Source SpiffeX509Source) *DialerManager { + return &DialerManager{ + dialers: make(map[string]Dialer), + dialersTLS: make(map[string]Dialer), + spiffeX509Source: spiffeX509Source, + } +} + +// Update updates the dialers configurations. +func (d *DialerManager) Update(configs map[string]*dynamic.TCPServersTransport) { + d.rtLock.Lock() + defer d.rtLock.Unlock() + + d.dialers = make(map[string]Dialer) + d.dialersTLS = make(map[string]Dialer) + for configName, config := range configs { + if err := d.createDialers(configName, config); err != nil { + log.Debug(). + Str("dialer", configName). + Err(err). + Msg("Create TCP Dialer") + } + } +} + +// Get gets a dialer by name. +func (d *DialerManager) Get(name string, tls bool) (Dialer, error) { + if len(name) == 0 { + name = "default@internal" + } + + d.rtLock.RLock() + defer d.rtLock.RUnlock() + + if tls { + if rt, ok := d.dialersTLS[name]; ok { + return rt, nil + } + + return nil, fmt.Errorf("TCP dialer not found %s", name) + } + + if rt, ok := d.dialers[name]; ok { + return rt, nil + } + + return nil, fmt.Errorf("TCP dialer not found %s", name) +} + +// createDialers creates the dialers according to the TCPServersTransport configuration. +func (d *DialerManager) createDialers(name string, cfg *dynamic.TCPServersTransport) error { + if cfg == nil { + return errors.New("no transport configuration given") + } + + dialer := &net.Dialer{ + Timeout: time.Duration(cfg.DialTimeout), + KeepAlive: time.Duration(cfg.DialKeepAlive), + } + + var tlsConfig *tls.Config + + if cfg.TLS != nil { + if cfg.TLS.Spiffe != nil { + if d.spiffeX509Source == nil { + return errors.New("SPIFFE is enabled for this transport, but not configured") + } + + authorizer, err := buildSpiffeAuthorizer(cfg.TLS.Spiffe) + if err != nil { + return fmt.Errorf("unable to build SPIFFE authorizer: %w", err) + } + + tlsConfig = tlsconfig.MTLSClientConfig(d.spiffeX509Source, d.spiffeX509Source, authorizer) + } + + if cfg.TLS.InsecureSkipVerify || len(cfg.TLS.RootCAs) > 0 || len(cfg.TLS.ServerName) > 0 || len(cfg.TLS.Certificates) > 0 || cfg.TLS.PeerCertURI != "" { + if tlsConfig != nil { + return errors.New("TLS and SPIFFE configuration cannot be defined at the same time") + } + + tlsConfig = &tls.Config{ + ServerName: cfg.TLS.ServerName, + InsecureSkipVerify: cfg.TLS.InsecureSkipVerify, + RootCAs: createRootCACertPool(cfg.TLS.RootCAs), + Certificates: cfg.TLS.Certificates.GetCertificates(), + } + + if cfg.TLS.PeerCertURI != "" { + tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error { + return traefiktls.VerifyPeerCertificate(cfg.TLS.PeerCertURI, tlsConfig, rawCerts) + } + } + } + } + + tlsDialer := &tls.Dialer{ + NetDialer: dialer, + Config: tlsConfig, + } + + d.dialers[name] = tcpDialer{dialer, time.Duration(cfg.TerminationDelay)} + d.dialersTLS[name] = tcpDialer{tlsDialer, time.Duration(cfg.TerminationDelay)} + + return nil +} + +func createRootCACertPool(rootCAs []traefiktls.FileOrContent) *x509.CertPool { + if len(rootCAs) == 0 { + return nil + } + + roots := x509.NewCertPool() + + for _, cert := range rootCAs { + certContent, err := cert.Read() + if err != nil { + log.Err(err).Msg("Error while read RootCAs") + continue + } + + roots.AppendCertsFromPEM(certContent) + } + + return roots +} + +func buildSpiffeAuthorizer(cfg *dynamic.Spiffe) (tlsconfig.Authorizer, error) { + switch { + case len(cfg.IDs) > 0: + spiffeIDs := make([]spiffeid.ID, 0, len(cfg.IDs)) + for _, rawID := range cfg.IDs { + id, err := spiffeid.FromString(rawID) + if err != nil { + return nil, fmt.Errorf("invalid SPIFFE ID: %w", err) + } + + spiffeIDs = append(spiffeIDs, id) + } + + return tlsconfig.AuthorizeOneOf(spiffeIDs...), nil + + case cfg.TrustDomain != "": + trustDomain, err := spiffeid.TrustDomainFromString(cfg.TrustDomain) + if err != nil { + return nil, fmt.Errorf("invalid SPIFFE trust domain: %w", err) + } + + return tlsconfig.AuthorizeMemberOf(trustDomain), nil + + default: + return tlsconfig.AuthorizeAny(), nil + } +} diff --git a/pkg/tcp/dialer_test.go b/pkg/tcp/dialer_test.go new file mode 100644 index 0000000000000000000000000000000000000000..603f012b59fb7019ad8fa9664cebc60f62e45106 --- /dev/null +++ b/pkg/tcp/dialer_test.go @@ -0,0 +1,593 @@ +package tcp + +import ( + "bytes" + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "io" + "math/big" + "net" + "net/url" + "testing" + "time" + + "github.com/spiffe/go-spiffe/v2/bundle/x509bundle" + "github.com/spiffe/go-spiffe/v2/spiffeid" + "github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig" + "github.com/spiffe/go-spiffe/v2/svid/x509svid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/traefik/traefik/v3/pkg/config/dynamic" + traefiktls "github.com/traefik/traefik/v3/pkg/tls" +) + +// LocalhostCert is a PEM-encoded TLS cert +// for host example.com, www.example.com +// expiring at Jan 29 16:00:00 2084 GMT. +// go run $GOROOT/src/crypto/tls/generate_cert.go --rsa-bits 1024 --host example.com,www.example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h +var LocalhostCert = []byte(`-----BEGIN CERTIFICATE----- +MIICDDCCAXWgAwIBAgIQH20JmcOlcRWHNuf62SYwszANBgkqhkiG9w0BAQsFADAS +MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw +MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB +iQKBgQC0qINy3F4oq6viDnlpDDE5J08iSRGggg6EylJKBKZfphEG2ufgK78Dufl3 ++7b0LlEY2AeZHwviHODqC9a6ihj1ZYQk0/djAh+OeOhFEWu+9T/VP8gVFarFqT8D +Opy+hrG7YJivUIzwb4fmJQRI7FajzsnGyM6LiXLU+0qzb7ZO/QIDAQABo2EwXzAO +BgNVHQ8BAf8EBAMCAqQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUw +AwEB/zAnBgNVHREEIDAeggtleGFtcGxlLmNvbYIPd3d3LmV4YW1wbGUuY29tMA0G +CSqGSIb3DQEBCwUAA4GBAB+eluoQYzyyMfeEEAOtlldevx5MtDENT05NB0WI+91R +we7mX8lv763u0XuCWPxbHszhclI6FFjoQef0Z1NYLRm8ZRq58QqWDFZ3E6wdDK+B ++OWvkW+hRavo6R9LzIZPfbv8yBo4M9PK/DXw8hLqH7VkkI+Gh793iH7Ugd4A7wvT +-----END CERTIFICATE-----`) + +// LocalhostKey is the private key for localhostCert. +var LocalhostKey = []byte(`-----BEGIN PRIVATE KEY----- +MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALSog3LcXiirq+IO +eWkMMTknTyJJEaCCDoTKUkoEpl+mEQba5+ArvwO5+Xf7tvQuURjYB5kfC+Ic4OoL +1rqKGPVlhCTT92MCH4546EURa771P9U/yBUVqsWpPwM6nL6GsbtgmK9QjPBvh+Yl +BEjsVqPOycbIzouJctT7SrNvtk79AgMBAAECgYB1wMT1MBgbkFIXpXGTfAP1id61 +rUTVBxCpkypx3ngHLjo46qRq5Hi72BN4FlTY8fugIudI8giP2FztkMvkiLDc4m0p +Gn+QMJzjlBjjTuNLvLy4aSmNRLIC3mtbx9PdU71DQswEpJHFj/vmsxbuSrG1I1YE +r1reuSo2ow6fOAjXLQJBANpz+RkOiPSPuvl+gi1sp2pLuynUJVDVqWZi386YRpfg +DiKCLpqwqYDkOozm/fwFALvwXKGmsyyL43HO8eI+2NsCQQDTtY32V+02GPecdsyq +msK06EPVTSaYwj9Mm+q709KsmYFHLXDqXjcKV4UgKYKRPz7my1fXodMmGmfuh1a3 +/HMHAkEAmOQKN0tA90mRJwUvvvMIyRBv0fq0kzq28P3KfiF9ZtZdjjFmxMVYHOmf +QPZ6VGR7+w1jB5BQXqEZcpHQIPSzeQJBAIy9tZJ/AYNlNbcegxEnsSjy/6VdlLsY +51vWi0Yym2uC4R6gZuBnoc+OP0ISVmqY0Qg9RjhjrCs4gr9f2ZaWjSECQCxqZMq1 +3viJ8BGCC0m/5jv1EHur3YgwphYCkf4Li6DKwIdMLk1WXkTcPIY3V2Jqj8rPEB5V +rqPRSAtd/h6oZbs= +-----END PRIVATE KEY-----`) + +// openssl req -newkey rsa:2048 \ +// -new -nodes -x509 \ +// -days 3650 \ +// -out cert.pem \ +// -keyout key.pem \ +// -subj "/CN=example.com" +// -addext "subjectAltName = DNS:example.com" +var mTLSCert = []byte(`-----BEGIN CERTIFICATE----- +MIIDJTCCAg2gAwIBAgIUYKnGcLnmMosOSKqTn4ydAMURE4gwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wHhcNMjAwODEzMDkyNzIwWhcNMzAw +ODExMDkyNzIwWjAWMRQwEgYDVQQDDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAOAe+QM1c9lZ2TPRgoiuPAq2A3Pfu+i82lmqrTJ0 +PR2Cx1fPbccCUTFJPlxSDiaMrwtvqw1yP9L2Pu/vJK5BY4YDVDtFGKjpRBau1otJ +iY50O5qMo3sfLqR4/1VsQGlLVZYLD3dyc4ZTmOp8+7tJ2SyGorojbIKfimZT7XD7 +dzrVr4h4Gn+SzzOnoKyx29uaNRP+XuMYHmHyQcJE03pUGhkTOvMwBlF96QdQ9WG0 +D+1CxRciEsZXE+imKBHoaTgrTkpnFHzsrIEw+OHQYf30zuT/k/lkgv1vqEwINHjz +W2VeTur5eqVvA7zZdoEXMRy7BUvh/nZk5AXkXAmZLn0eUg8CAwEAAaNrMGkwHQYD +VR0OBBYEFEDrbhPDt+hi3ZOzk6S/CFAVHwk0MB8GA1UdIwQYMBaAFEDrbhPDt+hi +3ZOzk6S/CFAVHwk0MA8GA1UdEwEB/wQFMAMBAf8wFgYDVR0RBA8wDYILZXhhbXBs +ZS5jb20wDQYJKoZIhvcNAQELBQADggEBAG/JRJWeUNx2mDJAk8W7Syq3gmQB7s9f ++yY/XVRJZGahOPilABqFpC6GVn2HWuvuOqy8/RGk9ja5abKVXqE6YKrljqo3XfzB +KQcOz4SFirpkHvNCiEcK3kggN3wJWqL2QyXAxWldBBBCO9yx7a3cux31C//sTUOG +xq4JZDg171U1UOpfN1t0BFMdt05XZFEM247N7Dcf7HoXwAa7eyLKgtKWqPDqGrFa +fvGDDKK9X/KVsU2x9V3pG+LsJg7ogUnSyD2r5G1F3Y8OVs2T/783PaN0M35fDL38 +09VbsxA2GasOHZrghUzT4UvZWWZbWEmG975hFYvdj6DlK9K0s5TdKIs= +-----END CERTIFICATE-----`) + +var mTLSKey = []byte(`-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDgHvkDNXPZWdkz +0YKIrjwKtgNz37vovNpZqq0ydD0dgsdXz23HAlExST5cUg4mjK8Lb6sNcj/S9j7v +7ySuQWOGA1Q7RRio6UQWrtaLSYmOdDuajKN7Hy6keP9VbEBpS1WWCw93cnOGU5jq +fPu7SdkshqK6I2yCn4pmU+1w+3c61a+IeBp/ks8zp6CssdvbmjUT/l7jGB5h8kHC +RNN6VBoZEzrzMAZRfekHUPVhtA/tQsUXIhLGVxPopigR6Gk4K05KZxR87KyBMPjh +0GH99M7k/5P5ZIL9b6hMCDR481tlXk7q+XqlbwO82XaBFzEcuwVL4f52ZOQF5FwJ +mS59HlIPAgMBAAECggEAAKLV3hZ2v7UrkqQTlMO50+X0WI3YAK8Yh4yedTgzPDQ0 +0KD8FMaC6HrmvGhXNfDMRmIIwD8Ew1qDjzbEieIRoD2+LXTivwf6c34HidmplEfs +K2IezKin/zuArgNio2ndUlGxt4sRnN373x5/sGZjQWcYayLSmgRN5kByuhFco0Qa +oSrXcXNUlb+KgRQXPDU4+M35tPHvLdyg+tko/m/5uK9dc9MNvGZHOMBKg0VNURJb +V1l3dR+evwvpqHzBvWiqN/YOiUUvIxlFKA35hJkfCl7ivFs4CLqqFNCKDao95fWe +s0UR9iMakT48jXV76IfwZnyX10OhIWzKls5trjDL8QKBgQD3thQJ8e0FL9y1W+Ph +mCdEaoffSPkgSn64wIsQ9bMmv4y+KYBK5AhqaHgYm4LgW4x1+CURNFu+YFEyaNNA +kNCXFyRX3Em3vxcShP5jIqg+f07mtXPKntWP/zBeKQWgdHX371oFTfaAlNuKX/7S +n0jBYjr4Iof1bnquMQvUoHCYWwKBgQDnntFU9/AQGaQIvhfeU1XKFkQ/BfhIsd27 +RlmiCi0ee9Ce74cMAhWr/9yg0XUxzrh+Ui1xnkMVTZ5P8tWIxROokznLUTGJA5rs +zB+ovCPFZcquTwNzn7SBnpHTR0OqJd8sd89P5ST2SqufeSF/gGi5sTs4EocOLCpZ +EPVIfm47XQKBgB4d5RHQeCDJUOw739jtxthqm1pqZN+oLwAHaOEG/mEXqOT15sM0 +NlG5oeBcB+1/M/Sj1t3gn8blrvmSBR00fifgiGqmPdA5S3TU9pjW/d2bXNxv80QP +S6fWPusz0ZtQjYc3cppygCXh808/nJu/AfmBF+pTSHRumjvTery/RPFBAoGBAMi/ +zCta4cTylEvHhqR5kiefePMu120aTFYeuV1KeKStJ7o5XNE5lVMIZk80e+D5jMpf +q2eIhhgWuBoPHKh4N3uqbzMbYlWgvEx09xOmTVKv0SWW8iTqzOZza2y1nZ4BSRcf +mJ1ku86EFZAYysHZp+saA3usA0ZzXRjpK87zVdM5AoGBAOSqI+t48PnPtaUDFdpd +taNNVDbcecJatm3w8VDWnarahfWe66FIqc9wUkqekqAgwZLa0AGdUalvXfGrHfNs +PtvuNc5EImfSkuPBYLBslNxtjbBvAYgacEdY+gRhn2TeIUApnND58lCWsKbNHLFZ +ajIPbTY+Fe9OTOFTN48ujXNn +-----END PRIVATE KEY-----`) + +func TestConflictingConfig(t *testing.T) { + dialerManager := NewDialerManager(nil) + + dynamicConf := map[string]*dynamic.TCPServersTransport{ + "test": { + TLS: &dynamic.TLSClientConfig{ + ServerName: "foobar", + Spiffe: &dynamic.Spiffe{}, + }, + }, + } + + dialerManager.Update(dynamicConf) + + _, err := dialerManager.Get("test", false) + require.Error(t, err) +} + +func TestNoTLS(t *testing.T) { + backendListener, err := net.Listen("tcp", ":0") + require.NoError(t, err) + defer backendListener.Close() + + go fakeRedis(t, backendListener) + + _, port, err := net.SplitHostPort(backendListener.Addr().String()) + require.NoError(t, err) + + dialerManager := NewDialerManager(nil) + + dynamicConf := map[string]*dynamic.TCPServersTransport{ + "test": { + TLS: &dynamic.TLSClientConfig{}, + }, + } + + dialerManager.Update(dynamicConf) + + dialer, err := dialerManager.Get("test", false) + require.NoError(t, err) + + conn, err := dialer.Dial("tcp", ":"+port) + require.NoError(t, err) + + _, err = conn.Write([]byte("ping\n")) + require.NoError(t, err) + + buf := make([]byte, 64) + n, err := conn.Read(buf) + require.NoError(t, err) + + assert.Equal(t, 4, n) + assert.Equal(t, "PONG", string(buf[:4])) + + err = conn.Close() + require.NoError(t, err) +} + +func TestTLS(t *testing.T) { + cert, err := tls.X509KeyPair(LocalhostCert, LocalhostKey) + require.NoError(t, err) + + backendListener, err := net.Listen("tcp", ":0") + require.NoError(t, err) + defer backendListener.Close() + + tlsListener := tls.NewListener(backendListener, &tls.Config{Certificates: []tls.Certificate{cert}}) + defer tlsListener.Close() + + go fakeRedis(t, tlsListener) + + _, port, err := net.SplitHostPort(tlsListener.Addr().String()) + require.NoError(t, err) + + dialerManager := NewDialerManager(nil) + + dynamicConf := map[string]*dynamic.TCPServersTransport{ + "test": { + TLS: &dynamic.TLSClientConfig{ + ServerName: "example.com", + RootCAs: []traefiktls.FileOrContent{traefiktls.FileOrContent(LocalhostCert)}, + }, + }, + } + + dialerManager.Update(dynamicConf) + + dialer, err := dialerManager.Get("test", true) + require.NoError(t, err) + + conn, err := dialer.Dial("tcp", ":"+port) + require.NoError(t, err) + + _, err = conn.Write([]byte("ping\n")) + require.NoError(t, err) + + err = conn.(*tls.Conn).CloseWrite() + require.NoError(t, err) + + var buf []byte + buffer := bytes.NewBuffer(buf) + n, err := io.Copy(buffer, conn) + require.NoError(t, err) + + assert.Equal(t, int64(4), n) + assert.Equal(t, "PONG", buffer.String()) +} + +func TestTLSWithInsecureSkipVerify(t *testing.T) { + cert, err := tls.X509KeyPair(LocalhostCert, LocalhostKey) + require.NoError(t, err) + + backendListener, err := net.Listen("tcp", ":0") + require.NoError(t, err) + defer backendListener.Close() + + tlsListener := tls.NewListener(backendListener, &tls.Config{Certificates: []tls.Certificate{cert}}) + defer tlsListener.Close() + + go fakeRedis(t, tlsListener) + + _, port, err := net.SplitHostPort(tlsListener.Addr().String()) + require.NoError(t, err) + + dialerManager := NewDialerManager(nil) + + dynamicConf := map[string]*dynamic.TCPServersTransport{ + "test": { + TLS: &dynamic.TLSClientConfig{ + ServerName: "bad-domain.com", + RootCAs: []traefiktls.FileOrContent{traefiktls.FileOrContent(LocalhostCert)}, + InsecureSkipVerify: true, + }, + }, + } + + dialerManager.Update(dynamicConf) + + dialer, err := dialerManager.Get("test", true) + require.NoError(t, err) + + conn, err := dialer.Dial("tcp", ":"+port) + require.NoError(t, err) + + _, err = conn.Write([]byte("ping\n")) + require.NoError(t, err) + + err = conn.(*tls.Conn).CloseWrite() + require.NoError(t, err) + + var buf []byte + buffer := bytes.NewBuffer(buf) + n, err := io.Copy(buffer, conn) + require.NoError(t, err) + + assert.Equal(t, int64(4), n) + assert.Equal(t, "PONG", buffer.String()) +} + +func TestMTLS(t *testing.T) { + cert, err := tls.X509KeyPair(LocalhostCert, LocalhostKey) + require.NoError(t, err) + + clientPool := x509.NewCertPool() + clientPool.AppendCertsFromPEM(mTLSCert) + + backendListener, err := net.Listen("tcp", ":0") + require.NoError(t, err) + defer backendListener.Close() + + tlsListener := tls.NewListener(backendListener, &tls.Config{ + // For TLS + Certificates: []tls.Certificate{cert}, + + // For mTLS + ClientAuth: tls.RequireAndVerifyClientCert, + ClientCAs: clientPool, + }) + defer tlsListener.Close() + + go fakeRedis(t, tlsListener) + + _, port, err := net.SplitHostPort(tlsListener.Addr().String()) + require.NoError(t, err) + + dialerManager := NewDialerManager(nil) + + dynamicConf := map[string]*dynamic.TCPServersTransport{ + "test": { + TLS: &dynamic.TLSClientConfig{ + ServerName: "example.com", + // For TLS + RootCAs: []traefiktls.FileOrContent{traefiktls.FileOrContent(LocalhostCert)}, + + // For mTLS + Certificates: traefiktls.Certificates{ + traefiktls.Certificate{ + CertFile: traefiktls.FileOrContent(mTLSCert), + KeyFile: traefiktls.FileOrContent(mTLSKey), + }, + }, + }, + }, + } + + dialerManager.Update(dynamicConf) + + dialer, err := dialerManager.Get("test", true) + require.NoError(t, err) + + conn, err := dialer.Dial("tcp", ":"+port) + require.NoError(t, err) + + _, err = conn.Write([]byte("ping\n")) + require.NoError(t, err) + + err = conn.(*tls.Conn).CloseWrite() + require.NoError(t, err) + + var buf []byte + buffer := bytes.NewBuffer(buf) + n, err := io.Copy(buffer, conn) + require.NoError(t, err) + + assert.Equal(t, int64(4), n) + assert.Equal(t, "PONG", buffer.String()) +} + +func TestSpiffeMTLS(t *testing.T) { + backendListener, err := net.Listen("tcp", ":0") + require.NoError(t, err) + defer backendListener.Close() + + trustDomain := spiffeid.RequireTrustDomainFromString("spiffe://traefik.test") + + pki := newFakeSpiffePKI(t, trustDomain) + + serverSVID := pki.genSVID(t, spiffeid.RequireFromPath(trustDomain, "/server")) + require.NoError(t, err) + + serverSource := fakeSpiffeSource{ + svid: serverSVID, + bundle: pki.bundle, + } + + // go-spiffe's `tlsconfig.MTLSServerConfig` (that should be used here) does not set a certificate on + // the returned `tls.Config` and relies instead on `GetCertificate` being always called. + // But it turns out that `StartTLS` from `httptest.Server`, enforces a default certificate + // if no certificate is previously set on the configured TLS config. + // It makes the test server always serve the httptest default certificate, and not the SPIFFE certificate, + // as GetCertificate is in that case never called (there's a default cert, and SNI is not used). + // To bypass this issue, we're manually extracting the server ceritificate from the server SVID + // and use another initialization method that forces serving the server SPIFFE certificate. + serverCert, err := tlsconfig.GetCertificate(&serverSource)(nil) + require.NoError(t, err) + + tlsListener := tls.NewListener(backendListener, tlsconfig.MTLSWebServerConfig( + serverCert, + &serverSource, + tlsconfig.AuthorizeAny(), + )) + defer tlsListener.Close() + + _, port, err := net.SplitHostPort(tlsListener.Addr().String()) + require.NoError(t, err) + + clientSVID := pki.genSVID(t, spiffeid.RequireFromPath(trustDomain, "/client")) + + clientSource := fakeSpiffeSource{ + svid: clientSVID, + bundle: pki.bundle, + } + + testCases := []struct { + desc string + config dynamic.Spiffe + clientSource SpiffeX509Source + wantError bool + }{ + { + desc: "supports SPIFFE mTLS", + config: dynamic.Spiffe{}, + clientSource: &clientSource, + }, + { + desc: "allows expected server SPIFFE ID", + config: dynamic.Spiffe{ + IDs: []string{"spiffe://traefik.test/server"}, + }, + clientSource: &clientSource, + }, + { + desc: "blocks unexpected server SPIFFE ID", + config: dynamic.Spiffe{ + IDs: []string{"spiffe://traefik.test/not-server"}, + }, + clientSource: &clientSource, + wantError: true, + }, + { + desc: "allows expected server trust domain", + config: dynamic.Spiffe{ + TrustDomain: "spiffe://traefik.test", + }, + clientSource: &clientSource, + }, + { + desc: "denies unexpected server trust domain", + config: dynamic.Spiffe{ + TrustDomain: "spiffe://not-traefik.test", + }, + clientSource: &clientSource, + wantError: true, + }, + { + desc: "spiffe IDs allowlist takes precedence", + config: dynamic.Spiffe{ + IDs: []string{"spiffe://traefik.test/not-server"}, + TrustDomain: "spiffe://not-traefik.test", + }, + clientSource: &clientSource, + wantError: true, + }, + } + + for _, test := range testCases { + t.Run(test.desc, func(t *testing.T) { + go fakeRedis(t, tlsListener) + + dialerManager := NewDialerManager(test.clientSource) + + dynamicConf := map[string]*dynamic.TCPServersTransport{ + "test": { + TLS: &dynamic.TLSClientConfig{ + Spiffe: &test.config, + }, + }, + } + + dialerManager.Update(dynamicConf) + + dialer, err := dialerManager.Get("test", true) + require.NoError(t, err) + + conn, err := dialer.Dial("tcp", ":"+port) + + if test.wantError { + require.Error(t, err) + return + } + + require.NoError(t, err) + + _, err = conn.Write([]byte("ping\n")) + require.NoError(t, err) + + err = conn.(*tls.Conn).CloseWrite() + require.NoError(t, err) + + var buf []byte + buffer := bytes.NewBuffer(buf) + n, err := io.Copy(buffer, conn) + require.NoError(t, err) + + assert.Equal(t, int64(4), n) + assert.Equal(t, "PONG", buffer.String()) + }) + } +} + +// fakeSpiffePKI simulates a SPIFFE aware PKI and allows generating multiple valid SVIDs. +type fakeSpiffePKI struct { + caPrivateKey *rsa.PrivateKey + + bundle *x509bundle.Bundle +} + +func newFakeSpiffePKI(t *testing.T, trustDomain spiffeid.TrustDomain) fakeSpiffePKI { + t.Helper() + + caPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048) + require.NoError(t, err) + + caTemplate := x509.Certificate{ + SerialNumber: big.NewInt(2000), + Subject: pkix.Name{ + Organization: []string{"spiffe"}, + }, + URIs: []*url.URL{spiffeid.RequireFromPath(trustDomain, "/ca").URL()}, + NotBefore: time.Now(), + NotAfter: time.Now().Add(time.Hour), + SubjectKeyId: []byte("ca"), + KeyUsage: x509.KeyUsageCertSign | + x509.KeyUsageCRLSign, + BasicConstraintsValid: true, + IsCA: true, + PublicKey: caPrivateKey.Public(), + } + + caCertDER, err := x509.CreateCertificate( + rand.Reader, + &caTemplate, + &caTemplate, + caPrivateKey.Public(), + caPrivateKey, + ) + require.NoError(t, err) + + bundle, err := x509bundle.ParseRaw( + trustDomain, + caCertDER, + ) + require.NoError(t, err) + + return fakeSpiffePKI{ + bundle: bundle, + caPrivateKey: caPrivateKey, + } +} + +func (f *fakeSpiffePKI) genSVID(t *testing.T, id spiffeid.ID) *x509svid.SVID { + t.Helper() + + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + require.NoError(t, err) + + template := x509.Certificate{ + SerialNumber: big.NewInt(200001), + URIs: []*url.URL{id.URL()}, + NotBefore: time.Now(), + NotAfter: time.Now().Add(time.Hour), + SubjectKeyId: []byte("svid"), + KeyUsage: x509.KeyUsageKeyEncipherment | + x509.KeyUsageKeyAgreement | + x509.KeyUsageDigitalSignature, + ExtKeyUsage: []x509.ExtKeyUsage{ + x509.ExtKeyUsageServerAuth, + x509.ExtKeyUsageClientAuth, + }, + BasicConstraintsValid: true, + PublicKey: privateKey.PublicKey, + IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, + } + + certDER, err := x509.CreateCertificate( + rand.Reader, + &template, + f.bundle.X509Authorities()[0], + privateKey.Public(), + f.caPrivateKey, + ) + require.NoError(t, err) + + keyPKCS8, err := x509.MarshalPKCS8PrivateKey(privateKey) + require.NoError(t, err) + + svid, err := x509svid.ParseRaw(certDER, keyPKCS8) + require.NoError(t, err) + + return svid +} + +// fakeSpiffeSource allows retrieving staticly an SVID and its associated bundle. +type fakeSpiffeSource struct { + bundle *x509bundle.Bundle + svid *x509svid.SVID +} + +func (s *fakeSpiffeSource) GetX509BundleForTrustDomain(trustDomain spiffeid.TrustDomain) (*x509bundle.Bundle, error) { + return s.bundle, nil +} + +func (s *fakeSpiffeSource) GetX509SVID() (*x509svid.SVID, error) { + return s.svid, nil +} diff --git a/pkg/tcp/proxy.go b/pkg/tcp/proxy.go index 525c43c4b1c7d664fd0c5dcdaa1154eaab6c4ddf..8f7e0574593c402abb0ae2f5efd8739352dfefbb 100644 --- a/pkg/tcp/proxy.go +++ b/pkg/tcp/proxy.go @@ -10,52 +10,42 @@ import ( "github.com/pires/go-proxyproto" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) // Proxy forwards a TCP request to a TCP service. type Proxy struct { - address string - tcpAddr *net.TCPAddr - terminationDelay time.Duration - proxyProtocol *dynamic.ProxyProtocol + address string + proxyProtocol *dynamic.ProxyProtocol + dialer Dialer } // NewProxy creates a new Proxy. -func NewProxy(address string, terminationDelay time.Duration, proxyProtocol *dynamic.ProxyProtocol) (*Proxy, error) { +func NewProxy(address string, proxyProtocol *dynamic.ProxyProtocol, dialer Dialer) (*Proxy, error) { if proxyProtocol != nil && (proxyProtocol.Version < 1 || proxyProtocol.Version > 2) { return nil, fmt.Errorf("unknown proxyProtocol version: %d", proxyProtocol.Version) } - // Creates the tcpAddr only for IP based addresses, - // because there is no need to resolve the name on every new connection, - // and building it should happen once. - var tcpAddr *net.TCPAddr - if host, _, err := net.SplitHostPort(address); err == nil && net.ParseIP(host) != nil { - tcpAddr, err = net.ResolveTCPAddr("tcp", address) - if err != nil { - return nil, err - } - } - return &Proxy{ - address: address, - tcpAddr: tcpAddr, - terminationDelay: terminationDelay, - proxyProtocol: proxyProtocol, + address: address, + proxyProtocol: proxyProtocol, + dialer: dialer, }, nil } // ServeTCP forwards the connection to a service. func (p *Proxy) ServeTCP(conn WriteCloser) { - log.Debug().Msgf("Handling connection from %s to %s", conn.RemoteAddr(), p.address) + log.Debug(). + Str("address", p.address). + Str("remoteAddr", conn.RemoteAddr().String()). + Msg("Handling TCP connection") // needed because of e.g. server.trackedConnection defer conn.Close() connBackend, err := p.dialBackend() if err != nil { - log.Error().Err(err).Msg("Error while connecting to backend") + log.Error().Err(err).Msg("Error while dialing backend") return } @@ -66,7 +56,7 @@ func (p *Proxy) ServeTCP(conn WriteCloser) { if p.proxyProtocol != nil && p.proxyProtocol.Version > 0 && p.proxyProtocol.Version < 3 { header := proxyproto.HeaderProxyFromAddrs(byte(p.proxyProtocol.Version), conn.RemoteAddr(), conn.LocalAddr()) if _, err := header.WriteTo(connBackend); err != nil { - log.Error().Err(err).Msg("Error while writing proxy protocol headers to backend connection") + log.Error().Err(err).Msg("Error while writing TCP proxy protocol headers to backend connection") return } } @@ -80,30 +70,22 @@ func (p *Proxy) ServeTCP(conn WriteCloser) { // This allows to not report an RST packet sent by the peer as an error, // as it is an abrupt but possible end for the TCP session if isReadConnResetError(err) { - log.Debug().Err(err).Msg("Error during connection") + log.Debug().Err(err).Msg("Error while handling TCP connection") } else { - log.Error().Err(err).Msg("Error during connection") + log.Error().Err(err).Msg("Error while handling TCP connection") } } <-errChan } -func (p Proxy) dialBackend() (*net.TCPConn, error) { - // Dial using directly the TCPAddr for IP based addresses. - if p.tcpAddr != nil { - return net.DialTCP("tcp", nil, p.tcpAddr) - } - - log.Debug().Msgf("Dial with lookup to address %s", p.address) - - // Dial with DNS lookup for host based addresses. - conn, err := net.Dial("tcp", p.address) +func (p Proxy) dialBackend() (WriteCloser, error) { + conn, err := p.dialer.Dial("tcp", p.address) if err != nil { return nil, err } - return conn.(*net.TCPConn), nil + return conn.(WriteCloser), nil } func (p Proxy) connCopy(dst, src WriteCloser, errCh chan error) { @@ -119,16 +101,16 @@ func (p Proxy) connCopy(dst, src WriteCloser, errCh chan error) { // In that case, logging the error is superfluous, // as in the first place we should not have needed to call CloseWrite. if !isSocketNotConnectedError(errClose) { - log.Debug().Err(errClose).Msg("Error while terminating connection") + log.Debug().Err(errClose).Msg("Error while terminating TCP connection") } return } - if p.terminationDelay >= 0 { - err := dst.SetReadDeadline(time.Now().Add(p.terminationDelay)) + if p.dialer.TerminationDelay() >= 0 { + err := dst.SetReadDeadline(time.Now().Add(p.dialer.TerminationDelay())) if err != nil { - log.Debug().Err(err).Msg("Error while setting deadline") + log.Debug().Err(err).Msg("Error while setting TCP connection deadline") } } } diff --git a/pkg/tcp/proxy_test.go b/pkg/tcp/proxy_test.go index fb8cad1dd2106c1592055e942c7b88f36dba0997..21176300c74dbb4e3eea742cfc96288e29b89881 100644 --- a/pkg/tcp/proxy_test.go +++ b/pkg/tcp/proxy_test.go @@ -3,7 +3,6 @@ package tcp import ( "bytes" "errors" - "fmt" "io" "net" "testing" @@ -12,7 +11,7 @@ import ( "github.com/pires/go-proxyproto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) func fakeRedis(t *testing.T, listener net.Listener) { @@ -20,7 +19,6 @@ func fakeRedis(t *testing.T, listener net.Listener) { for { conn, err := listener.Accept() - fmt.Println("Accept on server") require.NoError(t, err) for { @@ -54,7 +52,9 @@ func TestCloseWrite(t *testing.T) { _, port, err := net.SplitHostPort(backendListener.Addr().String()) require.NoError(t, err) - proxy, err := NewProxy(":"+port, 10*time.Millisecond, nil) + dialer := tcpDialer{&net.Dialer{}, 10 * time.Millisecond} + + proxy, err := NewProxy(":"+port, nil, dialer) require.NoError(t, err) proxyListener, err := net.Listen("tcp", ":0") @@ -133,7 +133,9 @@ func TestProxyProtocol(t *testing.T) { _, port, err := net.SplitHostPort(proxyBackendListener.Addr().String()) require.NoError(t, err) - proxy, err := NewProxy(":"+port, 10*time.Millisecond, &dynamic.ProxyProtocol{Version: test.version}) + dialer := tcpDialer{&net.Dialer{}, 10 * time.Millisecond} + + proxy, err := NewProxy(":"+port, &dynamic.ProxyProtocol{Version: test.version}, dialer) require.NoError(t, err) proxyListener, err := net.Listen("tcp", ":0") @@ -171,42 +173,3 @@ func TestProxyProtocol(t *testing.T) { }) } } - -func TestLookupAddress(t *testing.T) { - testCases := []struct { - desc string - address string - expectAddr assert.ComparisonAssertionFunc - expectRefresh assert.ValueAssertionFunc - }{ - { - desc: "IP doesn't need refresh", - address: "8.8.4.4:53", - expectAddr: assert.Equal, - expectRefresh: assert.NotNil, - }, - { - desc: "Hostname needs refresh", - address: "dns.google:53", - expectAddr: assert.NotEqual, - expectRefresh: assert.Nil, - }, - } - - for _, test := range testCases { - test := test - t.Run(test.desc, func(t *testing.T) { - t.Parallel() - - proxy, err := NewProxy(test.address, 10*time.Millisecond, nil) - require.NoError(t, err) - - test.expectRefresh(t, proxy.tcpAddr) - - conn, err := proxy.dialBackend() - require.NoError(t, err) - - test.expectAddr(t, test.address, conn.RemoteAddr().String()) - }) - } -} diff --git a/pkg/tcp/switcher.go b/pkg/tcp/switcher.go index 557f663a164f1cc7125cc1adc46a955d5f02b99e..0b62bab8c27bb8c247915be6806e0261f94c7d4f 100644 --- a/pkg/tcp/switcher.go +++ b/pkg/tcp/switcher.go @@ -1,7 +1,7 @@ package tcp import ( - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/safe" ) // HandlerSwitcher is a TCP handler switcher. diff --git a/pkg/testhelpers/config.go b/pkg/testhelpers/config.go index ab810e4f0d4af0f8969e4b473290237f11570248..3f379f6bd0bc3a00ca10f67c1e2c2391784701ae 100644 --- a/pkg/testhelpers/config.go +++ b/pkg/testhelpers/config.go @@ -1,7 +1,7 @@ package testhelpers import ( - "github.com/traefik/traefik/v2/pkg/config/dynamic" + "github.com/traefik/traefik/v3/pkg/config/dynamic" ) // BuildConfiguration is a helper to create a configuration. diff --git a/pkg/tls/certificate_store.go b/pkg/tls/certificate_store.go index 353efc95c462645dcff35a49752f256d8abf693f..20bdb317d61b9ca305faee807ed31a87ddd49952 100644 --- a/pkg/tls/certificate_store.go +++ b/pkg/tls/certificate_store.go @@ -10,7 +10,7 @@ import ( "github.com/patrickmn/go-cache" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/safe" ) // CertificateStore store for dynamic certificates. diff --git a/pkg/tls/certificate_store_test.go b/pkg/tls/certificate_store_test.go index a80516142b1de65225b0ed01e80b705dcb9f14aa..cd08af2c53ca666b1e21fb2128935fda7772118e 100644 --- a/pkg/tls/certificate_store_test.go +++ b/pkg/tls/certificate_store_test.go @@ -10,7 +10,7 @@ import ( "github.com/patrickmn/go-cache" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/safe" ) func TestGetBestCertificate(t *testing.T) { diff --git a/pkg/tls/tls.go b/pkg/tls/tls.go index fc97e265d05fd72b371908735dcea5bc48da48d8..93a9cab36ead120bbe569840ce479f80e10edf35 100644 --- a/pkg/tls/tls.go +++ b/pkg/tls/tls.go @@ -1,6 +1,6 @@ package tls -import "github.com/traefik/traefik/v2/pkg/types" +import "github.com/traefik/traefik/v3/pkg/types" const certificateHeader = "-----BEGIN CERTIFICATE-----\n" diff --git a/pkg/tls/tlsmanager.go b/pkg/tls/tlsmanager.go index 2fd249a87b99da3b2e9676af19754575107af2fc..790745d980b822715327a644c0aa4bffbf10e37b 100644 --- a/pkg/tls/tlsmanager.go +++ b/pkg/tls/tlsmanager.go @@ -12,9 +12,9 @@ import ( "github.com/go-acme/lego/v4/challenge/dns01" "github.com/go-acme/lego/v4/challenge/tlsalpn01" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/tls/generate" - "github.com/traefik/traefik/v2/pkg/types" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/tls/generate" + "github.com/traefik/traefik/v3/pkg/types" ) const ( @@ -224,24 +224,43 @@ func (m *Manager) Get(storeName, configName string) (*tls.Config, error) { return tlsConfig, err } -// GetCertificates returns all stored certificates. -func (m *Manager) GetCertificates() []*x509.Certificate { +// GetServerCertificates returns all certificates from the default store, +// as well as the user-defined default certificate (if it exists). +func (m *Manager) GetServerCertificates() []*x509.Certificate { var certificates []*x509.Certificate - // We iterate over all the certificates. - for _, store := range m.stores { - if store.DynamicCerts != nil && store.DynamicCerts.Get() != nil { - for _, cert := range store.DynamicCerts.Get().(map[string]*tls.Certificate) { - x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) - if err != nil { - continue - } + // The default store is the only relevant, because it is the only one configurable. + defaultStore, ok := m.stores[DefaultTLSStoreName] + if !ok || defaultStore == nil { + return certificates + } - certificates = append(certificates, x509Cert) + // We iterate over all the certificates. + if defaultStore.DynamicCerts != nil && defaultStore.DynamicCerts.Get() != nil { + for _, cert := range defaultStore.DynamicCerts.Get().(map[string]*tls.Certificate) { + x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) + if err != nil { + continue } + + certificates = append(certificates, x509Cert) } } + if defaultStore.DefaultCertificate != nil { + x509Cert, err := x509.ParseCertificate(defaultStore.DefaultCertificate.Certificate[0]) + if err != nil { + return certificates + } + + // Excluding the generated Traefik default certificate. + if x509Cert.Subject.CommonName == generate.DefaultDomain { + return certificates + } + + certificates = append(certificates, x509Cert) + } + return certificates } diff --git a/pkg/tls/zz_generated.deepcopy.go b/pkg/tls/zz_generated.deepcopy.go index c85405a372bcb23b80f33b9cbb0df351e37cfed3..6523c97b1d8de32e143fb9b2777b989f2d7e5530 100644 --- a/pkg/tls/zz_generated.deepcopy.go +++ b/pkg/tls/zz_generated.deepcopy.go @@ -4,7 +4,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -30,7 +30,7 @@ THE SOFTWARE. package tls import ( - types "github.com/traefik/traefik/v2/pkg/types" + types "github.com/traefik/traefik/v3/pkg/types" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. diff --git a/pkg/tracing/datadog/datadog.go b/pkg/tracing/datadog/datadog.go index 1e9969e37159ea8de4c917fae08813400c585963..f1a334f220691caa7619754dd1b23ac463f9f668 100644 --- a/pkg/tracing/datadog/datadog.go +++ b/pkg/tracing/datadog/datadog.go @@ -7,7 +7,7 @@ import ( "github.com/opentracing/opentracing-go" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/logs" ddtracer "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/opentracer" datadog "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" ) @@ -18,6 +18,7 @@ const Name = "datadog" // Config provides configuration settings for a datadog tracer. type Config struct { LocalAgentHostPort string `description:"Sets the Datadog Agent host:port." json:"localAgentHostPort,omitempty" toml:"localAgentHostPort,omitempty" yaml:"localAgentHostPort,omitempty"` + LocalAgentSocket string `description:"Sets the socket for the Datadog Agent." json:"localAgentSocket,omitempty" toml:"localAgentSocket,omitempty" yaml:"localAgentSocket,omitempty"` GlobalTags map[string]string `description:"Sets a list of key:value tags on all spans." json:"globalTags,omitempty" toml:"globalTags,omitempty" yaml:"globalTags,omitempty" export:"true"` Debug bool `description:"Enables Datadog debug." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"` PrioritySampling bool `description:"Enables priority sampling. When using distributed tracing, this option must be enabled in order to get all the parts of a distributed trace sampled." json:"prioritySampling,omitempty" toml:"prioritySampling,omitempty" yaml:"prioritySampling,omitempty" export:"true"` @@ -47,7 +48,6 @@ func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error logger := log.With().Str(logs.TracingProviderName, Name).Logger() opts := []datadog.StartOption{ - datadog.WithAgentAddr(c.LocalAgentHostPort), datadog.WithServiceName(serviceName), datadog.WithDebugMode(c.Debug), datadog.WithPropagator(datadog.NewPropagator(&datadog.PropagatorConfig{ @@ -59,6 +59,12 @@ func (c *Config) Setup(serviceName string) (opentracing.Tracer, io.Closer, error datadog.WithLogger(logs.NewDatadogLogger(logger)), } + if c.LocalAgentSocket != "" { + opts = append(opts, datadog.WithUDS(c.LocalAgentSocket)) + } else { + opts = append(opts, datadog.WithAgentAddr(c.LocalAgentHostPort)) + } + for k, v := range c.GlobalTags { opts = append(opts, datadog.WithGlobalTag(k, v)) } diff --git a/pkg/tracing/elastic/elastic.go b/pkg/tracing/elastic/elastic.go index 967f5fcb03c0d27b65014630c64f1115d7c2443e..383cca2bdb4afbfda56563d21c16e97542dffc72 100644 --- a/pkg/tracing/elastic/elastic.go +++ b/pkg/tracing/elastic/elastic.go @@ -6,8 +6,8 @@ import ( "github.com/opentracing/opentracing-go" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" - "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/pkg/logs" + "github.com/traefik/traefik/v3/pkg/version" "go.elastic.co/apm" "go.elastic.co/apm/module/apmot" "go.elastic.co/apm/transport" diff --git a/pkg/tracing/haystack/haystack.go b/pkg/tracing/haystack/haystack.go index 9c64dd36bef3930cb3f0c980673f788e72543cf9..6e460dcfb1a75e05698ebfbced487e054ca72f7d 100644 --- a/pkg/tracing/haystack/haystack.go +++ b/pkg/tracing/haystack/haystack.go @@ -8,7 +8,7 @@ import ( "github.com/ExpediaDotCom/haystack-client-go" "github.com/opentracing/opentracing-go" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/logs" ) // Name sets the name of this tracer. diff --git a/pkg/tracing/instana/instana.go b/pkg/tracing/instana/instana.go index 39c664468f7e6c10f04db5016fa0761c7f63b67e..edb2ee14e5c8fd71c8a6cc17854aee0bd4a2c5e8 100644 --- a/pkg/tracing/instana/instana.go +++ b/pkg/tracing/instana/instana.go @@ -6,7 +6,7 @@ import ( instana "github.com/instana/go-sensor" "github.com/opentracing/opentracing-go" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/logs" ) // Name sets the name of this tracer. diff --git a/pkg/tracing/jaeger/jaeger.go b/pkg/tracing/jaeger/jaeger.go index 206c206de13f057b6cc0310f029d5fc50a82269a..64eeb8e180c470bbd6cab48fb07231cef4f6ed99 100644 --- a/pkg/tracing/jaeger/jaeger.go +++ b/pkg/tracing/jaeger/jaeger.go @@ -6,7 +6,7 @@ import ( "github.com/opentracing/opentracing-go" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/logs" + "github.com/traefik/traefik/v3/pkg/logs" jaegercli "github.com/uber/jaeger-client-go" jaegercfg "github.com/uber/jaeger-client-go/config" "github.com/uber/jaeger-client-go/zipkin" diff --git a/pkg/tracing/opentelemetry/opentelemetry.go b/pkg/tracing/opentelemetry/opentelemetry.go index d42770ae35884a94b855f020b91499acad487f8e..af12c67a3613c76597b2f41d26245ff98381220e 100644 --- a/pkg/tracing/opentelemetry/opentelemetry.go +++ b/pkg/tracing/opentelemetry/opentelemetry.go @@ -8,15 +8,17 @@ import ( "github.com/opentracing/opentracing-go" "github.com/rs/zerolog/log" - "github.com/traefik/traefik/v2/pkg/types" - "github.com/traefik/traefik/v2/pkg/version" + "github.com/traefik/traefik/v3/pkg/types" + "github.com/traefik/traefik/v3/pkg/version" "go.opentelemetry.io/otel" oteltracer "go.opentelemetry.io/otel/bridge/opentracing" "go.opentelemetry.io/otel/exporters/otlp/otlptrace" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" + semconv "go.opentelemetry.io/otel/semconv/v1.12.0" "go.opentelemetry.io/otel/trace" "google.golang.org/grpc/credentials" "google.golang.org/grpc/encoding/gzip" @@ -60,7 +62,20 @@ func (c *Config) Setup(componentName string) (opentracing.Tracer, io.Closer, err bt.SetOpenTelemetryTracer(otel.Tracer(componentName, trace.WithInstrumentationVersion(version.Version))) opentracing.SetGlobalTracer(bt) - tracerProvider := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter)) + res, err := resource.New(context.Background(), + resource.WithAttributes(semconv.ServiceNameKey.String("traefik")), + resource.WithAttributes(semconv.ServiceVersionKey.String(version.Version)), + resource.WithFromEnv(), + resource.WithTelemetrySDK(), + ) + if err != nil { + return nil, nil, fmt.Errorf("building resource: %w", err) + } + + tracerProvider := sdktrace.NewTracerProvider( + sdktrace.WithResource(res), + sdktrace.WithBatcher(exporter), + ) otel.SetTracerProvider(tracerProvider) log.Debug().Msg("OpenTelemetry tracer configured") diff --git a/pkg/tracing/opentelemetry/opentelemetry_test.go b/pkg/tracing/opentelemetry/opentelemetry_test.go index 9d76f71d35b863c957b39db704b6552fbca0a549..40fcca1592e1141f6526b0dc4edb67f60001db4d 100644 --- a/pkg/tracing/opentelemetry/opentelemetry_test.go +++ b/pkg/tracing/opentelemetry/opentelemetry_test.go @@ -9,18 +9,48 @@ import ( "net/http/httptest" "strings" "testing" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - mtracing "github.com/traefik/traefik/v2/pkg/middlewares/tracing" - "github.com/traefik/traefik/v2/pkg/tracing" + mtracing "github.com/traefik/traefik/v3/pkg/middlewares/tracing" + "github.com/traefik/traefik/v3/pkg/tracing" "go.opentelemetry.io/collector/pdata/ptrace/ptraceotlp" ) -func TestTraceContextPropagation(t *testing.T) { - t.Parallel() +func TestTracing(t *testing.T) { + tests := []struct { + desc string + headers map[string]string + assertFn func(*testing.T, string) + }{ + { + desc: "service name and version", + assertFn: func(t *testing.T, trace string) { + t.Helper() - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + assert.Regexp(t, `({"key":"service.name","value":{"stringValue":"traefik"}})`, trace) + assert.Regexp(t, `({"key":"service.version","value":{"stringValue":"dev"}})`, trace) + }, + }, + { + desc: "context propagation", + headers: map[string]string{ + "traceparent": "00-00000000000000000000000000000001-0000000000000001-01", + "tracestate": "foo=bar", + }, + assertFn: func(t *testing.T, trace string) { + t.Helper() + + assert.Regexp(t, `("traceId":"00000000000000000000000000000001")`, trace) + assert.Regexp(t, `("parentSpanId":"0000000000000001")`, trace) + assert.Regexp(t, `("traceState":"foo=bar")`, trace) + }, + }, + } + + traceCh := make(chan string) + collector := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { gzr, err := gzip.NewReader(r.Body) require.NoError(t, err) @@ -34,34 +64,38 @@ func TestTraceContextPropagation(t *testing.T) { marshalledReq, err := json.Marshal(req) require.NoError(t, err) - bodyStr := string(marshalledReq) - assert.Regexp(t, `("traceId":"00000000000000000000000000000001")`, bodyStr) - assert.Regexp(t, `("parentSpanId":"0000000000000001")`, bodyStr) - assert.Regexp(t, `("traceState":"foo=bar")`, bodyStr) + traceCh <- string(marshalledReq) })) - defer ts.Close() + t.Cleanup(collector.Close) - cfg := Config{ - Address: strings.TrimPrefix(ts.URL, "http://"), + newTracing, err := tracing.NewTracing("", 0, &Config{ Insecure: true, - } - - newTracing, err := tracing.NewTracing("", 0, &cfg) + Address: strings.TrimPrefix(collector.URL, "http://"), + }) require.NoError(t, err) - defer newTracing.Close() + t.Cleanup(newTracing.Close) - req := httptest.NewRequest(http.MethodGet, "http://www.test.com", nil) - req.Header.Set("traceparent", "00-00000000000000000000000000000001-0000000000000001-00") - req.Header.Set("tracestate", "foo=bar") - rw := httptest.NewRecorder() + epHandler := mtracing.NewEntryPoint(context.Background(), newTracing, "test", http.NotFoundHandler()) - var forwarded bool - next := http.HandlerFunc(func(http.ResponseWriter, *http.Request) { - forwarded = true - }) + for _, test := range tests { + t.Run(test.desc, func(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, "http://www.test.com", nil) + for k, v := range test.headers { + req.Header.Set(k, v) + } + + rw := httptest.NewRecorder() - handler := mtracing.NewEntryPoint(context.Background(), newTracing, "test", next) - handler.ServeHTTP(rw, req) + epHandler.ServeHTTP(rw, req) - require.True(t, forwarded) + select { + case <-time.After(10 * time.Second): + t.Error("Trace not exported") + + case trace := <-traceCh: + assert.Equal(t, http.StatusNotFound, rw.Code) + test.assertFn(t, trace) + } + }) + } } diff --git a/pkg/types/metrics.go b/pkg/types/metrics.go index ddcf71d967aa7da6bd8ca9a11312738a0324df09..2d8b4114d6b4eabf1ca488f101d8c56786adc350 100644 --- a/pkg/types/metrics.go +++ b/pkg/types/metrics.go @@ -13,19 +13,19 @@ type Metrics struct { Prometheus *Prometheus `description:"Prometheus metrics exporter type." json:"prometheus,omitempty" toml:"prometheus,omitempty" yaml:"prometheus,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` Datadog *Datadog `description:"Datadog metrics exporter type." json:"datadog,omitempty" toml:"datadog,omitempty" yaml:"datadog,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` StatsD *Statsd `description:"StatsD metrics exporter type." json:"statsD,omitempty" toml:"statsD,omitempty" yaml:"statsD,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` - InfluxDB *InfluxDB `description:"InfluxDB metrics exporter type." json:"influxDB,omitempty" toml:"influxDB,omitempty" yaml:"influxDB,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` InfluxDB2 *InfluxDB2 `description:"InfluxDB v2 metrics exporter type." json:"influxDB2,omitempty" toml:"influxDB2,omitempty" yaml:"influxDB2,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` OpenTelemetry *OpenTelemetry `description:"OpenTelemetry metrics exporter type." json:"openTelemetry,omitempty" toml:"openTelemetry,omitempty" yaml:"openTelemetry,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` } // Prometheus can contain specific configuration used by the Prometheus Metrics exporter. type Prometheus struct { - Buckets []float64 `description:"Buckets for latency metrics." json:"buckets,omitempty" toml:"buckets,omitempty" yaml:"buckets,omitempty" export:"true"` - AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"` - AddRoutersLabels bool `description:"Enable metrics on routers." json:"addRoutersLabels,omitempty" toml:"addRoutersLabels,omitempty" yaml:"addRoutersLabels,omitempty" export:"true"` - AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"` - EntryPoint string `description:"EntryPoint" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty" export:"true"` - ManualRouting bool `description:"Manual routing" json:"manualRouting,omitempty" toml:"manualRouting,omitempty" yaml:"manualRouting,omitempty" export:"true"` + Buckets []float64 `description:"Buckets for latency metrics." json:"buckets,omitempty" toml:"buckets,omitempty" yaml:"buckets,omitempty" export:"true"` + AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"` + AddRoutersLabels bool `description:"Enable metrics on routers." json:"addRoutersLabels,omitempty" toml:"addRoutersLabels,omitempty" yaml:"addRoutersLabels,omitempty" export:"true"` + AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"` + EntryPoint string `description:"EntryPoint" json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty" export:"true"` + ManualRouting bool `description:"Manual routing" json:"manualRouting,omitempty" toml:"manualRouting,omitempty" yaml:"manualRouting,omitempty" export:"true"` + HeaderLabels map[string]string `description:"Defines the extra labels for the requests_total metrics, and for each of them, the request header containing the value for this label." json:"headerLabels,omitempty" toml:"headerLabels,omitempty" yaml:"headerLabels,omitempty" export:"true"` } // SetDefaults sets the default values. @@ -83,30 +83,6 @@ func (s *Statsd) SetDefaults() { s.Prefix = "traefik" } -// InfluxDB contains address, login and metrics pushing interval configuration. -type InfluxDB struct { - Address string `description:"InfluxDB address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` - Protocol string `description:"InfluxDB address protocol (udp or http)." json:"protocol,omitempty" toml:"protocol,omitempty" yaml:"protocol,omitempty"` - PushInterval types.Duration `description:"InfluxDB push interval." json:"pushInterval,omitempty" toml:"pushInterval,omitempty" yaml:"pushInterval,omitempty" export:"true"` - Database string `description:"InfluxDB database used when protocol is http." json:"database,omitempty" toml:"database,omitempty" yaml:"database,omitempty" export:"true"` - RetentionPolicy string `description:"InfluxDB retention policy used when protocol is http." json:"retentionPolicy,omitempty" toml:"retentionPolicy,omitempty" yaml:"retentionPolicy,omitempty" export:"true"` - Username string `description:"InfluxDB username (only with http)." json:"username,omitempty" toml:"username,omitempty" yaml:"username,omitempty" loggable:"false"` - Password string `description:"InfluxDB password (only with http)." json:"password,omitempty" toml:"password,omitempty" yaml:"password,omitempty" loggable:"false"` - AddEntryPointsLabels bool `description:"Enable metrics on entry points." json:"addEntryPointsLabels,omitempty" toml:"addEntryPointsLabels,omitempty" yaml:"addEntryPointsLabels,omitempty" export:"true"` - AddRoutersLabels bool `description:"Enable metrics on routers." json:"addRoutersLabels,omitempty" toml:"addRoutersLabels,omitempty" yaml:"addRoutersLabels,omitempty" export:"true"` - AddServicesLabels bool `description:"Enable metrics on services." json:"addServicesLabels,omitempty" toml:"addServicesLabels,omitempty" yaml:"addServicesLabels,omitempty" export:"true"` - AdditionalLabels map[string]string `description:"Additional labels (influxdb tags) on all metrics" json:"additionalLabels,omitempty" toml:"additionalLabels,omitempty" yaml:"additionalLabels,omitempty" export:"true"` -} - -// SetDefaults sets the default values. -func (i *InfluxDB) SetDefaults() { - i.Address = "localhost:8089" - i.Protocol = "udp" - i.PushInterval = types.Duration(10 * time.Second) - i.AddEntryPointsLabels = true - i.AddServicesLabels = true -} - // InfluxDB2 contains address, token and metrics pushing interval configuration. type InfluxDB2 struct { Address string `description:"InfluxDB v2 address." json:"address,omitempty" toml:"address,omitempty" yaml:"address,omitempty"` diff --git a/pkg/types/zz_generated.deepcopy.go b/pkg/types/zz_generated.deepcopy.go index 1770e4ef415eae94790d42bc74df65e21fee9fe4..8c55ace8796aa8e88e801b6b59797ae3f408d257 100644 --- a/pkg/types/zz_generated.deepcopy.go +++ b/pkg/types/zz_generated.deepcopy.go @@ -4,7 +4,7 @@ /* The MIT License (MIT) -Copyright (c) 2016-2020 Containous SAS; 2020-2022 Traefik Labs +Copyright (c) 2016-2020 Containous SAS; 2020-2023 Traefik Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/pkg/udp/proxy.go b/pkg/udp/proxy.go index 31f64a5ce45b893d43d28db619800daa9fc10399..bb3644a638b6be6c4591a3ada16739ca24c417aa 100644 --- a/pkg/udp/proxy.go +++ b/pkg/udp/proxy.go @@ -20,14 +20,14 @@ func NewProxy(address string) (*Proxy, error) { // ServeUDP implements the Handler interface. func (p *Proxy) ServeUDP(conn *Conn) { - log.Debug().Msgf("Handling connection from %s to %s", conn.rAddr, p.target) + log.Debug().Msgf("Handling UDP stream from %s to %s", conn.rAddr, p.target) // needed because of e.g. server.trackedConnection defer conn.Close() connBackend, err := net.Dial("udp", p.target) if err != nil { - log.Error().Err(err).Msg("Error while connecting to backend") + log.Error().Err(err).Msg("Error while dialing backend") return } @@ -40,7 +40,7 @@ func (p *Proxy) ServeUDP(conn *Conn) { err = <-errChan if err != nil { - log.Error().Err(err).Msg("Error while serving UDP") + log.Error().Err(err).Msg("Error while handling UDP stream") } <-errChan @@ -55,6 +55,6 @@ func connCopy(dst io.WriteCloser, src io.Reader, errCh chan error) { errCh <- err if err := dst.Close(); err != nil { - log.Debug().Err(err).Msg("Error while terminating connection") + log.Debug().Err(err).Msg("Error while terminating UDP stream") } } diff --git a/pkg/udp/switcher.go b/pkg/udp/switcher.go index d198a35878daa4f657d56b9b786ceb8e7763da84..bb596be04c8e5f31e2f1af37bfc7ed08bd14ffac 100644 --- a/pkg/udp/switcher.go +++ b/pkg/udp/switcher.go @@ -1,7 +1,7 @@ package udp import ( - "github.com/traefik/traefik/v2/pkg/safe" + "github.com/traefik/traefik/v3/pkg/safe" ) // HandlerSwitcher is a switcher implementation of the Handler interface. diff --git a/script/binary b/script/binary index 3a3e94b614546fbae6d35818086dbd5541bf2256..c1de7c9bbeffc6d6ab664a60a0148478cb8172f0 100755 --- a/script/binary +++ b/script/binary @@ -24,7 +24,7 @@ fi # shellcheck disable=SC2086 # shellcheck disable=SC2048 CGO_ENABLED=0 GOGC=off go build ${FLAGS[*]} -ldflags "-s -w \ - -X github.com/traefik/traefik/v2/pkg/version.Version=$VERSION \ - -X github.com/traefik/traefik/v2/pkg/version.Codename=$CODENAME \ - -X github.com/traefik/traefik/v2/pkg/version.BuildDate=$DATE" \ + -X github.com/traefik/traefik/v3/pkg/version.Version=$VERSION \ + -X github.com/traefik/traefik/v3/pkg/version.Codename=$CODENAME \ + -X github.com/traefik/traefik/v3/pkg/version.BuildDate=$DATE" \ -installsuffix nocgo -o dist/traefik ./cmd/traefik diff --git a/script/code-gen.sh b/script/code-gen.sh index de705c8148175d0cb512b086dd5c9993b169a232..905ac67cb190e85d6daa9a125d06c3bbf03b882c 100755 --- a/script/code-gen.sh +++ b/script/code-gen.sh @@ -4,7 +4,7 @@ set -e -o pipefail PROJECT_MODULE="github.com/traefik/traefik" -MODULE_VERSION="v2" +MODULE_VERSION="v3" IMAGE_NAME="kubernetes-codegen:latest" CURRENT_DIR="$(pwd)" @@ -18,28 +18,40 @@ docker build --build-arg KUBE_VERSION=v0.20.2 \ "." echo "Generating Traefik clientSet code ..." -cmd="/go/src/k8s.io/code-generator/generate-groups.sh all ${PROJECT_MODULE}/${MODULE_VERSION}/pkg/provider/kubernetes/crd/generated ${PROJECT_MODULE}/${MODULE_VERSION}/pkg/provider/kubernetes/crd traefik:v1alpha1 --go-header-file=/go/src/${PROJECT_MODULE}/script/boilerplate.go.tmpl" docker run --rm \ -v "${CURRENT_DIR}:/go/src/${PROJECT_MODULE}" \ -w "/go/src/${PROJECT_MODULE}" \ - "${IMAGE_NAME}" ${cmd} + "${IMAGE_NAME}" \ + /go/src/k8s.io/code-generator/generate-groups.sh all \ + ${PROJECT_MODULE}/${MODULE_VERSION}/pkg/provider/kubernetes/crd/generated \ + ${PROJECT_MODULE}/${MODULE_VERSION}/pkg/provider/kubernetes/crd \ + "traefikio:v1alpha1" \ + --go-header-file=/go/src/${PROJECT_MODULE}/script/boilerplate.go.tmpl echo "Generating DeepCopy code ..." -cmd="deepcopy-gen --input-dirs ${PROJECT_MODULE}/${MODULE_VERSION}/pkg/config/dynamic --input-dirs ${PROJECT_MODULE}/${MODULE_VERSION}/pkg/tls --input-dirs ${PROJECT_MODULE}/${MODULE_VERSION}/pkg/types --output-package ${PROJECT_MODULE}/${MODULE_VERSION} -O zz_generated.deepcopy --go-header-file=/go/src/${PROJECT_MODULE}/script/boilerplate.go.tmpl" + docker run --rm \ -v "${CURRENT_DIR}:/go/src/${PROJECT_MODULE}" \ -w "/go/src/${PROJECT_MODULE}" \ - "${IMAGE_NAME}" ${cmd} + "${IMAGE_NAME}" \ + deepcopy-gen \ + --input-dirs ${PROJECT_MODULE}/${MODULE_VERSION}/pkg/config/dynamic \ + --input-dirs ${PROJECT_MODULE}/${MODULE_VERSION}/pkg/tls \ + --input-dirs ${PROJECT_MODULE}/${MODULE_VERSION}/pkg/types \ + --output-package ${PROJECT_MODULE}/${MODULE_VERSION} -O zz_generated.deepcopy \ + --go-header-file=/go/src/${PROJECT_MODULE}/script/boilerplate.go.tmpl echo "Generating the CRD definitions for the documentation ..." -cmd="controller-gen crd:crdVersions=v1 paths=./pkg/provider/kubernetes/crd/traefik/v1alpha1/... output:dir=./docs/content/reference/dynamic-configuration/" docker run --rm \ -v "${CURRENT_DIR}:/go/src/${PROJECT_MODULE}" \ -w "/go/src/${PROJECT_MODULE}" \ - "${IMAGE_NAME}" ${cmd} + "${IMAGE_NAME}" \ + controller-gen crd:crdVersions=v1 \ + paths={./pkg/provider/kubernetes/crd/traefikio/v1alpha1/...} \ + output:dir=./docs/content/reference/dynamic-configuration/ echo "Concatenate the CRD definitions for publication and integration tests ..." -cat "${CURRENT_DIR}"/docs/content/reference/dynamic-configuration/traefik.containo.us_*.yaml > "${CURRENT_DIR}"/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml +cat "${CURRENT_DIR}"/docs/content/reference/dynamic-configuration/traefik.io_*.yaml > "${CURRENT_DIR}"/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml cp -f "${CURRENT_DIR}"/docs/content/reference/dynamic-configuration/kubernetes-crd-definition-v1.yml "${CURRENT_DIR}"/integration/fixtures/k8s/01-traefik-crd.yml cp -r "${CURRENT_DIR}/${MODULE_VERSION}"/* "${CURRENT_DIR}" diff --git a/script/codegen.Dockerfile b/script/codegen.Dockerfile index ac2815fb5db98fc43561936ab9628ed9cb8ea135..d946b2e161b87a7b36be7e66d832df83bac38cc4 100644 --- a/script/codegen.Dockerfile +++ b/script/codegen.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.19 +FROM golang:1.20 ARG USER=$USER ARG UID=$UID diff --git a/script/gcg/traefik-bugfix.toml b/script/gcg/traefik-bugfix.toml index 9db9d689cc32d74f5c8256f0265d11877bd1ccdd..189f8c45161c6e3004f887689363853433ebbfbe 100644 --- a/script/gcg/traefik-bugfix.toml +++ b/script/gcg/traefik-bugfix.toml @@ -4,11 +4,11 @@ RepositoryName = "traefik" OutputType = "file" FileName = "traefik_changelog.md" -# example new bugfix v2.9.6 +# example new bugfix v2.9.9 CurrentRef = "v2.9" -PreviousRef = "v2.9.5" +PreviousRef = "v2.9.8" BaseBranch = "v2.9" -FutureCurrentRefName = "v2.9.6" +FutureCurrentRefName = "v2.9.9" ThresholdPreviousRef = 10 ThresholdCurrentRef = 10 diff --git a/webui/package.json b/webui/package.json index 1f88c6a5200b45ac22d3ebca44173582e9abb091..23e2be3d47bf4d59c8902110f8e46252457ac6a8 100644 --- a/webui/package.json +++ b/webui/package.json @@ -3,7 +3,7 @@ "version": "2.0.0", "description": "Traefik UI", "productName": "Traefik", - "cordovaId": "us.containo.traefik", + "cordovaId": "io.traefik.traefik", "private": true, "scripts": { "transfer": "node dev/scripts/transfer.js", diff --git a/webui/src/_mixins/GetTableProps.js b/webui/src/_mixins/GetTableProps.js index 014a397bb42822c1a4d28d6ce4bfe3de7ff61ee3..5ca70949dc02cfcc301d76166bd8a80b11d5ec4d 100644 --- a/webui/src/_mixins/GetTableProps.js +++ b/webui/src/_mixins/GetTableProps.js @@ -11,6 +11,7 @@ const allColumns = [ required: true, label: 'Status', align: 'left', + sortable: true, fieldToProps: row => ({ state: row.status === 'enabled' ? 'positive' : 'negative' }), @@ -20,6 +21,7 @@ const allColumns = [ name: 'tls', align: 'left', label: 'TLS', + sortable: false, fieldToProps: row => ({ isTLS: row.tls }), component: TLSState }, @@ -27,6 +29,7 @@ const allColumns = [ name: 'rule', align: 'left', label: 'Rule', + sortable: true, component: QChip, fieldToProps: () => ({ class: 'app-chip app-chip-rule', dense: true }), content: row => row.rule @@ -35,6 +38,7 @@ const allColumns = [ name: 'entryPoints', align: 'left', label: 'Entrypoints', + sortable: true, component: Chips, fieldToProps: row => ({ classNames: 'app-chip app-chip-entry-points', @@ -46,6 +50,7 @@ const allColumns = [ name: 'name', align: 'left', label: 'Name', + sortable: true, component: QChip, fieldToProps: () => ({ class: 'app-chip app-chip-name', dense: true }), content: row => row.name @@ -54,6 +59,7 @@ const allColumns = [ name: 'type', align: 'left', label: 'Type', + sortable: true, component: QChip, fieldToProps: () => ({ class: 'app-chip app-chip-entry-points', @@ -65,6 +71,7 @@ const allColumns = [ name: 'servers', align: 'right', label: 'Servers', + sortable: true, fieldToProps: () => ({ class: 'servers-label' }), content: function (value) { if (value.loadBalancer && value.loadBalancer.servers) { @@ -78,6 +85,7 @@ const allColumns = [ align: 'left', label: 'Service', component: QChip, + sortable: true, fieldToProps: () => ({ class: 'app-chip app-chip-service', dense: true }), content: row => row.service }, @@ -85,8 +93,23 @@ const allColumns = [ name: 'provider', align: 'center', label: 'Provider', + sortable: true, fieldToProps: row => ({ name: row.provider }), component: ProviderIcon + }, + { + name: 'priority', + align: 'left', + label: 'Priority', + sortable: true, + component: QChip, + fieldToProps: () => ({ class: 'app-chip app-chip-accent', dense: true }), + content: row => { + return { + short: String(row.priority).length > 10 ? String(row.priority).substring(0, 10) + '...' : row.priority, + long: row.priority + } + } } ] @@ -98,7 +121,8 @@ const columnsByResource = { 'name', 'service', 'tls', - 'provider' + 'provider', + 'priority' ], udpRouters: ['status', 'entryPoints', 'name', 'service', 'provider'], services: ['status', 'name', 'type', 'servers', 'provider'], diff --git a/webui/src/_services/HttpService.js b/webui/src/_services/HttpService.js index 0e206b24d1cb1f99da6ad5a3ba712fb5189cb5c4..9a1228285c4e2c890c638ec266911232ecb3ffc6 100644 --- a/webui/src/_services/HttpService.js +++ b/webui/src/_services/HttpService.js @@ -4,7 +4,7 @@ import { getTotal } from './utils' const apiBase = '/http' function getAllRouters (params) { - return APP.api.get(`${apiBase}/routers?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}`) + return APP.api.get(`${apiBase}/routers?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}&sortBy=${params.sortBy}&direction=${params.direction}&serviceName=${params.serviceName}&middlewareName=${params.middlewareName}`) .then(response => { const { data = [], headers } = response const total = getTotal(headers, params) @@ -22,7 +22,7 @@ function getRouterByName (name) { } function getAllServices (params) { - return APP.api.get(`${apiBase}/services?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}`) + return APP.api.get(`${apiBase}/services?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}&sortBy=${params.sortBy}&direction=${params.direction}`) .then(response => { const { data = [], headers } = response const total = getTotal(headers, params) @@ -40,7 +40,7 @@ function getServiceByName (name) { } function getAllMiddlewares (params) { - return APP.api.get(`${apiBase}/middlewares?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}`) + return APP.api.get(`${apiBase}/middlewares?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}&sortBy=${params.sortBy}&direction=${params.direction}`) .then(response => { const { data = [], headers } = response const total = getTotal(headers, params) diff --git a/webui/src/_services/TcpService.js b/webui/src/_services/TcpService.js index e5645e9b19c33cb2d1bb086e86b2da8e79856453..ca33b0120185f2d85358a7573bd784e6227e3e15 100644 --- a/webui/src/_services/TcpService.js +++ b/webui/src/_services/TcpService.js @@ -4,7 +4,7 @@ import { getTotal } from './utils' const apiBase = '/tcp' function getAllRouters (params) { - return APP.api.get(`${apiBase}/routers?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}`) + return APP.api.get(`${apiBase}/routers?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}&sortBy=${params.sortBy}&direction=${params.direction}&serviceName=${params.serviceName}&middlewareName=${params.middlewareName}`) .then(response => { const { data = [], headers } = response const total = getTotal(headers, params) @@ -22,7 +22,7 @@ function getRouterByName (name) { } function getAllServices (params) { - return APP.api.get(`${apiBase}/services?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}`) + return APP.api.get(`${apiBase}/services?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}&sortBy=${params.sortBy}&direction=${params.direction}`) .then(response => { const { data = [], headers } = response const total = getTotal(headers, params) @@ -40,7 +40,7 @@ function getServiceByName (name) { } function getAllMiddlewares (params) { - return APP.api.get(`${apiBase}/middlewares?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}`) + return APP.api.get(`${apiBase}/middlewares?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}&sortBy=${params.sortBy}&direction=${params.direction}`) .then(response => { const { data = [], headers } = response const total = getTotal(headers, params) diff --git a/webui/src/_services/UdpService.js b/webui/src/_services/UdpService.js index fd641d3575b74b68ee153aba21753b175775e6e7..549a99c1b6e6c3f9c79570c61485834df5267a95 100644 --- a/webui/src/_services/UdpService.js +++ b/webui/src/_services/UdpService.js @@ -4,7 +4,7 @@ import { getTotal } from './utils' const apiBase = '/udp' function getAllRouters (params) { - return APP.api.get(`${apiBase}/routers?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}`) + return APP.api.get(`${apiBase}/routers?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}&sortBy=${params.sortBy}&direction=${params.direction}&serviceName=${params.serviceName}`) .then(response => { const { data = [], headers } = response const total = getTotal(headers, params) @@ -22,7 +22,7 @@ function getRouterByName (name) { } function getAllServices (params) { - return APP.api.get(`${apiBase}/services?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}`) + return APP.api.get(`${apiBase}/services?search=${params.query}&status=${params.status}&per_page=${params.limit}&page=${params.page}&sortBy=${params.sortBy}&direction=${params.direction}`) .then(response => { const { data = [], headers } = response const total = getTotal(headers, params) diff --git a/webui/src/components/_commons/MainTable.vue b/webui/src/components/_commons/MainTable.vue index 85ae32e5557e90b2a710cbfa38be048757b1b70b..6119b33da849c5a29128ecd159adbe349106ee86 100644 --- a/webui/src/components/_commons/MainTable.vue +++ b/webui/src/components/_commons/MainTable.vue @@ -6,9 +6,12 @@ <tr class="table-header"> <th v-for="column in columns" - v-bind:class="`text-${column.align}`" - v-bind:key="column.name"> + v-bind:class="getColumn(column.name).sortable ? `text-${column.align} cursor-pointer`: `text-${column.align}`" + v-bind:key="column.name" + @click="getColumn(column.name).sortable ? onSortClick(column.name) : null"> {{ column.label }} + <i v-if="currentSort === column.name" class="material-icons">{{currentSortDir === 'asc' ? 'arrow_drop_down' : 'arrow_drop_up'}}</i> + <i v-else style="opacity: 0" class="material-icons">{{currentSortDir === 'asc' ? 'arrow_drop_down' : 'arrow_drop_up'}}</i> </th> </tr> </thead> @@ -27,9 +30,19 @@ v-bind:is="getColumn(column.name).component" v-bind="getColumn(column.name).fieldToProps(row)" > - <template v-if="getColumn(column.name).content"> + <template v-if="getColumn(column.name).content && column.name !== 'priority'"> {{ getColumn(column.name).content(row) }} </template> + <template v-if="getColumn(column.name).content && column.name === 'priority'"> + <div> + {{ getColumn(column.name).content(row).short }} + </div> + <q-tooltip anchor="top middle" self="bottom middle" :offset="[10, 10]"> + <div class="priority-tooltip"> + {{ getColumn(column.name).content(row).long }} + </div> + </q-tooltip> + </template> </component> </td> <td @@ -72,6 +85,12 @@ export default { QSpinnerDots, QPageScroller }, + data () { + return { + currentSort: 'name', + currentSortDir: 'asc' + } + }, methods: { getColumn (columnName) { return this.columns.find(c => c.name === columnName) || {} @@ -80,6 +99,14 @@ export default { this.onLoadMore({ page: index }) .then(() => done()) .catch(() => done(true)) + }, + onSortClick (s) { + if (s === this.currentSort) { + this.currentSortDir = this.currentSortDir === 'asc' ? 'desc' : 'asc' + } + this.currentSort = s + this.$emit('update:currentSort', s) + this.$emit('update:currentSortDir', this.currentSortDir) } } } @@ -127,4 +154,8 @@ export default { font-size: 14px; font-weight: 600; } + + .priority-tooltip{ + font-size: larger; + } </style> diff --git a/webui/src/components/_commons/PanelRouterDetails.vue b/webui/src/components/_commons/PanelRouterDetails.vue index 4b5d2029bc22b343a9a05403601b5218e1686324..4afa3318a2a9b8857d86ab69e902cedf148ef7c4 100644 --- a/webui/src/components/_commons/PanelRouterDetails.vue +++ b/webui/src/components/_commons/PanelRouterDetails.vue @@ -73,6 +73,18 @@ </div> </div> </q-card-section> + <q-card-section v-if="data.priority"> + <div class="row items-start no-wrap"> + <div class="col"> + <div class="text-subtitle2">PRIORITY</div> + <q-chip + dense + class="app-chip app-chip-entry-points"> + {{ data.priority }} + </q-chip> + </div> + </div> + </q-card-section> <q-card-section v-if="data.error"> <div class="row items-start no-wrap"> <div class="col"> diff --git a/webui/src/components/_commons/PanelServiceDetails.vue b/webui/src/components/_commons/PanelServiceDetails.vue index b7343617291baa657153674fd9be16a2137f27de..38c7cc1a689af8595003bfba8eed359142255123 100644 --- a/webui/src/components/_commons/PanelServiceDetails.vue +++ b/webui/src/components/_commons/PanelServiceDetails.vue @@ -55,19 +55,6 @@ </div> </q-card-section> - <q-card-section v-if="data.loadBalancer && data.loadBalancer.terminationDelay"> - <div class="row items-start no-wrap"> - <div class="col"> - <div class="text-subtitle2">Termination Delay</div> - <q-chip - dense - class="app-chip app-chip-name"> - {{ data.loadBalancer.terminationDelay }} ms - </q-chip> - </div> - </div> - </q-card-section> - <q-card-section v-if="data.loadBalancer && data.loadBalancer.proxyProtocol"> <div class="row items-start no-wrap"> <div class="col"> diff --git a/webui/src/pages/_commons/MiddlewareDetail.vue b/webui/src/pages/_commons/MiddlewareDetail.vue index 51a42fd5cebff54e388fed55d310244bc1a897f4..65d4fa40e5fc012d12b96079bd9e7c5f1cfeb90e 100644 --- a/webui/src/pages/_commons/MiddlewareDetail.vue +++ b/webui/src/pages/_commons/MiddlewareDetail.vue @@ -44,12 +44,15 @@ <div class="row items-center q-col-gutter-lg"> <div class="col-12"> <main-table - :data="allRouters" v-bind="getTableProps({ type: `${protocol}-routers` })" + :data="allRouters" + :onLoadMore="onGetAll" :request="()=>{}" :loading="routersLoading" :pagination.sync="routersPagination" :filter="routersFilter" + :currentSort.sync="sortBy" + :currentSortDir.sync="sortDir" /> </div> </div> @@ -91,7 +94,11 @@ export default { page: 1, rowsPerPage: 1000, rowsNumber: 0 - } + }, + filter: '', + status: '', + sortBy: 'name', + sortDir: 'asc' } }, computed: { @@ -108,11 +115,14 @@ export default { }, getRouterByName () { return this[`${this.protocol}_getRouterByName`] + }, + getAllRouters () { + return this[`${this.protocol}_getAllRouters`] } }, methods: { - ...mapActions('http', { http_getMiddlewareByName: 'getMiddlewareByName', http_getRouterByName: 'getRouterByName' }), - ...mapActions('tcp', { tcp_getMiddlewareByName: 'getMiddlewareByName', tcp_getRouterByName: 'getRouterByName' }), + ...mapActions('http', { http_getMiddlewareByName: 'getMiddlewareByName', http_getRouterByName: 'getRouterByName', http_getAllRouters: 'getAllRouters' }), + ...mapActions('tcp', { tcp_getMiddlewareByName: 'getMiddlewareByName', tcp_getRouterByName: 'getRouterByName', tcp_getAllRouters: 'getAllRouters' }), refreshAll () { if (this.middlewareByName.loading) { return @@ -127,22 +137,26 @@ export default { return } // Get routers - if (body.usedBy) { - for (const router in body.usedBy) { - if (body.usedBy.hasOwnProperty(router)) { - this.getRouterByName(body.usedBy[router]) - .then(body => { - if (body) { - this.routersLoading = false - this.allRouters.push(body) - } - }) - .catch(error => { - console.log('Error -> routers/byName', error) - }) + this.getAllRouters({ + query: this.filter, + status: this.status, + page: 1, + limit: 1000, + middlewareName: this.name, + serviceName: '', + sortBy: this.sortBy, + direction: this.sortDir + }) + .then(body => { + this.allRouters = [] + if (body) { + this.routersLoading = false + this.allRouters.push(...body.data) } - } - } + }) + .catch(error => { + console.log('Error -> routers/byName', error) + }) clearTimeout(this.timeOutGetAll) this.timeOutGetAll = setTimeout(() => { this.loading = false @@ -153,12 +167,18 @@ export default { }) } }, + watch: { + 'sortBy' () { + this.refreshAll() + }, + 'sortDir' () { + this.refreshAll() + } + }, created () { this.refreshAll() }, - mounted () { - - }, + mounted () {}, beforeDestroy () { clearInterval(this.timeOutGetAll) this.$store.commit('http/getMiddlewareByNameClear') diff --git a/webui/src/pages/_commons/ServiceDetail.vue b/webui/src/pages/_commons/ServiceDetail.vue index 0fc9b40eff402e063a6bd65818e2076d3d78afab..19122e8e84e6b810d71727f59666ed393085016f 100644 --- a/webui/src/pages/_commons/ServiceDetail.vue +++ b/webui/src/pages/_commons/ServiceDetail.vue @@ -112,12 +112,15 @@ <div class="row items-center q-col-gutter-lg"> <div class="col-12"> <main-table - :data="allRouters" v-bind="getTableProps({ type: `${protocol}-routers` })" + :data="allRouters" + :onLoadMore="onGetAll" :request="()=>{}" :loading="routersLoading" :pagination.sync="routersPagination" :filter="routersFilter" + :currentSort.sync="sortBy" + :currentSortDir.sync="sortDir" /> </div> </div> @@ -167,7 +170,11 @@ export default { page: 1, rowsPerPage: 1000, rowsNumber: 0 - } + }, + filter: '', + status: '', + sortBy: 'name', + sortDir: 'asc' } }, computed: { @@ -185,12 +192,15 @@ export default { }, getRouterByName () { return this[`${this.protocol}_getRouterByName`] + }, + getAllRouters () { + return this[`${this.protocol}_getAllRouters`] } }, methods: { - ...mapActions('http', { http_getServiceByName: 'getServiceByName', http_getRouterByName: 'getRouterByName' }), - ...mapActions('tcp', { tcp_getServiceByName: 'getServiceByName', tcp_getRouterByName: 'getRouterByName' }), - ...mapActions('udp', { udp_getServiceByName: 'getServiceByName', udp_getRouterByName: 'getRouterByName' }), + ...mapActions('http', { http_getServiceByName: 'getServiceByName', http_getRouterByName: 'getRouterByName', http_getAllRouters: 'getAllRouters' }), + ...mapActions('tcp', { tcp_getServiceByName: 'getServiceByName', tcp_getRouterByName: 'getRouterByName', tcp_getAllRouters: 'getAllRouters' }), + ...mapActions('udp', { udp_getServiceByName: 'getServiceByName', udp_getRouterByName: 'getRouterByName', udp_getAllRouters: 'getAllRouters' }), refreshAll () { if (this.serviceByName.loading) { return @@ -205,22 +215,26 @@ export default { return } // Get routers - if (body.usedBy) { - for (const router in body.usedBy) { - if (body.usedBy.hasOwnProperty(router)) { - this.getRouterByName(body.usedBy[router]) - .then(body => { - if (body) { - this.routersLoading = false - this.allRouters.push(body) - } - }) - .catch(error => { - console.log('Error -> routers/byName', error) - }) + this.getAllRouters({ + query: this.filter, + status: this.status, + page: 1, + limit: 1000, + middlewareName: '', + serviceName: this.name, + sortBy: this.sortBy, + direction: this.sortDir + }) + .then(body => { + this.allRouters = [] + if (body) { + this.routersLoading = false + this.allRouters.push(...body.data) } - } - } + }) + .catch(error => { + console.log('Error -> getAllRouters', error) + }) clearTimeout(this.timeOutGetAll) this.timeOutGetAll = setTimeout(() => { this.loading = false @@ -231,12 +245,18 @@ export default { }) } }, + watch: { + 'sortBy' () { + this.refreshAll() + }, + 'sortDir' () { + this.refreshAll() + } + }, created () { this.refreshAll() }, - mounted () { - - }, + mounted () {}, beforeDestroy () { clearInterval(this.timeOutGetAll) this.$store.commit('http/getServiceByNameClear') diff --git a/webui/src/pages/http/Middlewares.vue b/webui/src/pages/http/Middlewares.vue index e723c600299646c32b72197e913ee10e57cee785..ec1c057925b8f29134ac17e0b2b796406c438c9e 100644 --- a/webui/src/pages/http/Middlewares.vue +++ b/webui/src/pages/http/Middlewares.vue @@ -15,6 +15,8 @@ :onLoadMore="handleLoadMore" :endReached="allMiddlewares.endReached" :loading="allMiddlewares.loading" + :currentSort.sync="sortBy" + :currentSortDir.sync="sortDir" /> </div> </div> @@ -50,7 +52,9 @@ export default { data () { return { filter: '', - status: '' + status: '', + sortBy: 'name', + sortDir: 'asc' } }, computed: { @@ -62,6 +66,8 @@ export default { return this.getAllMiddlewares({ query: this.filter, status: this.status, + sortBy: this.sortBy, + direction: this.sortDir, ...params }) }, @@ -82,6 +88,12 @@ export default { }, 'filter' () { this.refreshAll() + }, + 'sortBy' () { + this.refreshAll() + }, + 'sortDir' () { + this.refreshAll() } }, beforeDestroy () { diff --git a/webui/src/pages/http/Routers.vue b/webui/src/pages/http/Routers.vue index e5cf9cc7a5d15d3cdbafaa3bf07d6327b486b619..6bdd544c483f54b5fae8a6bfae680a675e8935cc 100644 --- a/webui/src/pages/http/Routers.vue +++ b/webui/src/pages/http/Routers.vue @@ -15,6 +15,8 @@ :onLoadMore="handleLoadMore" :endReached="allRouters.endReached" :loading="allRouters.loading" + :currentSort.sync="sortBy" + :currentSortDir.sync="sortDir" /> </div> </div> @@ -50,7 +52,9 @@ export default { data () { return { filter: '', - status: '' + status: '', + sortBy: 'name', + sortDir: 'asc' } }, computed: { @@ -60,8 +64,12 @@ export default { ...mapActions('http', { getAllRouters: 'getAllRouters' }), getAllRoutersWithParams (params) { return this.getAllRouters({ + serviceName: '', + middlewareName: '', query: this.filter, status: this.status, + sortBy: this.sortBy, + direction: this.sortDir, ...params }) }, @@ -82,6 +90,12 @@ export default { }, 'filter' () { this.refreshAll() + }, + 'sortBy' () { + this.refreshAll() + }, + 'sortDir' () { + this.refreshAll() } }, beforeDestroy () { diff --git a/webui/src/pages/http/Services.vue b/webui/src/pages/http/Services.vue index 6e9fc5336ca5ee8d157f11b6f22439e1459eeb40..d97865510040b1b4633638d6a0564eaec465d24d 100644 --- a/webui/src/pages/http/Services.vue +++ b/webui/src/pages/http/Services.vue @@ -15,6 +15,8 @@ :onLoadMore="handleLoadMore" :endReached="allServices.endReached" :loading="allServices.loading" + :currentSort.sync="sortBy" + :currentSortDir.sync="sortDir" /> </div> </div> @@ -50,7 +52,9 @@ export default { data () { return { filter: '', - status: '' + status: '', + sortBy: 'name', + sortDir: 'asc' } }, computed: { @@ -62,6 +66,8 @@ export default { return this.getAllServices({ query: this.filter, status: this.status, + sortBy: this.sortBy, + direction: this.sortDir, ...params }) }, @@ -82,6 +88,12 @@ export default { }, 'filter' () { this.refreshAll() + }, + 'sortBy' () { + this.refreshAll() + }, + 'sortDir' () { + this.refreshAll() } }, beforeDestroy () { diff --git a/webui/src/pages/tcp/Middlewares.vue b/webui/src/pages/tcp/Middlewares.vue index 735341134fffe226f34842ba1bd4d6407194d5b1..51971740a2dbca80a0f03325ae16c05a2a7c64b8 100644 --- a/webui/src/pages/tcp/Middlewares.vue +++ b/webui/src/pages/tcp/Middlewares.vue @@ -15,6 +15,8 @@ :onLoadMore="handleLoadMore" :endReached="allMiddlewares.endReached" :loading="allMiddlewares.loading" + :currentSort.sync="sortBy" + :currentSortDir.sync="sortDir" /> </div> </div> @@ -50,7 +52,9 @@ export default { data () { return { filter: '', - status: '' + status: '', + sortBy: 'name', + sortDir: 'asc' } }, computed: { @@ -62,6 +66,8 @@ export default { return this.getAllMiddlewares({ query: this.filter, status: this.status, + sortBy: this.sortBy, + direction: this.sortDir, ...params }) }, @@ -82,6 +88,12 @@ export default { }, 'filter' () { this.refreshAll() + }, + 'sortBy' () { + this.refreshAll() + }, + 'sortDir' () { + this.refreshAll() } }, beforeDestroy () { diff --git a/webui/src/pages/tcp/Routers.vue b/webui/src/pages/tcp/Routers.vue index 2702c8110c9fd971f843e5f50c90f2e653b7f09b..352a4e149f5fae3a318ae024d2c5ed2c613320b3 100644 --- a/webui/src/pages/tcp/Routers.vue +++ b/webui/src/pages/tcp/Routers.vue @@ -15,6 +15,8 @@ :onLoadMore="handleLoadMore" :endReached="allRouters.endReached" :loading="allRouters.loading" + :currentSort.sync="sortBy" + :currentSortDir.sync="sortDir" /> </div> </div> @@ -50,7 +52,9 @@ export default { data () { return { filter: '', - status: '' + status: '', + sortBy: 'name', + sortDir: 'asc' } }, computed: { @@ -60,8 +64,12 @@ export default { ...mapActions('tcp', { getAllRouters: 'getAllRouters' }), getAllRoutersWithParams (params) { return this.getAllRouters({ + serviceName: '', + middlewareName: '', query: this.filter, status: this.status, + sortBy: this.sortBy, + direction: this.sortDir, ...params }) }, @@ -82,6 +90,12 @@ export default { }, 'filter' () { this.refreshAll() + }, + 'sortBy' () { + this.refreshAll() + }, + 'sortDir' () { + this.refreshAll() } }, beforeDestroy () { diff --git a/webui/src/pages/tcp/Services.vue b/webui/src/pages/tcp/Services.vue index 99492e2db5e43b3c0ef7f1b3f4bea6f8f5e9519c..f8c7b38a0ffe7c013610d5ec3918e12730d8a97d 100644 --- a/webui/src/pages/tcp/Services.vue +++ b/webui/src/pages/tcp/Services.vue @@ -15,6 +15,8 @@ :onLoadMore="handleLoadMore" :endReached="allServices.endReached" :loading="allServices.loading" + :currentSort.sync="sortBy" + :currentSortDir.sync="sortDir" /> </div> </div> @@ -50,7 +52,9 @@ export default { data () { return { filter: '', - status: '' + status: '', + sortBy: 'name', + sortDir: 'asc' } }, computed: { @@ -62,6 +66,8 @@ export default { return this.getAllServices({ query: this.filter, status: this.status, + sortBy: this.sortBy, + direction: this.sortDir, ...params }) }, @@ -82,6 +88,12 @@ export default { }, 'filter' () { this.refreshAll() + }, + 'sortBy' () { + this.refreshAll() + }, + 'sortDir' () { + this.refreshAll() } }, beforeDestroy () { diff --git a/webui/src/pages/udp/Routers.vue b/webui/src/pages/udp/Routers.vue index e73826fa118bb417a2ed4cf119658217127cc3da..9996563155d1c31bc8230b6974bb174965a7cb25 100644 --- a/webui/src/pages/udp/Routers.vue +++ b/webui/src/pages/udp/Routers.vue @@ -14,6 +14,8 @@ :onLoadMore="handleLoadMore" :endReached="allRouters.endReached" :loading="allRouters.loading" + :currentSort.sync="sortBy" + :currentSortDir.sync="sortDir" /> </div> </div> @@ -49,7 +51,9 @@ export default { data () { return { filter: '', - status: '' + status: '', + sortBy: 'name', + sortDir: 'asc' } }, computed: { @@ -61,6 +65,10 @@ export default { return this.getAllRouters({ query: this.filter, status: this.status, + sortBy: this.sortBy, + direction: this.sortDir, + serviceName: '', + middlewareName: '', ...params }) }, @@ -81,6 +89,12 @@ export default { }, 'filter' () { this.refreshAll() + }, + 'sortBy' () { + this.refreshAll() + }, + 'sortDir' () { + this.refreshAll() } }, beforeDestroy () { diff --git a/webui/src/pages/udp/Services.vue b/webui/src/pages/udp/Services.vue index 3f62296070f5966f094bf6421712645ba76d7392..995cc896b972203b7b71652ae769f24055d558cc 100644 --- a/webui/src/pages/udp/Services.vue +++ b/webui/src/pages/udp/Services.vue @@ -15,6 +15,8 @@ :onLoadMore="handleLoadMore" :endReached="allServices.endReached" :loading="allServices.loading" + :currentSort.sync="sortBy" + :currentSortDir.sync="sortDir" /> </div> </div> @@ -50,7 +52,9 @@ export default { data () { return { filter: '', - status: '' + status: '', + sortBy: 'name', + sortDir: 'asc' } }, computed: { @@ -62,6 +66,8 @@ export default { return this.getAllServices({ query: this.filter, status: this.status, + sortBy: this.sortBy, + direction: this.sortDir, ...params }) }, @@ -82,6 +88,12 @@ export default { }, 'filter' () { this.refreshAll() + }, + 'sortBy' () { + this.refreshAll() + }, + 'sortDir' () { + this.refreshAll() } }, beforeDestroy () {